LookatTarget.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using System;
  2. using UnityEngine;
  3. #pragma warning disable 649
  4. namespace UnityStandardAssets.Cameras
  5. {
  6. public class LookatTarget : AbstractTargetFollower
  7. {
  8. // A simple script to make one object look at another,
  9. // but with optional constraints which operate relative to
  10. // this gameobject's initial rotation.
  11. // Only rotates around local X and Y.
  12. // Works in local coordinates, so if this object is parented
  13. // to another moving gameobject, its local constraints will
  14. // operate correctly
  15. // (Think: looking out the side window of a car, or a gun turret
  16. // on a moving spaceship with a limited angular range)
  17. // to have no constraints on an axis, set the rotationRange greater than 360.
  18. [SerializeField] private Vector2 m_RotationRange;
  19. [SerializeField] private float m_FollowSpeed = 1;
  20. private Vector3 m_FollowAngles;
  21. private Quaternion m_OriginalRotation;
  22. protected Vector3 m_FollowVelocity;
  23. // Use this for initialization
  24. protected override void Start()
  25. {
  26. base.Start();
  27. m_OriginalRotation = transform.localRotation;
  28. }
  29. protected override void FollowTarget(float deltaTime)
  30. {
  31. // we make initial calculations from the original local rotation
  32. transform.localRotation = m_OriginalRotation;
  33. // tackle rotation around Y first
  34. Vector3 localTarget = transform.InverseTransformPoint(m_Target.position);
  35. float yAngle = Mathf.Atan2(localTarget.x, localTarget.z)*Mathf.Rad2Deg;
  36. yAngle = Mathf.Clamp(yAngle, -m_RotationRange.y*0.5f, m_RotationRange.y*0.5f);
  37. transform.localRotation = m_OriginalRotation*Quaternion.Euler(0, yAngle, 0);
  38. // then recalculate new local target position for rotation around X
  39. localTarget = transform.InverseTransformPoint(m_Target.position);
  40. float xAngle = Mathf.Atan2(localTarget.y, localTarget.z)*Mathf.Rad2Deg;
  41. xAngle = Mathf.Clamp(xAngle, -m_RotationRange.x*0.5f, m_RotationRange.x*0.5f);
  42. var targetAngles = new Vector3(m_FollowAngles.x + Mathf.DeltaAngle(m_FollowAngles.x, xAngle),
  43. m_FollowAngles.y + Mathf.DeltaAngle(m_FollowAngles.y, yAngle));
  44. // smoothly interpolate the current angles to the target angles
  45. m_FollowAngles = Vector3.SmoothDamp(m_FollowAngles, targetAngles, ref m_FollowVelocity, m_FollowSpeed);
  46. // and update the gameobject itself
  47. transform.localRotation = m_OriginalRotation*Quaternion.Euler(-m_FollowAngles.x, m_FollowAngles.y, 0);
  48. }
  49. }
  50. }