Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Instancing and hierarchical transformation of an assembly of physics blocks -

Discussion in 'Physics for ECS' started by roryo, Oct 10, 2020.

  1. roryo

    roryo

    Joined:
    May 21, 2009
    Posts:
    1,482
    I am procedurally generating structures made of physics blocks and I am wondering how best to instantiate and transform complex assemblies of these blocks prior to simulation. Is it correct to assume that Entity parenting won't work, since that might interfere with the transformations of the blocks during physics simulation?

    For example, once this wall of discreet blocks is generated, the player may want to instantiate it and rotate the copy:

    Screen Shot 2020-10-10 at 2.39.30 PM.png


    What would be the best way to do this? Could it be that there is hierarchical transformation through parent/child components that gets removed when "building" the structure mode is done and as PhysicVelocity components are being added?
     
  2. steveeHavok

    steveeHavok

    Joined:
    Mar 19, 2019
    Posts:
    481
    For dynamic bodies the Translation and Rotation components are assumed to be in world space. So, as you say, adding a Parent component will cause problems.

    If the hierarchy is there while placement is happening, then when placement finishes and physics components are to be added, the LocalToWorld matrix of each block could be read and decomposed. Then when the Parent components are removed the Translation and Rotation components can be set from the decomposed matrix. This sort of thing happens when GameObject information is converted to ComponentData structs in the PhysicsShape conversion system and you can check out the local package code in <Project>\Library\PackageCache\com.unity.physics@x.y.z\Unity.Physics.Hybrid\Utilities\PhysicsShapeExtensions.cs

    That might be overly complicated for your own specific needs though. The simpler option is just to get Translation and Rotation values using the
    Unity.Physics.Math.DecomposeRigidBodyTransform
    function.
    For example:

    Code (CSharp):
    1.                     var worldFromBody = Math.DecomposeRigidBodyTransform(GetComponent<LocalToWorld>(entity).Value);
    2.                     position = new Translation { Value = worldFromBody.pos };
    3.                     rotation = new Rotation { Value = worldFromBody.rot };
    Alternatively, if all the blocks have already been stripped of their hierarchy and you want to move a block that already has the Translation, Rotation and Physics components setup, then the sample RagdollDemo script does something like similar to moving a bunch of independent entities as if they were one unit when placing the final body parts of the ragdoll. The code uses a positionOffset, a rotationOffset and some common position to shift and rotate all the bodies e.g.

    Code (CSharp):
    1.             for (int i = 0; i < entities.Length; i++)
    2.             {
    3.                 var e = entities[i];
    4.  
    5.                 Translation positionComponent = EntityManager.GetComponentData<Translation>(e);
    6.                 Rotation rotationComponent = EntityManager.GetComponentData<Rotation>(e);
    7.  
    8.                 float3 position = positionComponent.Value;
    9.                 quaternion rotation = rotationComponent.Value;
    10.  
    11.                 float3 localPosition = position - oldCommonPosition;
    12.                 localPosition = math.rotate(rotationOffset, localPosition);
    13.  
    14.                 position = localPosition + oldCommonPosition + positionOffset;
    15.                 rotation = math.mul(rotation, rotationOffset);
    16.  
    17.                 positionComponent.Value = position;
    18.                 rotationComponent.Value = rotation;
    19.  
    20.                 EntityManager.SetComponentData<Translation>(e, positionComponent);
    21.                 EntityManager.SetComponentData<Rotation>(e, rotationComponent);
    22.             }
    23.         }
     
    roryo likes this.
  3. roryo

    roryo

    Joined:
    May 21, 2009
    Posts:
    1,482
    Thanks, @steveeHavok - these are great ideas! And I am happy to hear about Math.DecomposeRigidBodyTransform, which I wasn't aware of.