Search Unity

Rigidbody Rotation Constraints rather than freezing

Discussion in 'Physics' started by TKDHayk, Nov 28, 2019.

  1. TKDHayk

    TKDHayk

    Joined:
    Dec 22, 2015
    Posts:
    131
    In my Game, I have giant flying bugs which swarm, orbit, and attack the player. Their movement is are purely controlled by physics forces.

    Currently, They are using AddTorque to turn and face the player, but I have had to freeze rotation in the x and z axes to prevent them from flipping upside down at times.

    However, I need these enemies to be able to rotate in the X axis somewhat, so that if the player is above them, they will adjust pitch to face upwards. Likewise, If the player is below them, they should pitch down to face thee player.

    So how can I constrain, rather than freeze, the x Axis of a rigidbody?

    I would like my Enemies to be able to rotate on the x axis , a maximum of 89 degrees in either direction relative to Quaternion.identity, totaling 178 degrees of movement on the x axis.

    Alternately, I can come up with a way for these enemies to "Recover" their rotation when they are upside down, by applying torque towards Quaternion.Identity. If anyone knows how to write this code, please let me know. this would be an even better solution, allowing my enemies to flip freely without any constraints, knowing they an always recover their orientation. This is great for recovering from explosions.

    Here is the code I am currently using to Rotate the enemy toward the player - works pretty good.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class FacePlayer : MonoBehaviour
    {
    public Transform target;
    public float force = 0.0001f;
    void FixedUpdate()
    {
    Vector3 targetDelta = target.position - transform.position;
    //get the angle between transform.forward and target delta
    float angleDiff = Vector3.Angle(transform.forward, targetDelta);
    // get its cross product, which is the axis of rotation to
    // get from one vector to the other
    Vector3 cross = Vector3.Cross(transform.forward, targetDelta);
    // apply torque along that axis according to the magnitude of the angle.
    this.gameObject.GetComponent<Rigidbody>().AddTorque(cross * angleDiff * force);
    }
    }
     
  2. devotid

    devotid

    Joined:
    Nov 14, 2011
    Posts:
    445
    How about a hinge joint on the X axis with limited angle and then set the desired angle with target position? That way you can dampen it and limiting its angle is pretty simple.