I found a solution, now it follows the mouse cursor and it doesn’t require 2 scripts (You don’t need CursorHit.cs). Here is the tweaked version of the HeadLookController for anyone that wants it:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class BendingSegment {
public Transform firstTransform;
public Transform lastTransform;
public float thresholdAngleDifference = 0;
public float bendingMultiplier = 0.6f;
public float maxAngleDifference = 30;
public float maxBendingAngle = 80;
public float responsiveness = 5;
internal float angleH;
internal float angleV;
internal Vector3 dirUp;
internal Vector3 referenceLookDir;
internal Vector3 referenceUpDir;
internal int chainLength;
internal Quaternion[] origRotations;
}
[System.Serializable]
public class NonAffectedJoints {
public Transform joint;
public float effect = 0;
}
public class HeadLookController : MonoBehaviour {
private float offset = 1.5f;
private Vector3 MouseCursor;
public Transform rootNode;
public BendingSegment[] segments;
public NonAffectedJoints[] nonAffectedJoints;
public Vector3 headLookVector = Vector3.forward;
public Vector3 headUpVector = Vector3.up;
public Vector3 target = Vector3.zero;
public float effect = 1;
public bool overrideAnimation = false;
void Start () {
if (rootNode == null) {
rootNode = transform;
}
// Setup segments
foreach (BendingSegment segment in segments) {
Quaternion parentRot = segment.firstTransform.parent.rotation;
Quaternion parentRotInv = Quaternion.Inverse(parentRot);
segment.referenceLookDir =
parentRotInv * rootNode.rotation * headLookVector.normalized;
segment.referenceUpDir =
parentRotInv * rootNode.rotation * headUpVector.normalized;
segment.angleH = 0;
segment.angleV = 0;
segment.dirUp = segment.referenceUpDir;
segment.chainLength = 1;
Transform t = segment.lastTransform;
while (t != segment.firstTransform && t != t.root) {
segment.chainLength++;
t = t.parent;
}
segment.origRotations = new Quaternion[segment.chainLength];
t = segment.lastTransform;
for (int i=segment.chainLength-1; i>=0; i--) {
segment.origRotations *= t.localRotation;*
-
t = t.parent;*
-
}*
-
}*
-
}*
-
void LateUpdate () {*
-
if (Time.deltaTime == 0)*
-
return;*
-
// Remember initial directions of joints that should not be affected*
-
Vector3[] jointDirections = new Vector3[nonAffectedJoints.Length];*
-
for (int i=0; i<nonAffectedJoints.Length; i++) {*
_ foreach (Transform child in nonAffectedJoints*.joint) {_
jointDirections _= child.position - nonAffectedJoints.joint.position;
break;
}
}*_
* // Handle each segment*
* foreach (BendingSegment segment in segments) {*
* Transform t = segment.lastTransform;*
* if (overrideAnimation) {*
* for (int i=segment.chainLength-1; i>=0; i–) {*
_ t.localRotation = segment.origRotations*;
t = t.parent;
}
}*_
* Quaternion parentRot = segment.firstTransform.parent.rotation;*
* Quaternion parentRotInv = Quaternion.Inverse(parentRot);*
* // Desired look direction in world space*
* Vector3 lookDirWorld = (target - segment.lastTransform.position).normalized;*
* // Desired look directions in neck parent space*
_ Vector3 lookDirGoal = (parentRotInv * lookDirWorld);_
* // Get the horizontal and vertical rotation angle to look at the target*
* float hAngle = AngleAroundAxis(*
* segment.referenceLookDir, lookDirGoal, segment.referenceUpDir*
* );*
* Vector3 rightOfTarget = Vector3.Cross(segment.referenceUpDir, lookDirGoal);*
* Vector3 lookDirGoalinHPlane =*
* lookDirGoal - Vector3.Project(lookDirGoal, segment.referenceUpDir);*
* float vAngle = AngleAroundAxis(*
* lookDirGoalinHPlane, lookDirGoal, rightOfTarget*
* );*
* // Handle threshold angle difference, bending multiplier,*
* // and max angle difference here*
* float hAngleThr = Mathf.Max(*
* 0, Mathf.Abs(hAngle) - segment.thresholdAngleDifference*
_ ) * Mathf.Sign(hAngle);_
* float vAngleThr = Mathf.Max(*
* 0, Mathf.Abs(vAngle) - segment.thresholdAngleDifference*
_ ) * Mathf.Sign(vAngle);_
* hAngle = Mathf.Max(*
_ Mathf.Abs(hAngleThr) * Mathf.Abs(segment.bendingMultiplier),
* Mathf.Abs(hAngle) - segment.maxAngleDifference*
) * Mathf.Sign(hAngle) * Mathf.Sign(segment.bendingMultiplier);_
* vAngle = Mathf.Max(*
_ Mathf.Abs(vAngleThr) * Mathf.Abs(segment.bendingMultiplier),
* Mathf.Abs(vAngle) - segment.maxAngleDifference*
) * Mathf.Sign(vAngle) * Mathf.Sign(segment.bendingMultiplier);_
* // Handle max bending angle here*
* hAngle = Mathf.Clamp(hAngle, -segment.maxBendingAngle, segment.maxBendingAngle);*
* vAngle = Mathf.Clamp(vAngle, -segment.maxBendingAngle, segment.maxBendingAngle);*
* Vector3 referenceRightDir =*
* Vector3.Cross(segment.referenceUpDir, segment.referenceLookDir);*
* // Lerp angles*
* segment.angleH = Mathf.Lerp(*
_ segment.angleH, hAngle, Time.deltaTime * segment.responsiveness_
* );*
* segment.angleV = Mathf.Lerp(*
_ segment.angleV, vAngle, Time.deltaTime * segment.responsiveness_
* );*
* // Get direction*
* lookDirGoal = Quaternion.AngleAxis(segment.angleH, segment.referenceUpDir)*
_ * Quaternion.AngleAxis(segment.angleV, referenceRightDir)
* segment.referenceLookDir;_
* // Make look and up perpendicular*
* Vector3 upDirGoal = segment.referenceUpDir;*
* Vector3.OrthoNormalize(ref lookDirGoal, ref upDirGoal);*
* // Interpolated look and up directions in neck parent space*
* Vector3 lookDir = lookDirGoal;*
_ segment.dirUp = Vector3.Slerp(segment.dirUp, upDirGoal, Time.deltaTime5);
Vector3.OrthoNormalize(ref lookDir, ref segment.dirUp);*_
* // Look rotation in world space*
* Quaternion lookRot = (*
_ (parentRot * Quaternion.LookRotation(lookDir, segment.dirUp))
* Quaternion.Inverse(
parentRot * Quaternion.LookRotation(
* segment.referenceLookDir, segment.referenceUpDir*
* )
)
);*_
* // Distribute rotation over all joints in segment*
* Quaternion dividedRotation =*
* Quaternion.Slerp(Quaternion.identity, lookRot, effect / segment.chainLength);*
* t = segment.lastTransform;*
* for (int i=0; i<segment.chainLength; i++) {*
_ t.rotation = dividedRotation * t.rotation;
* t = t.parent;
}
}*_
* // Handle non affected joints*
* for (int i=0; i<nonAffectedJoints.Length; i++) {*
* Vector3 newJointDirection = Vector3.zero;*
_ foreach (Transform child in nonAffectedJoints*.joint) {
newJointDirection = child.position - nonAffectedJoints.joint.position;
break;
}*_
* Vector3 combinedJointDirection = Vector3.Slerp(*
jointDirections_, newJointDirection, nonAffectedJoints*.effect*
* );*_
_ nonAffectedJoints*.joint.rotation = Quaternion.FromToRotation(
newJointDirection, combinedJointDirection*
) * nonAffectedJoints*.joint.rotation;
}*_
* if (Input.GetKey(KeyCode.UpArrow))*
* offset += Time.deltaTime;*
* if (Input.GetKey(KeyCode.DownArrow))*
* offset -= Time.deltaTime;*
* Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition);*
* RaycastHit hit;*
* if (Physics.Raycast(cursorRay, out hit))*
* {*
_ MouseCursor = hit.point + offset * Vector3.down;
* }*_
* target = MouseCursor;*
* }*
* // The angle between dirA and dirB around axis*
* public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis) {*
* // Project A and B onto the plane orthogonal target axis*
* dirA = dirA - Vector3.Project(dirA, axis);*
* dirB = dirB - Vector3.Project(dirB, axis);*
* // Find (positive) angle between A and B*
* float angle = Vector3.Angle(dirA, dirB);*
* // Return angle multiplied with 1 or -1*
_ return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
* }
}*_