1 using System;
2 using
UnityEngine;
3
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
12         
// Only rotates around local X and Y.
13
14         
// Works in local coordinates, so if this object is parented
15         
// to another moving gameobject, its local constraints will
16         
// operate correctly
17         
// (Think: looking out the side window of a car, or a gun turret
18         
// on a moving spaceship with a limited angular range)
19
20         
// to have no constraints on an axis, set the rotationRange greater than 360.
21
22         [SerializeField]
private Vector2 m_RotationRange;
23         [SerializeField]
private float m_FollowSpeed = 1;
24
25         
private Vector3 m_FollowAngles;
26         
private Quaternion m_OriginalRotation;
27
28         
protected Vector3 m_FollowVelocity;
29
30
31         
// Use this for initialization
32         
protected override void Start()
33         {
34             
base.Start();
35             m_OriginalRotation = transform.localRotation;
36         }
37
38
39         
protected override void FollowTarget(float deltaTime)
40         {
41             
// we make initial calculations from the original local rotation
42             transform.localRotation = m_OriginalRotation;
43
44             
// tackle rotation around Y first
45             Vector3 localTarget = transform.InverseTransformPoint(m_Target.position);
46             
float yAngle = Mathf.Atan2(localTarget.x, localTarget.z)*Mathf.Rad2Deg;
47
48             yAngle = Mathf.Clamp(yAngle, -m_RotationRange.y*
0.5f, m_RotationRange.y*0.5f);
49             transform.localRotation = m_OriginalRotation*Quaternion.Euler(
0, yAngle, 0);
50
51             
// then recalculate new local target position for rotation around X
52             localTarget = transform.InverseTransformPoint(m_Target.position);
53             
float xAngle = Mathf.Atan2(localTarget.y, localTarget.z)*Mathf.Rad2Deg;
54             xAngle = Mathf.Clamp(xAngle, -m_RotationRange.x*
0.5f, m_RotationRange.x*0.5f);
55             
var targetAngles = new Vector3(m_FollowAngles.x + Mathf.DeltaAngle(m_FollowAngles.x, xAngle),
56                                            m_FollowAngles.y + Mathf.DeltaAngle(m_FollowAngles.y, yAngle));
57
58             
// smoothly interpolate the current angles to the target angles
59             m_FollowAngles = Vector3.SmoothDamp(m_FollowAngles, targetAngles,
ref m_FollowVelocity, m_FollowSpeed);
60
61
62             
// and update the gameobject itself
63             transform.localRotation = m_OriginalRotation*Quaternion.Euler(-m_FollowAngles.x, m_FollowAngles.y,
0);
64         }
65     }
66 }