37 #region public members 38 [Tooltip(
"Which direction to position the element relative to: HeadOriented rolls with the head, HeadFacingWorldUp view dir but ignores head roll, and HeadMoveDirection uses the direction the head last moved without roll")]
41 [Tooltip(
"Min distance from eye to position element around, i.e. the sphere radius")]
42 public float MinDistance = 1f;
43 [Tooltip(
"Max distance from eye to element")]
44 public float MaxDistance = 2f;
46 [Tooltip(
"The element will stay at least this far away from the center of view")]
47 public float MinViewDegrees = 0f;
48 [Tooltip(
"The element will stay at least this close to the center of view")]
49 public float MaxViewDegrees = 30f;
50 [Tooltip(
"Apply a different clamp to vertical FOV than horizontal. Vertical = Horizontal * AspectV")]
51 public float AspectV = 1f;
53 [Tooltip(
"Option to ignore angle clamping")]
54 public bool IgnoreAngleClamp =
false;
55 [Tooltip(
"Option to ignore distance clamping")]
56 public bool IgnoreDistanceClamp =
false;
58 [Tooltip(
"If true, element will orient to ReferenceDirection, otherwise it will orient to ref pos (the head is the only option currently)")]
59 public bool OrientToRefDir =
false;
66 private Vector3 GetReferenceDirection()
68 Vector3 ret = Vector3.one;
71 ret = Camera.main.GetComponent<InputModule.CameraMotionInfo>().MoveDirection;
84 private Vector3 GetReferenceUp()
86 Vector3 ret = Vector3.up;
89 ret = base.solverHandler.TransformTarget != null ? base.solverHandler.TransformTarget.up : Vector3.up;
94 private Vector3 GetReferencePoint()
96 return base.solverHandler.TransformTarget != null ? base.solverHandler.TransformTarget.position : Vector3.zero;
105 Vector3 desiredPos = this.WorkingPos;
107 if (IgnoreAngleClamp)
109 if (IgnoreDistanceClamp)
111 desiredPos = transform.position;
115 GetDesiredOrientation_DistanceOnly(ref desiredPos);
120 GetDesiredOrientation(ref desiredPos);
124 Vector3 refDirUp = GetReferenceUp();
125 Quaternion desiredRot = Quaternion.identity;
129 desiredRot = Quaternion.LookRotation(GetReferenceDirection(), refDirUp);
133 Vector3 refPoint = GetReferencePoint();
134 desiredRot = Quaternion.LookRotation(desiredPos - refPoint, refDirUp);
140 desiredRot.x = desiredRot.z = 0f;
143 this.GoalPosition = desiredPos;
144 this.GoalRotation = desiredRot;
146 UpdateWorkingPosToGoal();
147 UpdateWorkingRotToGoal();
154 private void GetDesiredOrientation_DistanceOnly(ref Vector3 desiredPos)
157 Vector3 refPoint = GetReferencePoint();
158 Vector3 elementPoint = transform.position;
159 Vector3 elementDelta = elementPoint - refPoint;
160 float elementDist = elementDelta.magnitude;
161 Vector3 elementDir = elementDist > 0 ? elementDelta / elementDist : Vector3.one;
164 float clampedDistance = Mathf.Clamp(elementDist, MinDistance, MaxDistance);
166 if (clampedDistance != elementDist)
168 desiredPos = refPoint + clampedDistance * elementDir;
172 private void GetDesiredOrientation(ref Vector3 desiredPos)
175 Vector3 refDir = GetReferenceDirection();
176 Vector3 refDirUp = GetReferenceUp();
177 Vector3 refPoint = GetReferencePoint();
178 Vector3 elementPoint = transform.position;
179 Vector3 elementDelta = elementPoint - refPoint;
180 float elementDist = elementDelta.magnitude;
181 Vector3 elementDir = elementDist > 0 ? elementDelta / elementDist : Vector3.one;
184 Vector3 elementDirPerp = (elementDir - refDir);
185 elementDirPerp -= refDir * Vector3.Dot(elementDirPerp, refDir);
186 elementDirPerp.Normalize();
189 float HtoVAng = Vector3.Angle(elementDirPerp, refDirUp);
190 float VAspectScale = Mathf.Lerp(AspectV, 1f, Mathf.Abs(Mathf.Sin(HtoVAng * Mathf.Deg2Rad)));
193 float angDegree = Vector3.Angle(elementDir, refDir);
194 float angDegreeClamped = Mathf.Clamp(angDegree, MinViewDegrees * VAspectScale, MaxViewDegrees * VAspectScale);
197 float clampedDistance = IgnoreDistanceClamp ? elementDist : Mathf.Clamp(elementDist, MinDistance, MaxDistance);
200 if (angDegree != angDegreeClamped)
202 float angRad = angDegreeClamped * Mathf.Deg2Rad;
205 desiredPos = refPoint + clampedDistance * (refDir * Mathf.Cos(angRad) + elementDirPerp * Mathf.Sin(angRad));
207 else if (clampedDistance != elementDist)
210 desiredPos = refPoint + clampedDistance * elementDir;