42 #region public members 43 [Tooltip(
"The desired orientation of this object. Default sets the object to face the TrackedObject/TargetTransform. CameraFacing sets the object to always face the user.")]
52 get {
return orientation; }
53 set { orientation = value; }
56 [Tooltip(
"XYZ offset for this object in relation to the TrackedObject/TargetTransform. Mixing local and world offsets is not recommended.")]
58 private Vector3 localOffset =
new Vector3(0,-1,1);
63 public Vector3 LocalOffset
65 get {
return localOffset; }
66 set { localOffset = value; }
69 [Tooltip(
"XYZ offset for this object in worldspace, best used with the YawOnly orientation. Mixing local and world offsets is not recommended.")]
71 private Vector3 worldOffset = Vector3.zero;
76 public Vector3 WorldOffset
78 get {
return worldOffset; }
79 set { worldOffset = value; }
82 [Tooltip(
"Lock the rotation to a specified number of steps around the tracked object.")]
84 private bool useAngleSteppingForWorldOffset =
false;
89 public bool UseAngleSteppingForWorldOffset
91 get {
return useAngleSteppingForWorldOffset; }
92 set { useAngleSteppingForWorldOffset = value; }
95 [Tooltip(
"TetherAngleSteps is the division of steps this object can tether to. Higher the number, the more snapple steps.")]
98 private int tetherAngleSteps = 6;
102 public int TetherAngleSteps
104 get {
return tetherAngleSteps;}
107 if (value > 24 || value < 2)
109 Debug.LogError(
"TetherAngleSteps was set to a size larger than it's max range. Clamping to a valid value.");
111 tetherAngleSteps = Mathf.Clamp(value, 2, 24);
118 Vector3 desiredPos = solverHandler.TransformTarget != null ? solverHandler.TransformTarget.position : Vector3.zero;
120 Quaternion targetRot = solverHandler.TransformTarget != null ? solverHandler.TransformTarget.rotation : Quaternion.Euler(0, 1, 0);
121 Quaternion yawOnlyRot = Quaternion.Euler(0, targetRot.eulerAngles.y, 0);
122 desiredPos = desiredPos + (SnapToTetherAngleSteps(targetRot) * LocalOffset);
123 desiredPos = desiredPos + (SnapToTetherAngleSteps(yawOnlyRot) * WorldOffset);
125 Quaternion desiredRot = CalculateDesiredRotation(desiredPos);
127 GoalPosition = desiredPos;
128 GoalRotation = desiredRot;
130 UpdateWorkingPosToGoal();
131 UpdateWorkingRotToGoal();
135 private Quaternion SnapToTetherAngleSteps(Quaternion RotationToSnap)
137 if (!UseAngleSteppingForWorldOffset)
139 return RotationToSnap;
142 float stepAngle = 360f / TetherAngleSteps;
143 int numberOfSteps = Mathf.RoundToInt(solverHandler.TransformTarget.transform.localEulerAngles.y / stepAngle);
145 float newAngle = stepAngle * numberOfSteps;
147 return Quaternion.Euler(RotationToSnap.eulerAngles.x, newAngle, RotationToSnap.eulerAngles.z);
150 private Quaternion CalculateDesiredRotation( Vector3 desiredPos )
152 Quaternion desiredRot;
157 float targetYRotation;
158 if (solverHandler.TransformTarget != null)
160 targetYRotation = solverHandler.TransformTarget.eulerAngles.y;
166 desiredRot = Quaternion.Euler(0f, targetYRotation, 0f);
169 desiredRot = transform.rotation;
175 desiredRot = Quaternion.LookRotation(solverHandler.TransformTarget.position - desiredPos);
178 desiredRot = Quaternion.LookRotation(
CameraCache.
Main.transform.position - desiredPos);
182 if (solverHandler.TransformTarget != null)
184 desiredRot = solverHandler.TransformTarget.rotation;
188 desiredRot = Quaternion.identity;
193 if (UseAngleSteppingForWorldOffset)
195 desiredRot = SnapToTetherAngleSteps(desiredRot);