0
\$\begingroup\$

Am working on the controls and camera movement for my character. What I am trying to do is have the character head be able to rotate left and right and then when the head is rotated a certain amount, the whole character rotates around. I have kinda of done it, the head can move smoothly, but it stutters when it starts rotating everything.

Hopefully it is visible in this GIF.

GIF

You may be able to see that the head does rotate smoothly, but when the body starts rotating, it stutters.

Here is the code that is in LateUpdate that handles all the rotations.

this.current_rotation = Quaternion.Lerp(this.current_rotation, Quaternion.Euler(new Vector3(this.pitch, this.yaw, 0)), this.mouse_sensitivity * Time.deltaTime);

this.cam.transform.rotation = this.current_rotation;
this.head.transform.rotation = this.current_rotation;

if(this.head.transform.localRotation.y > 0.3 || this.head.transform.localRotation.y < -0.3){
    Quaternion from = Quaternion.Euler(0, this.player.transform.eulerAngles.y, 0);
    Quaternion to = Quaternion.Euler(0, this.current_rotation.eulerAngles.y, 0);

    Quaternion q =  Quaternion.Lerp(from, to, this.mouse_sensitivity * Time.deltaTime);
    this.player.transform.rotation = q;
}
\$\endgroup\$
  • \$\begingroup\$ Can you upload an example project somewhere, or describe the rest of your scene (scripts, object hierarchy) a bit more? Guessing head cube is child of body cube. So when body rotates, head is rotated, and maybe then your mouselook script tries to rotate the head as well. This interferes with the body rotation and, I think, gives you the camera/head stuttering. Also, when you rotate the body, you over-rotate, rotating by delta*speed rather than calculating to get exactly to the 0.3 edge. This could be causing your un-smooth body rotation. \$\endgroup\$ – Chris Mills-Price Nov 23 '16 at 0:23
  • \$\begingroup\$ Hi, here is a test project I created with the bare assets. filedropper.com/sorotation133397 \$\endgroup\$ – JacketPotatoeFan Nov 23 '16 at 0:50
1
\$\begingroup\$

OK, I couldn't get the sample project working in Unity, but I used the script to recreate it with a couple assumptions, as follows:

  • Your Camera_Control.cs script is on the body cube.
  • The head cube is a child of the body cube.
  • The camera is a child of the head cube

I was able to fix this in two ways:

  1. Move the head cube off of the body, so that rotating the body doesn't automatically rotate the head as well.
  2. Or, counter-rotate the head when you do rotate the body, to neutralize the effect.

I assume the latter is the style of solution you wanted. So, I add two new Quaternions (essentially reversed), Lerp between them, and assign that to the cam/head transforms.

this.current_rotation = Quaternion.Lerp(this.current_rotation, Quaternion.Euler(new Vector3(this.pitch, this.yaw, 0)), this.mouse_sensitivity * Time.deltaTime);

this.cam.transform.rotation  = this.current_rotation;
this.head.transform.rotation = this.current_rotation;

if(this.head.transform.localRotation.y > 0.3 || this.head.transform.localRotation.y < -0.3){
    Quaternion from = Quaternion.Euler(0, this.player.transform.eulerAngles.y, 0);
    Quaternion to   = Quaternion.Euler(0, this.current_rotation.eulerAngles.y, 0);

    // Reverse 'y' rotation, maintain x/z rotation
    Quaternion headFrom = this.current_rotation;
    Quaternion headTo   = Quaternion.Euler(headFrom.eulerAngles.x, this.player.transform.eulerAngles.y, headFrom.eulerAngles.z);

    Quaternion q = Quaternion.Lerp(from,     to,     this.mouse_sensitivity * Time.deltaTime);
    Quaternion r = Quaternion.Lerp(headFrom, headTo, this.mouse_sensitivity * Time.deltaTime);
    this.player.transform.rotation = q;
    this.cam.transform.rotation    = r;
    this.head.transform.rotation   = r;
}

That should fix the jitter. You'll still have other rotation work to do afterwards, but at least it'll be smooth. :)

\$\endgroup\$
  • \$\begingroup\$ I think I've wasted your time. I should have explained the setup. I've only just noticed myself (still new to all this), that the script is actually rotating the bones. So for the basic cube with a head, your script works perfectly fine. But because there is an armature, I am not sure how to apply that. See this pic.. i.imgur.com/lHnFpJB.png I can't just move the head and nest the body parts in an empty, as it seems to completely mess up when rotating. Sorry for not knowing this at the time of asking the question. \$\endgroup\$ – JacketPotatoeFan Nov 23 '16 at 17:55
  • \$\begingroup\$ I figured it out, and also reduced the amount of code needed. Basically I just needed to set the head rotation again after I rotate the player. Sorry for wasting your time, I still feel that you offered the best solution based on the information I provided, and I did test your additions to the 2 cube setup, and it worked fine, so will accept your solution. \$\endgroup\$ – JacketPotatoeFan Nov 23 '16 at 18:45
  • \$\begingroup\$ No worries - was fun to mess around with anyways. Glad you figured out your problem. :) \$\endgroup\$ – Chris Mills-Price Nov 23 '16 at 20:19
0
\$\begingroup\$

From your screenshots it looks like the problem may be from the colliders on your head and body object. You are directly manipulating the transform in your code, but while this is happening the physics engine is also trying to handle the collisions between the two colliders and this will result in erratic movement.

If that is the issue, there are a number of ways to avoid that problem, from changing what objects have colliders to having colliders ignoring each other using layering.

\$\endgroup\$
  • \$\begingroup\$ There aren't any colliders on those. They are just 2 cubes for testing purposes. \$\endgroup\$ – JacketPotatoeFan Nov 22 '16 at 23:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.