68 lines
2.2 KiB
C#
68 lines
2.2 KiB
C#
using UnityEngine;
|
|
|
|
public class AxisConstrainedLookAt : MonoBehaviour
|
|
{
|
|
public Transform target;
|
|
|
|
public enum LocalAxis { X, Y, Z }
|
|
public enum RotationAxis { X, Y, Z }
|
|
|
|
[Header("Which local axis should point at the target?")]
|
|
public LocalAxis lookAxis = LocalAxis.Z;
|
|
|
|
[Header("Allow rotation only around this world axis")]
|
|
public RotationAxis allowedRotationAxis = RotationAxis.Y;
|
|
|
|
void Update()
|
|
{
|
|
if (target == null) return;
|
|
|
|
Vector3 toTarget = target.position - transform.position;
|
|
|
|
if (toTarget.sqrMagnitude < 0.0001f) return;
|
|
|
|
// Project direction onto the allowed rotation plane
|
|
Vector3 projectedDirection = ProjectDirection(toTarget.normalized, allowedRotationAxis);
|
|
if (projectedDirection.sqrMagnitude < 0.0001f) return;
|
|
|
|
// Get the desired rotation to look at the projected target direction
|
|
Quaternion targetRotation = Quaternion.LookRotation(projectedDirection, Vector3.up);
|
|
|
|
// Adjust rotation so the selected local axis is pointing in that direction
|
|
Quaternion localAxisRotation = GetLocalAxisRotation(lookAxis);
|
|
|
|
// Apply final rotation
|
|
transform.rotation = targetRotation * Quaternion.Inverse(localAxisRotation);
|
|
}
|
|
|
|
private Vector3 ProjectDirection(Vector3 direction, RotationAxis axis)
|
|
{
|
|
switch (axis)
|
|
{
|
|
case RotationAxis.X:
|
|
return Vector3.ProjectOnPlane(direction, Vector3.right);
|
|
case RotationAxis.Y:
|
|
return Vector3.ProjectOnPlane(direction, Vector3.up);
|
|
case RotationAxis.Z:
|
|
return Vector3.ProjectOnPlane(direction, Vector3.forward);
|
|
default:
|
|
return direction;
|
|
}
|
|
}
|
|
|
|
private Quaternion GetLocalAxisRotation(LocalAxis axis)
|
|
{
|
|
switch (axis)
|
|
{
|
|
case LocalAxis.X:
|
|
return Quaternion.LookRotation(Vector3.right, Vector3.up);
|
|
case LocalAxis.Y:
|
|
return Quaternion.LookRotation(Vector3.up, Vector3.forward); // alternative up
|
|
case LocalAxis.Z:
|
|
return Quaternion.LookRotation(Vector3.forward, Vector3.up);
|
|
default:
|
|
return Quaternion.identity;
|
|
}
|
|
}
|
|
}
|