- Home /
Head and body rotate threshold
I currently have a script that will rotate the player's body when the head surpasses a maxAngle float value (I have it set at 90). It works great but I want to make it so that when the player is looking straight down or up (and/or close to it) the maxAngle value gets smaller to allow the body to rotate with the head more.
I either need to do change my angle calculation so the maxAngle shapes around the rotation sphere(?) OR I change the maxAngle to be smaller when the x rotation on the head gets bigger.
I know what I need but I don't quite know how to achieve it. The image below is how I describe the maxAngle on the rotation sphere
Answer by Cornelis-de-Jager · Apr 03, 2018 at 11:26 PM
Ok so here is my solution. first you need to calculate the max angle you can rotate on. This needs to be dynamic:
void Update () {
maxAngle = CalculateAngle ();
}
float CalculateAngle () {
Vector3 lookDir = head.forward;
Vector3 faceDir = body.forward;
float diff = Mathf.Abs(Vector3.Angle(lookDir, faceDir));
Debug.Log(diff);
// Now write the curve function
float angle = LookCurve (diff) ;
return angle;
}
float LookCurve (float diff) {
// Cats Eye (like in diagram)
return 90 * (1 - Mathf.Pow(diff / 90, 2.5f));
}
The lookCurve function is basically what gives the Shape. For the linear it will simply be a diamond shape lookbox, for your more catlike one it will be the second return function. pick one or make your own. go to google and plug in this formula 'y = 90 * (1-(x/90)^2.5)' it will automaticall create a graph, you can then just tweek it, I suggest tweeking the power.
The next step is to Create a function that simple moves the players head towards the centre if they are out of bounds. You will need to do this yourself. Should be simple though.
I'm trying it out now and am noticing some things. I get a error with using Vector3s within a Quaternion.Angle() method, I switched it to Vector3.Angle and will give it a shot. I am also noticing an issue of using the power in the LookCurve(float diff) method, I rewrote it using $$anonymous$$athf.Pow(diff/90, 2.5).
A way to draw this in the inspector would be nice, but google does show the curve I want to have. I assume 90 can be replaced with whatever number I have set for the clamped angle at which the player can look up and down?
And to know what values your using for lookDir and faceDir, lookDir is "head" and faceDir is the "body". Please correct my errors in understanding
EDIT::
I tested it out but I had to change the faceDir to accept the body's y position, and lookDir to be the head.forward to see a change in maxAngle. It works however the maxAngle gets into the thousands range when looking up (0 at bottom). I need a curve that when looking down or up the value is 0, and when looking straight is the max number is like 80.
Here what I did:
private float Calculate$$anonymous$$axAngle()
{
Vector3 lookDir = head.forward; //new Vector3(0, head.rotation.y, 0);
Vector3 faceDir = new Vector3(0f, body.position.y, 0f); //.new Vector3(0, body.forward.y, 0);
float diff = $$anonymous$$athf.Abs(Vector3.Angle(lookDir, faceDir)) * 2f;
Debug.Log(diff);
//write the curve function
float angle = LookCurve(diff);
return angle;
}
private float LookCurve(float diff)
{
//linear a diamond shape lookbox
//return 90 - diff;
//cats eye (my diagram)
return 90 * $$anonymous$$athf.Pow(diff / 90, 2.5f);
//return 90 * (1 - (diff / 90)^2.5);
}
Ran through the $$anonymous$$ath Again. There are two mistakes in there:
// Change this
float diff = $$anonymous$$athf.Abs(Vector3.Angle(lookDir, faceDir)) * 2f;
// To this:
float diff = $$anonymous$$athf.Abs(Vector3.Angle(lookDir, faceDir));
AND
// Change this:
return 90 * $$anonymous$$athf.Pow(diff / 90, 2.5f);
// To this
return 90 * (1 - $$anonymous$$athf.Pow(diff / 90, 2.5f));
I Also updated the answer
I am very close to a solution with this, the line curve is does not achieve the "cat's eye" as you called it. It goes on infinitely...
A semi-ellipse or semi-circle would probably achieve the cat's eye. The semi-circle would need to have a max x value of whatever I want it to be (say 80). I just don't know how to achieve that.