Home > Enterprise >  Unity 3D - How to gllobaly rotate one object based on second
Unity 3D - How to gllobaly rotate one object based on second

Time:01-19

I have got a very large problem with rotation in Unity. What I want:

I have two 3D objects. Just one is for player manipulating, second object Transform.rotation and Transform.position is dependent on object number one with scale of 1/10. It means if I will move first object from (0,0,0) to (10,30,90) then obj.2 will move from (0,0,0) to (1,3,9). It's simple. But I have got LARGE problem with rotation.

I can't make rotation on normal transform because it's based on "local position". Below I present my problem with simplest 2D object situation:

enter image description here

As you can see when I rotate red object 90 degrees the second object rotate 9 degrees and the axes become different in relation to the world. After more transformations in 3D world it make a large mess. For example after some transformations if I will want to rotate 3D object from me (like using accelerator on motocycle) on first make second object rotating from left to right (because it's based on object axis).

Of course using Transform.Rotate instead of Transform.localRotate (or Transform.EulerAngles instead of Transform.localEulerAngles) is not a solutions because it's means only if objects are childrens (it this this case are not).

WHAT I FOUND:

Using Transform.Rotate(Xdegree,Ydegree,Zdegree, Space.World) is solution for rotating second object !

What I need:

Xdegree, Ydegree and Zdegree from first (manipulated by player) object.

Transform.EulerAngles and Transform.Rotation DOESN'T work because it's returns "local objects" rotations.

So... I know that if 3D obj.2 rotation is (0;30;0) and i use obj2.Rotate(45,0,0) then the obj.2 rotation will be (~37.76;~39.23;~26.56) and it's okay. But I dont know how to convert the other way (from "local" rotation XYZ to degrees that I can use on Transform.Rotate() (of course I will divided this values (xyz) by 10 at the end because I have got 1/10 moving scale))

CodePudding user response:

If you need one GameObject to have 1/10 of the rotation and position of another, you could use something like:

//the player-controlled cube
public Transform t1;
//the 1/10 cube
public Transform t2;

void Update(){
    //set the position of t2 to 1/10 of the position of t1
    t2.position = 0.1f * t1.position;
    //get the axis and angle of t1's rotation
    t1.rotation.ToAngleAxis(out float angle, out Vector3 axis);
    //t2 should be rotated in the same direction (axis), but with 1/10th of the angle
    t2.rotation = Quaternion.AngleAxis(angle * 0.1f, axis);
}

Edit: To allow resetting delta rotation and changing targets, you could do something like this. Note: this glitches when it wraps more than a full circle, I'm not an expert on Quaternions so you'd have to figure it out yourself.

    //the player-controlled cube
    public Transform t1;
    //the 1/10 cube
    public Transform t2;
    private Vector3 t1originalPosition;
    private Quaternion t1originalRotation;
    private Vector3 t2originalPosition;
    private Quaternion t2originalRotation;

    void Start()
    {
        ResetTarget(t1);
    }

    void Update()
    {
        if (t1 != null)
        {
            //set the position of t2 to 1/10 of the position of t1
            t2.position = t2originalPosition   0.1f * (t1.position - t1originalPosition);

            Quaternion t1Rotation = t1.rotation * Quaternion.Inverse(t1originalRotation);
            //get the axis and angle of t1's rotation
            t1Rotation.ToAngleAxis(out float angle, out Vector3 axis);

            //t2 should be rotated in the same direction (axis), but with 1/10th of the angle
            t2.rotation = Quaternion.AngleAxis(angle * 0.1f, axis) * t2originalRotation;
        }
        
    }

    public void ResetTarget(Transform target = null)
    {
        t2originalPosition = t2.position;
        t2originalRotation = t2.rotation;

        t1 = target;
        t1originalPosition = t1.position;
        t1originalRotation = t1.rotation;
    }

CodePudding user response:

Use quaternions instead of the euler angles (xyz rotation angles). And simply give the global rotation value (quaternion) of one object to the other. To add together quaternions, you just multiply them together.

  •  Tags:  
  • Related