LookatTarget.cs 2.7 KB

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