100 lines
3.2 KiB
C#
100 lines
3.2 KiB
C#
using UnityEngine;
|
|
|
|
namespace GraphicsCat
|
|
{
|
|
[ExecuteAlways]
|
|
public class LookAtMainCamera : MonoBehaviour
|
|
{
|
|
public enum AlignMode { Full, YAxisOnly }
|
|
|
|
[Tooltip("Full: face camera on all axes. YAxisOnly: only rotate around world Y to face camera.")]
|
|
public AlignMode alignMode = AlignMode.Full;
|
|
|
|
[Tooltip("Local self-rotation speed in degrees per second on each axis.")]
|
|
public Vector3 selfRotationDegreesPerSecond = Vector3.zero;
|
|
|
|
[Tooltip("Optional euler offset (applied after aligning to camera).")]
|
|
public Vector3 rotationOffsetEuler = Vector3.zero;
|
|
|
|
[Tooltip("Use LateUpdate for camera-following (recommended if camera moves in Update).")]
|
|
public bool useLateUpdate = true;
|
|
|
|
[Tooltip("If true, the look direction will be inverted (useful if your mesh faces -Z by default).")]
|
|
public bool invertLookDirection = true;
|
|
|
|
[Tooltip("If set, this camera will be used instead of Camera.main.")]
|
|
public Camera overrideCamera;
|
|
|
|
// cached camera transform (will be updated if main camera changes)
|
|
Transform targetCameraTransform;
|
|
|
|
void OnEnable()
|
|
{
|
|
TryCacheCamera();
|
|
}
|
|
|
|
void TryCacheCamera()
|
|
{
|
|
if (overrideCamera != null)
|
|
{
|
|
targetCameraTransform = overrideCamera.transform;
|
|
return;
|
|
}
|
|
|
|
if (Camera.main != null)
|
|
targetCameraTransform = Camera.main.transform;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (!useLateUpdate)
|
|
AlignToCameraAndSelfRotate();
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if (useLateUpdate)
|
|
AlignToCameraAndSelfRotate();
|
|
}
|
|
|
|
void AlignToCameraAndSelfRotate()
|
|
{
|
|
if (targetCameraTransform == null)
|
|
TryCacheCamera();
|
|
|
|
// 1) Align to camera
|
|
if (targetCameraTransform != null)
|
|
{
|
|
Vector3 camPos = targetCameraTransform.position;
|
|
Vector3 toCam = camPos - transform.position;
|
|
|
|
// optionally invert direction if front faces -Z
|
|
if (invertLookDirection)
|
|
toCam = -toCam;
|
|
|
|
if (alignMode == AlignMode.Full)
|
|
{
|
|
if (toCam.sqrMagnitude > 0.0001f)
|
|
transform.rotation = Quaternion.LookRotation(toCam.normalized, Vector3.up);
|
|
}
|
|
else // YAxisOnly
|
|
{
|
|
toCam.y = 0f;
|
|
if (toCam.sqrMagnitude > 0.0001f)
|
|
transform.rotation = Quaternion.LookRotation(toCam.normalized, Vector3.up);
|
|
}
|
|
|
|
// apply an optional rotation offset after facing the camera
|
|
if (rotationOffsetEuler != Vector3.zero)
|
|
transform.rotation *= Quaternion.Euler(rotationOffsetEuler);
|
|
}
|
|
|
|
// 2) Apply local self-rotation (spin) in local space
|
|
if (selfRotationDegreesPerSecond != Vector3.zero)
|
|
{
|
|
transform.Rotate(selfRotationDegreesPerSecond * Time.deltaTime, Space.Self);
|
|
}
|
|
}
|
|
}
|
|
}
|