Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can character's body be continuously rotated when its head is already turned by 60°`?

After some experimenting I parented an empty (HeadCam) to the character's neck. This snippet allow rotation of the head synchronously to the CardboardHead/Camera.

void LateUpdate() {
    neckBone.transform.rotation = Camera.transform.rotation *  Quaternion.Euler( 0,0,-90);
    Camera.transform.position = HeadCam.transform.position;
}

enter image description here

The character's arms shouldn't move when only the head rotates as long in the range -60° to 60° after that I would like to move the whole character with the arms still visible. The following method works as long the character isn't rotated by more than 180° after that the characters flips by 180° how could I achieve constant rotation?

void LateUpdate() {
    Quaternion camRot = Camera.transform.rotation * Quaternion.Euler( 0,0,-90);                 
    neckBone.transform.rotation = camRot;
    float yrot = camRot.eulerAngles.y;
    float ydelta = 0;
    if ( yrot < 300f && yrot > 180 ) {
        ydelta = yrot - 300f;
    }
    if ( yrot > 60f && yrot < 180 ) {
        ydelta = yrot - 60;
    }
    playerObj.transform.rotation =  Quaternion.Euler(0, ydelta, 0); 
    Camera.transform.position = HeadCam.transform.position;
}

enter image description here

A java applet for testing the algorithm standalone: https://github.com/3dbug/blender/blob/master/HeadCamRot.java

like image 623
stacker Avatar asked Jun 04 '15 21:06

stacker


People also ask

How do you rotate a Rigidbody in Assassin's Creed Unity?

Use Rigidbody. MoveRotation to rotate a Rigidbody, complying with the Rigidbody's interpolation setting. If Rigidbody interpolation is enabled on the Rigidbody, calling Rigidbody. MoveRotation will resulting in a smooth transition between the two rotations in any intermediate frames rendered.

What is spatial rotation?

a. a circular motion of a configuration about a given point or line, without a change in shape. b. a transformation in which the coordinate axes are rotated by a fixed angle about the origin.


2 Answers

One possible solution would be:

// Transform of the full body of the character.
Transform body;
// Transform of the head (child of |body| component).
Transform head;
// Maximum delta angle in degrees.
float maxAngle = 60.0f;

void RotateCharacter(Quaternion target) {
  // Rotate head as much as possible without exceeding the joint angle.
  head.rotation = Quaternion.RotateTowards (body.rotation, target, maxAngle);
  // Complete the remainder of the rotation by body.
  body.rotation = target * Quaternion.Inverse (head.localRotation);
}

Please keep in mind that you might need to limit non-horizontal rotations beforehand, i.e., I assumed given x & z angles of the passed rotation won't exceed maxAngle. Besides, even so, it should be quite straightforward to add that limitation as well inside the function above if needed.

Hope it helps.

like image 55
anokta Avatar answered Oct 24 '22 09:10

anokta


Finally I found a solution for this:

private float bodyRot = 0F;
private float FOV = 70f;

void LateUpdate() {
    if ( neckBone != null ) {
        Quaternion camRotQ = CameraFacing.transform.rotation * Quaternion.Euler( 0,0,-90);
        neckBone.transform.rotation = camRotQ;
        float camRot = camRotQ.eulerAngles.y;

        float delta = camRot- bodyRot;
        if ( delta > 180 ) {
            delta -= 360;
        }
        if ( delta < -180 ) {
            delta += 360;
        }
        if ( Math.Abs(delta) > FOV ) {
            if ((delta > FOV || delta < -180) && delta < 180) {
                bodyRot = camRot - FOV;
            }
            delta = camRot- bodyRot;
            if ((delta < FOV || delta > 180 ) ) {
                bodyRot = camRot + FOV;
            }
        }
        playerObj.transform.rotation =  Quaternion.Euler(0, bodyRot, 0); 
        CameraFacing.transform.position = cameraMount.transform.position;
    }
}
like image 1
stacker Avatar answered Oct 24 '22 10:10

stacker