I recently became interested in this topic after diving through some old posts, as I needed something similar.
Referencing rigidbody lookat torque?
I was able to get it working with the following code:
using Mirror;
using UnityEngine;
public class ShipController : NetworkBehaviour
{
public Vector3 heading = Vector3.zero;
private float alignmentSpeed = 0.00725f;
private float alignmentDampening = 0.2f;
private Rigidbody body;
public void Start()
{
// if no rigidbody, add one
body = GetComponent<Rigidbody>();
if (body == null)
{
body = gameObject.AddComponent<Rigidbody>();
}
}
public void SetHeading(GameObject target)
{
// TODO: do more than just set the heading
heading = target.transform.position;
}
public void SetHeading(Vector3 location)
{
heading = location;
}
public void FixedUpdate()
{
if (!isServer) return;
if (heading == Vector3.zero) return;
var normal = Vector3.up;
var target = Quaternion.LookRotation(heading, normal);
var deltaRotation = target * Quaternion.Inverse(transform.rotation);
var deltaAngles = GetRelativeAngles(deltaRotation.eulerAngles);
var torque = new Vector3(deltaAngles.x, deltaAngles.y, deltaAngles.z) * alignmentSpeed;
body.AddTorque(torque, ForceMode.VelocityChange);
body.angularVelocity *= alignmentDampening;
}
private Vector3 GetRelativeAngles(Vector3 angles)
{
var relativeAngles = angles;
if (relativeAngles.x > 180)
{
relativeAngles.x -= 360;
}
if (relativeAngles.y > 180)
{
relativeAngles.y -= 360;
}
if (relativeAngles.z > 180)
{
relativeAngles.z -= 360;
}
return relativeAngles;
}
}
For my use I set the Rigidbody mass to 1000, Linear damping to 0.007, and Angular damping to 0.8.
If you don’t need Mirror, you can remove isServer and change NetworkBehaviour to MonoBehaviour.
I hope this helps someone out. If there is enough interest in a full tutorial I might make one, just let me know.
Thanks,
Marsh