lower and upper body rotation

Hello. Being fairly new to the world of coding, I am facing a problem.

I have the typical behavior of a human body to apply.

I have the upper body is a child of the lower body.
it is on the lower body that my script is attached.

The upper body must turn to + 45 ° - 45 ° (min… an max… var). If one tries to turn over, the entire body rotating at 45 ° (and so on).
For the upper body (upperCube), I did this:

 var sensitivity : float = 5;
 var xRotation : float;
 var lowerCubeRotation : float;
 var upperCube : GameObject;
 var minUpperCubeXRotation = -45;
 var maxUpperCubeXRotation = 45;

function Update () {
var controller = GetComponent(CharacterController);
xRotation += Input.GetAxis("Mouse X") * sensitivity;
Rotation();
}

function Rotation() {
if (xRotation > maxUpperCubeXRotation){
}

if (xRotation < minUpperCubeXRotation){
}

upperCube.transform.localEulerAngles = Vector3(0, xRotation, 0);

}

So the upper body rotates and if it reaches one of the limits, the lower body must perform a rotation of 45 ° (var lowerCubeRotation) over a period of 3 seconds (to be defined in a var) and the upper body returns to allignment with the lower body.

But how to code the part of the lower body. As I said, I suck.
I tested:

transform.Rotate(0, lowerCubeRotation, 0);

xRotation -= minUpperBodyXRotation;

which applies a rotation of 45 ° to transform (lower body), but instantly. And a rotation of the upper body to 0 (at the bottom allignment).

My problem lies in the duration of the rotation. I want it to end after x seconds, not immediately.

need help please.
(post on unity forum)

use google translate

You’re in the right path: use euler angles to set the rotation, and always set x, y and z at the same time. You can use Mathf.MoveTowards to move only the angle y at constant speed (degrees per second): save the initial lower part euler angles, and when the upper part goes out of the limits, add the upper rotation to the initial lower part y angle, then set the new target angle.

var sensitivity : float = 5;
var xRotation : float;
var lowerCubeRotation : float;
var upperCube : GameObject;
var minUpperCubeXRotation = -45;
var maxUpperCubeXRotation = 45;
var speed: float = 180; // degrees per second

private var targetAngle: float; // angle around y to reach
private var curAngle: float; // current angle around y
private var iniAngle: Vector3; // initial complete euler angles
private var controller: CharacterController;

function Start(){
  controller = GetComponent(CharacterController);
  iniAngle = transform.eulerAngles; // save the complete initial euler angles
  targetAngle = iniAngle.y; // initialize the target...
  curAngle = iniAngle.y; // and the current Y angles
}

function Update () {
  xRotation += Input.GetAxis("Mouse X") * sensitivity;
  Rotation();
}

function Rotation() {
  // set the upper part rotation (use modulo 360 to avoid crazy rotations):
  upperCube.transform.localEulerAngles = Vector3(0, xRotation % 360, 0);
  if (xRotation > maxUpperCubeXRotation || xRotation < minUpperCubeXRotation){
    // if xRotation gone out of limits...
    targetAngle = iniAngle.y + xRotation; // find the new target angle
  }
  // "move" the current angle gradually each update...
  curAngle = Mathf.MoveTowards(curAngle, targetAngle, speed * Time.deltaTime);
  // keep the original x and z angles, and set the current angle modulo 360
  transform.eulerAngles = Vector3(iniAngle.x, curAngle % 360, iniAngle.z);
}

Thank you for the answer. I used some of what you said for this:

var sensitivity : float = 5;
var xRotation : float;
var upperBodyXRotation : float;
var speed: float = 180;
var upperBody : GameObject;
var minUpperBodyXRotation : float;
var maxUpperBodyXRotation : float;

private var transformTargetAngle : float;
private var transformCurrentAngle : float;
private var transformInitialAngle : Vector3;

function Start() {
	controller = GetComponent(CharacterController);
	transformInitialAngle = transform.eulerAngles;
	transformTargetAngle = transformInitialAngle.y;
	transformCurrentAngle = transformInitialAngle.y;
}

function Update () {
	xRotation += Input.GetAxis("Mouse X") * sensitivity;
	upperBodyXRotation = xRotation;
	if (upperBodyXRotation > maxUpperBodyXRotation) {
		upperBodyXRotation = maxUpperBodyXRotation;
	}
    if (transform.eulerAngles.y == transformTargetAngle) {
        transformInitialAngle = transform.eulerAngles;
    }
	Rotation();
}

function Rotation() {
	if (upperBodyXRotation == maxUpperBodyXRotation) {
		upperBodyXRotation -= maxUpperBodyXRotation;
		transformTargetAngle = transformInitialAngle.y + maxUpperBodyXRotation;
		transformCurrentAngle = Mathf.MoveTowards(transformCurrentAngle, transformTargetAngle, speed * Time.deltaTime);
		transform.eulerAngles = Vector3(transformInitialAngle.x, transformCurrentAngle % 360, transformInitialAngle.z);
		
	}
	upperBody.transform.eulerAngles = Vector3(0, xRotation % 360, 0);
}

in this case, when the upper body reaches 45 ° (maxUpperBodyXRotation), it runs the function that turns the lower body 45 degrees. The upper body is found at 0 ° with:

upperBodyXRotation -= maxUpperBodyXRotation;

logically, when I start again to turn the upper body 45 °, rotation of the lower basin should turn 45 degrees but it does not.
“upperBodyXRotation” reste à 0.

I think for the rotation of the lower body, just change the “transform.eulerAngles” of “transformInitialAngle = transform.eulerAngles” by the new “transform.eulerAngles” from rotation function.

I tested this to reassign “transform.eulerAngles” with that obtained in the rotation function but it does not work:

if (transform.eulerAngles.y == transformTargetAngle) {
	transformInitialAngle = transform.eulerAngles;
}

So to summarize, at present, I can rotate that lasts x seconds at the bottom of the body when the upper body is “maxUpperBodyXRotation” but this only works once. How can it be repeated?

I want that if the upper body rotates at an angle of 45 ° (maxUpperBodyXRotation) from the lower body, lower body rotates 45 ° (“maxUpperBodyXRotation” or other). Thus, the upper body is at the same rotation as the lower body (0, allignment upper and lower body) and subsequently, the action can be repeated.

May I ask a lot. But from the world of 3D, I know very little the world of the script. I learn every day a little more but sometimes I stuck.
So if someone can give me his help, thank you.