1using System.Collections;
2using System.Collections.Generic;
9 [SerializeField, Range(0.0f, 100.0f), Tooltip(
"How quickly to interpolate the window towards its target position and rotation.")]
10 private float windowFollowSpeed = 5.0f;
14 get {
return windowFollowSpeed; }
15 set { windowFollowSpeed = Mathf.Abs(value); }
17 [SerializeField, Range(0.0f, 10.0f), Tooltip(
"Extra distance.")]
18 private float windowExtraDistance = 1.0f;
22 get {
return windowExtraDistance; }
23 set { windowExtraDistance = Mathf.Abs(value); }
25 [Header(
"Window Settings")]
26 [SerializeField, Tooltip(
"What part of the view port to anchor the window to.")]
27 private TextAnchor windowAnchor = TextAnchor.LowerCenter;
31 get {
return windowAnchor; }
32 set { windowAnchor = value; }
35 [SerializeField, Tooltip(
"The offset from the view port center applied based on the window anchor selection.")]
36 private Vector2 windowOffset =
new Vector2(0.1f, 0.1f);
40 get {
return windowOffset; }
41 set { windowOffset = value; }
49 [SerializeField, Range(-180.0f, 180.0f)]
50 private float YOffset = 0.0f;
57 private byte initialFollow = 0;
59 private Transform cameraTransform;
60 private Quaternion windowHorizontalRotation;
61 private Quaternion windowHorizontalRotationInverse;
62 private Quaternion windowVerticalRotation;
63 private Quaternion windowVerticalRotationInverse;
65 private static readonly Vector2 defaultWindowRotation =
new Vector2(10.0f, 20.0f);
70 cameraTransform = Camera.main ? Camera.main.transform :
null;
72 cameraTransform =
followMe.transform;
78 windowHorizontalRotation = Quaternion.AngleAxis(defaultWindowRotation.y, Vector3.right);
79 windowHorizontalRotationInverse = Quaternion.Inverse(windowHorizontalRotation);
80 windowVerticalRotation = Quaternion.AngleAxis(defaultWindowRotation.x, Vector3.up);
81 windowVerticalRotationInverse = Quaternion.Inverse(windowVerticalRotation);
82 if (cameraTransform !=
null)
84 bool shouldFollow = !(!(Mathf.Abs(transform.rotation.eulerAngles.y - cameraTransform.rotation.eulerAngles.y)
86 if (!shouldFollow)
return;
87 if (initialFollow < 180)
89 float t = Time.deltaTime * windowFollowSpeed;
90 bool shouldFollowY = !(!(Mathf.Abs(transform.rotation.eulerAngles.y - cameraTransform.rotation.eulerAngles.y)
92 float distance = Mathf.Max(16.0f / Camera.main.fieldOfView, Camera.main.nearClipPlane + 0.25f) + windowExtraDistance;
93 bool inGoodDistance = Vector3.Distance(cameraTransform.position, transform.position) >= distance * 0.95 && Vector3.Distance(cameraTransform.position, transform.position) <= distance * 1.05;
98 var position = Vector3.Lerp(transform.position, CalculateWindowPosition(cameraTransform), t);
99 transform.position =
new Vector3(position.x, cameraTransform.position.y, position.z);
102 if (!shouldFollowY && inGoodDistance)
104 var cameraWorldPos = cameraTransform.parent.TransformPoint(cameraTransform.localPosition);
107 var position =
Vector3.Lerp(transform.position, CalculateWindowPosition(cameraTransform), t);
109 transform.position =
new Vector3(transform.position.x, position.y, transform.position.z);
113 transform.position =
Vector3.Lerp(transform.position, CalculateWindowPosition(cameraTransform), t);
121 Quaternion.Slerp(transform.rotation, CalculateWindowRotation(cameraTransform),
124 transform.eulerAngles =
new Vector3(transform.eulerAngles.x, rotation.eulerAngles.y, transform.eulerAngles.z);
127 if (!shouldFollowY && inGoodDistance)
130 Quaternion.Slerp(transform.rotation, CalculateWindowRotation(cameraTransform),
133 transform.eulerAngles =
new Vector3(rotation.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z);
139 Quaternion.Slerp(transform.rotation, CalculateWindowRotation(cameraTransform),
146 private Vector3 CalculateWindowPosition(Transform cameraTransform)
148 float windowDistance = Mathf.Max(16.0f / Camera.main.fieldOfView, Camera.main.nearClipPlane + 0.25f) + windowExtraDistance;
149 Vector3 position = cameraTransform.position + (cameraTransform.forward * windowDistance);
150 Vector3 horizontalOffset = cameraTransform.right * windowOffset.x;
151 Vector3 verticalOffset = cameraTransform.up * windowOffset.y;
153 switch (windowAnchor)
155 case TextAnchor.UpperLeft: position += verticalOffset - horizontalOffset;
break;
156 case TextAnchor.UpperCenter: position += verticalOffset;
break;
157 case TextAnchor.UpperRight: position += verticalOffset + horizontalOffset;
break;
158 case TextAnchor.MiddleLeft: position -= horizontalOffset;
break;
159 case TextAnchor.MiddleRight: position += horizontalOffset;
break;
160 case TextAnchor.LowerLeft: position -= verticalOffset + horizontalOffset;
break;
161 case TextAnchor.LowerCenter: position -= verticalOffset;
break;
162 case TextAnchor.LowerRight: position -= verticalOffset - horizontalOffset;
break;
168 private Quaternion CalculateWindowRotation(Transform cameraTransform)
170 Quaternion rotation = cameraTransform.rotation;
172 switch (windowAnchor)
174 case TextAnchor.UpperLeft: rotation *= windowHorizontalRotationInverse * windowVerticalRotationInverse;
break;
175 case TextAnchor.UpperCenter: rotation *= windowHorizontalRotationInverse;
break;
176 case TextAnchor.UpperRight: rotation *= windowHorizontalRotationInverse * windowVerticalRotation;
break;
177 case TextAnchor.MiddleLeft: rotation *= windowVerticalRotationInverse;
break;
178 case TextAnchor.MiddleRight: rotation *= windowVerticalRotation;
break;
179 case TextAnchor.LowerLeft: rotation *= windowHorizontalRotation * windowVerticalRotationInverse;
break;
180 case TextAnchor.LowerCenter: rotation *= windowHorizontalRotation;
break;
181 case TextAnchor.LowerRight: rotation *= windowHorizontalRotation * windowVerticalRotation;
break;
bool OnlyFollowAfterAngleDifferenceY
bool TryCorrectParentRotation
bool OnlyFollowAfterAngleDifference
float WindowExtraDistance