Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Is there a utility for setting worldspace position/rotation on a child transform?

Discussion in 'Entity Component System' started by PhilSA, Oct 10, 2019.

  1. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    So on child transforms, Translation and Rotation are in local space.

    Is there a quick & easy way to set the world position or world rotation of a child transform? Especially for the rotations?

    Or if not, what's the math required for it? Some sort of multiplication of the desired worldspace quaternion by a WorldToLocal matrix?
     
    Last edited: Oct 10, 2019
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
  3. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    yeah it's mostly for the rotation that I feel stuck. I should've made it more clear

    I'm guessing something like this might work, but I wonder if there's a way to do this without needing to access the parent entities
    Code (CSharp):
    1. quaternion parentWorldRotation = new quaternion(parentLocalToWorld.Value);
    2. quaternion desiredWorldRotation = blablabla;
    3. rotation.Value = math.mul(math.inverse(parentWorldRotation ), desiredWorldRotation);
     
    Last edited: Oct 10, 2019
    florianhanke and siggigg like this.
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Afaik we should mul through all parents hierarchy unfortunately :(
     
  5. siggigg

    siggigg

    Joined:
    Apr 11, 2018
    Posts:
    247
    Thank you, this finally put me on the right track :) I set up two update queries, one for entities without a parent (just set Rotation directly) and then the second one based on your idea.

    I'm sure there's a more elegant solution to this, and I would love to hear it too! ;) but for now, this works.

    This example btw is for billboards facing the camera but with a locked up axis.

    Code (CSharp):
    1. Entities.WithName("FaceCameraSystem_ForEachNoParent")
    2.         .WithNone<Parent>()
    3.         .ForEach(
    4.                 (ref Rotation rotation, in LocalToWorld localToWorld, in FaceCamera faceCamera) =>
    5.                 {
    6.                     var direction = math.normalize(cameraPos - localToWorld.Position);
    7.                     rotation.Value = quaternion.LookRotationSafe(new float3(direction.x, 0, direction.z), localToWorld.Up);
    8.                 })
    9.         .Run();
    10.  
    11. Entities.WithName("FaceCameraSystem_ForEachWithParent")
    12.         .WithReadOnly(ltws)
    13.         .ForEach(
    14.                 (ref Rotation rotation, in LocalToWorld localToWorld, in Parent parent, in FaceCamera faceCamera) =>
    15.                 {
    16.                     var direction = math.normalize(cameraPos - localToWorld.Position);
    17.                     var newRotation = quaternion.LookRotationSafe(new float3(direction.x, 0, direction.z), localToWorld.Up);
    18.  
    19.                     var parentLTW = ltws[parent.Value];
    20.                     var parentWorldRotation = new quaternion(parentLTW.Value);
    21.                     rotation.Value = math.mul(math.inverse(parentWorldRotation), newRotation);
    22.                 })
    23.         .Run();