UP-Viagg-io/Viagg-io/Assets/AxisConstrainedLookAt.cs
2025-06-19 14:22:40 +02:00

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;
}
}
}