Search Unity

How do you set non-local rotation in ECS? (also: documentation feedback)

Discussion in 'Entity Component System' started by dthurn, Mar 26, 2019.

  1. dthurn

    dthurn

    Joined:
    Feb 17, 2015
    Posts:
    77
    Hi, really quick question: how do you set the global rotation of an entity in ECS? It seems that the Rotation component always sets the equivalent of transform.localRotation, while I'm looking for transform.rotation.

    Also, some documentation feedback: I spent a good 15 or 20 minutes reading over the Transforms documentation for ECS trying to answer this question, and while I feel like I understand what's going on under the hood better now, I think this page could be really improved by adding just a few examples of how things map from the MonoBehaviour world, like "hey, remember transform.localPosition? Now it's called Translation!", etc.
     
    BigRookGames, jdtec and Sarkahn like this.
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,776
    Just use Rotation Component instead.
    You can use for example
    Code (CSharp):
    1. GetComponentDataFromEntity <Rotation> () ;
     
    Stephen_O likes this.
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Set world rotation - multiply your world rotation to inversed LocalToWorld matrix associated with entity
    Get world rotation - multiply rotation from Rotation component to LocalToWorld matrix associated with entity
     
  4. dthurn

    dthurn

    Joined:
    Feb 17, 2015
    Posts:
    77
    @Antypodish The Rotation component sets local rotations, not world-space rotation

    @eizenhorn Do you mean multiply the entire matrix by the quaternion? Because that gives me some freaky effects and changes scale and stuff.

    I'm basically trying to translate this code from Unity:

    Code (CSharp):
    1. transform.rotation = Quaternion.LookRotation(target.position - transform.position, Vector3.up);
    2.  
    I tried multiplying by LocalToWorld like this but it didn't go well:

    Code (CSharp):
    1. rotation.Value = math.mul(
    2.     math.inverse(localToWorld.Value),
    3.     quaternion.LookRotationSafe(rotationData.TargetPosition - rotationData.SourcePosition, Vector3.up).value);
    Or is there some specific element of LocalToWorld which holds the parent rotation?
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,776
    @dthurn are yo on Unity 2018, or 2019?

    Makes really no sense to me, if that what is happening. My understanding was, that transform.localRotation meant to be strictly for local rotation.
     
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    No. Simple multiplication it’s for translation. For rotation you also use sum/subtract of sin cos per axis.
     
  7. MadboyJames

    MadboyJames

    Joined:
    Oct 28, 2017
    Posts:
    262
    Could you post a code snippet demonstrating getting a global rotation from LocalToWorld? I am struggling to make it work.
     
    ADHDCoder likes this.
  8. Leonidas85

    Leonidas85

    Joined:
    Mar 11, 2015
    Posts:
    14
    Code (CSharp):
    1.  Quaternion.LookRotation(localToWorld.Forward, localToWorld.Up)
    As to the answer of the topic's question;
    For an entity without a parent you can set the rotation to the world rotation and then you need to recalculate the LocalToWorld matrix. This can be done by creating a new float4x4 matrix from the Translation and Rotation values.

    For an entity _with_ a parent you also need to update the LocalToParent matrix which is more involved. You will need to get the parent's LocalToWorld matrix, calculate the position and rotation difference and use those to define the Rotation and Translation, and then create a new LocalToParent and LocalToWorld matrix.

    In both cases if the entity you're setting the world rotation for also has children you'll need to recurse through them to update their LocalToWorld matrices.

    You can find an example of all of the above here: https://forum.unity.com/threads/how-to-set-nested-translation-to-world-position.756224/#post-5059022
     
    Last edited: Oct 12, 2019
    Projekt-Krieg likes this.
  9. Projekt-Krieg

    Projekt-Krieg

    Joined:
    Apr 5, 2013
    Posts:
    4
    for everybody else who searches a way to get the localRotation as WorldRotation in ECS jobs:


    Code (CSharp):
    1. public static quaternion GetWorldRotation(LocalToWorld ltw)
    2.     {
    3.         return quaternion.LookRotationSafe(ltw.Forward, ltw.Up);
    4.     }
    this bit made my day hell
     
  10. ScriptsEngineer

    ScriptsEngineer

    Joined:
    Jun 8, 2018
    Posts:
    37
    any direct solution to configure world rotation?
     
  11. thelebaron

    thelebaron

    Joined:
    Jun 2, 2013
    Posts:
    857
    why not just
    Code (CSharp):
    1. var worldRotation = new quaternion(localToWorld.Value);
    also to set
    Code (CSharp):
    1. var localToWorld = new LocalToWorld
    2.             {
    3.                 Value = float4x4.TRS(translation, rotation, scale)
    4.             };
     
    jmcusack and ScriptsEngineer like this.
  12. ScriptsEngineer

    ScriptsEngineer

    Joined:
    Jun 8, 2018
    Posts:
    37
    thank you @thelebaron, now already know a way to follow!