简体   繁体   中英

How do you get the player game object from rotating with the sphere game object

I am currently making a Katamari/Billy Hatcher game where the player has to roll spheres around. When the game starts the player has normal platformer controls until it approaches a sphere and if the player presses the "attach" button, the player becomes a child of the sphere. The issue I am having is whenever this happens, the player rotates with the sphere. I tried freezing the player's rigid body so it can stop rotating but that just stops the sphere's rotation. Is there any way to stop the rotation of the player, while keeping the sphere rotating?

Picture: enter image description here Here's my scripts for the process:

Rigidbody hitRB;
public Vector3 offset = new Vector3(0, 0, 1);
public LayerMask pickupMask;
bool isAttached;


private void TouchingGum()
{
    RaycastHit hit = new RaycastHit();
    foreach (GameObject gumball in gumBalls)
    {
        
        if (Input.GetButtonDown("Attach") && Physics.Raycast(transform.position,transform.forward, out hit, attachRequireDistance, pickupMask))
        {
            isAttached = true;
            Debug.Log(true);
        }
        else
        {
            isAttached = false;
        }
    }


    if (isAttached)
    {
        hitRB = hit.collider.gameObject.GetComponent<Rigidbody>();
        Vector3 heldOffset = transform.right * offset.x + transform.up * offset.y + transform.forward * offset.z;
        hitRB.isKinematic = true;
        hitRB.MovePosition(player.transform.position + heldOffset);
    }
    else if(!isAttached && !hitRB == null)
    {
        hitRB.isKinematic = false;
    }

If you can, don't use parent/child relationships in these situations. I feel that there is always a better way. One way of accomplishing this is by taking the player's transform, and adding the forward direction to an offset:

Vector3 offset = new Vector3(0, 0, 1);
LayerMask pickupMask; //change to mask of objects that can be picked up in editor.
public bool held;

void Update()
{
   RaycastHit hit;
   if (Input.GetKey(KeyCode.Mouse0) && Physics.Raycast(transform.position, transform.forward, out hit, 2, pickupMask))
   {
       held = true;
   }
   else
   {
       held = false
   }
   Rigidbody hitRB = hit.collider.gameObject.GetComponent<Rigidbody>();
   if (held)
   {
       Vector3 heldOffset = (transform.right * offset.x) + (transform.up * offset.y) + (transform.forward * offset.z);
       // if it still glitches, remove the previous line and add the line after this one.
       Vector3 heldOffset = transform.forward * offset.z;
       hitRB.isKinematic = true;
       hit.collider.gameObject.transform.position = transform.position + heldOffset;
   }
   if else (!held && !hitRB == null)
   {
      hitRB.isKinematic = false;
   }
}

This script uses raycast and input to detect if the player is clicking the left mouse button and is looking at an object within 2 distance and with a certain layer mask. Then it will set the velocity to the offset plus the player's position. In other words, this gets the object you looked at while pressing left click, and holds it in front of you (or whatever the offset is).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM