mercredi 23 septembre 2015

Unity ThirdPersonCamera.js to ThirdPersonCamera.cs

1:  using UnityEngine;  
2:  using System.Collections;  
3:  public class ThirdPersonCamera : MonoBehaviour {  
4:       Transform cameraTransform;  
5:       private Transform _target;  
6:       // The distance in the x-z plane to the target  
7:       public float distance = 7.0f;  
8:       // the height we want the camera to be above the target  
9:       public float height = 3.0f;  
10:       public float angularSmoothLag = 0.3f;  
11:       public float angularMaxSpeed = 15.0f;  
12:       public float heightSmoothLag = 0.3f;  
13:       public float snapSmoothLag = 0.2f;  
14:       public float snapMaxSpeed = 720.0f;  
15:       public float clampHeadPositionScreenSpace = 0.75f;  
16:       public float lockCameraTimeout = 0.2f;  
17:       private Vector3 headOffset = Vector3.zero;  
18:       private Vector3 centerOffset = Vector3.zero;  
19:       private float heightVelocity = 0.0f;  
20:       private float angleVelocity = 0.0f;  
21:       private bool snap = false;  
22:       private ThirdPersonController controller;  
23:       private float targetHeight = 100000.0f;   
24:       void Awake ()  
25:       {  
26:            if(!cameraTransform && Camera.main)  
27:                 cameraTransform = Camera.main.transform;  
28:            if(!cameraTransform) {  
29:                 Debug.Log("Please assign a camera to the ThirdPersonCamera script.");  
30:                 enabled = false;       
31:            }  
32:            _target = transform;  
33:            if (_target)  
34:            {  
35:                 controller = _target.GetComponent <ThirdPersonController> ();  
36:            }  
37:            if (controller)  
38:            {  
39:                 Collider characterController = _target.GetComponent <Collider> ();  
40:                 centerOffset = characterController.bounds.center - _target.position;  
41:                 headOffset = centerOffset;  
42:                 headOffset.y = characterController.bounds.max.y - _target.position.y;  
43:            }  
44:            else  
45:                 Debug.Log("Please assign a target to the camera that has a ThirdPersonController script attached.");  
46:            Cut(_target, centerOffset);  
47:       }  
48:       float AngleDistance (float a, float b)  
49:       {  
50:            a = Mathf.Repeat(a, 360);  
51:            b = Mathf.Repeat(b, 360);  
52:            return Mathf.Abs(b - a);  
53:       }  
54:       void DebugDrawStuff ()  
55:       {  
56:            Debug.DrawLine(_target.position, _target.position + headOffset);  
57:       }  
58:       void Apply (Transform dummyTarget , Vector3 dummyCenter)  
59:       {  
60:            // Early out if we don't have a target  
61:            if (!controller)  
62:                 return;  
63:            Vector3 targetCenter = _target.position + centerOffset;  
64:            Vector3 targetHead = _target.position + headOffset;  
65:            //     DebugDrawStuff();  
66:            // Calculate the current & target rotation angles  
67:            float originalTargetAngle = _target.eulerAngles.y;  
68:            float currentAngle = cameraTransform.eulerAngles.y;  
69:            // Adjust real target angle when camera is locked  
70:            float targetAngle = originalTargetAngle;   
71:            // When pressing Fire2 (alt) the camera will snap to the target direction real quick.  
72:            // It will stop snapping when it reaches the target  
73:            if (Input.GetButton("Fire2"))  
74:                 snap = true;  
75:            if (snap)  
76:            {  
77:                 // We are close to the target, so we can stop snapping now!  
78:                 if (AngleDistance (currentAngle, originalTargetAngle) < 3.0)  
79:                      snap = false;  
80:                 currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, snapSmoothLag, snapMaxSpeed);  
81:            }  
82:            // Normal camera motion  
83:            else  
84:            {  
85:                 if (controller.GetLockCameraTimer () < lockCameraTimeout)  
86:                 {  
87:                      targetAngle = currentAngle;  
88:                 }  
89:                 // Lock the camera when moving backwards!  
90:                 // * It is really confusing to do 180 degree spins when turning around.  
91:                 if (AngleDistance (currentAngle, targetAngle) > 160 && controller.IsMovingBackwards ())  
92:                      targetAngle += 180;  
93:                 currentAngle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angleVelocity, angularSmoothLag, angularMaxSpeed);  
94:            }  
95:            // When jumping don't move camera upwards but only down!  
96:            if (controller.IsJumping ())  
97:            {  
98:                 // We'd be moving the camera upwards, do that only if it's really high  
99:                 float newTargetHeight = targetCenter.y + height;  
100:                 if (newTargetHeight < targetHeight || newTargetHeight - targetHeight > 5)  
101:                      targetHeight = targetCenter.y + height;  
102:            }  
103:            // When walking always update the target height  
104:            else  
105:            {  
106:                 targetHeight = targetCenter.y + height;  
107:            }  
108:            // Damp the height  
109:            float currentHeight = cameraTransform.position.y;  
110:            currentHeight = Mathf.SmoothDamp (currentHeight, targetHeight, ref heightVelocity, heightSmoothLag);  
111:            // Convert the angle into a rotation, by which we then reposition the camera  
112:         Quaternion currentRotation = Quaternion.Euler (0, currentAngle, 0);  
113:            // Set the position of the camera on the x-z plane to:  
114:            // distance meters behind the target  
115:            cameraTransform.position = targetCenter;  
116:            cameraTransform.position += currentRotation * Vector3.back * distance;  
117:            // Set the height of the camera  
118:            cameraTransform.position = new Vector3 (cameraTransform.position.x,currentHeight,cameraTransform.position.z);  
119:            // Always look at the target       
120:            SetUpRotation(targetCenter, targetHead);  
121:       }  
122:       void Cut (Transform dummyTarget, Vector3 dummyCenter)  
123:       {  
124:            float oldHeightSmooth = heightSmoothLag;  
125:            float oldSnapMaxSpeed = snapMaxSpeed;  
126:            float oldSnapSmooth = snapSmoothLag;  
127:            snapMaxSpeed = 10000;  
128:            snapSmoothLag = 0.001f;  
129:            heightSmoothLag = 0.001f;  
130:            snap = true;  
131:            Apply (transform, Vector3.zero);  
132:            heightSmoothLag = oldHeightSmooth;  
133:            snapMaxSpeed = oldSnapMaxSpeed;  
134:            snapSmoothLag = oldSnapSmooth;  
135:       }  
136:       void SetUpRotation (Vector3 centerPos, Vector3 headPos)  
137:       {  
138:            // Now it's getting hairy. The devil is in the details here, the big issue is jumping of course.  
139:            // * When jumping up and down we don't want to center the guy in screen space.  
140:            // This is important to give a feel for how high you jump and avoiding large camera movements.  
141:            //    
142:            // * At the same time we dont want him to ever go out of screen and we want all rotations to be totally smooth.  
143:            //  
144:            // So here is what we will do:  
145:            //  
146:            // 1. We first find the rotation around the y axis. Thus he is always centered on the y-axis  
147:            // 2. When grounded we make him be centered  
148:            // 3. When jumping we keep the camera rotation but rotate the camera to get him back into view if his head is above some threshold  
149:            // 4. When landing we smoothly interpolate towards centering him on screen  
150:            Vector3 cameraPos = cameraTransform.position;  
151:            Vector3 offsetToCenter = centerPos - cameraPos;  
152:            // Generate base rotation only around y-axis  
153:            Quaternion yRotation = Quaternion.LookRotation(new Vector3(offsetToCenter.x, 0, offsetToCenter.z));  
154:            Vector3 relativeOffset = Vector3.forward * distance + Vector3.down * height;  
155:            cameraTransform.rotation = yRotation * Quaternion.LookRotation(relativeOffset);  
156:            // Calculate the projected center position and top position in world space  
157:            Ray centerRay = cameraTransform.GetComponent <Camera>().ViewportPointToRay(new Vector3(0.5f, 0.5f, 1));  
158:            Ray topRay = cameraTransform.GetComponent <Camera>().ViewportPointToRay(new Vector3(0.5f, clampHeadPositionScreenSpace, 1));  
159:            Vector3 centerRayPos = centerRay.GetPoint(distance);  
160:            Vector3 topRayPos = topRay.GetPoint(distance);  
161:            float centerToTopAngle = Vector3.Angle(centerRay.direction, topRay.direction);  
162:            float heightToAngle = centerToTopAngle / (centerRayPos.y - topRayPos.y);  
163:            float extraLookAngle = heightToAngle * (centerRayPos.y - centerPos.y);  
164:            if (extraLookAngle < centerToTopAngle)  
165:            {  
166:                 extraLookAngle = 0;  
167:            }  
168:            else  
169:            {  
170:                 extraLookAngle = extraLookAngle - centerToTopAngle;  
171:                 cameraTransform.rotation *= Quaternion.Euler(-extraLookAngle, 0, 0);  
172:            }  
173:       }  
174:       Vector3 GetCenterOffset ()  
175:       {  
176:            return centerOffset;  
177:       }  
178:       // Use this for initialization  
179:       void Start () {  
180:       }  
181:       // Update is called once per frame  
182:       void Update () {  
183:       }  
184:       void LateUpdate () {  
185:            Apply (transform, Vector3.zero);  
186:       }  
187:  }  

Aucun commentaire:

Publier un commentaire