Search code examples
unity-game-enginerotationeuler-angles

Euler angles for a direction respect to rotated local axis system in unity


I want a determined angle in a local rotated axis system. Basically I want to achieve the angle in a plane of a determined rotated axis system. The best way to explain it is graphically.

Enter image description here

I can do that projecting the direction from origin to target in my plane, and then use Vector3.Angle(origin forward dir, Projected direction in plane).

Is there is a way to obtain this in a similar way like Quaternion.FromToRotation(from, to).eulerAngles; but, with the Euler angles, with respect to a coordinate system that is not the world's one, but the local rotated one (the one represented by the rotated plane in the picture above)?

So that the desired angle would be, for the rotation in the local y axis: Quaternion.FromToRotation(from, to).localEulerAngles.y, as the locan Euler angles would be (0, -desiredAngle, 0), based on this approach.

Or is there a more direct way than the way I achieved it?


Solution

  • If I understand you correct there are probably many possible ways to go.

    I think you could e.g. use Quaternion.ToAngleAxis which returns an Angle and the axis aroun and which was rotated. This axis you can then convert into the local space of your object

    public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
    {
        // As you had it already, still in worldspace
        var rotation = Quaternion.FromToRotation(obj.forward, vector);
        rotation.ToAngleAxis(out var angle, out var axis);
    
        // Now convert the axis from currently world space into the local space
        // Afaik localAxis should already be normalized
        var localAxis = obj.InverseTransformDirection(axis);
    
        // Or make it float and only return the angle if you don't need the rest anyway
        return localAxis * angle;
    }
    

    As alternative as mentioned I guess yes, you could also simply convert the other vector into local space first, then Quaternion.FromToRotation should already be in local space

    public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
    {
        var localVector = obj.InverseTransformDirection(vector);
    
        // Now this already is a rotation in local space
        var rotation = Quaternion.FromToRotation(Vector3.forward, localVector);
        
        return rotation.eulerAngles;
    }