nicholas-maltbie / PropHunt

PropHunt game attempt using Unity and the Data Oriented Technology Stack
MIT License
11 stars 0 forks source link

Player Object Transformation #158

Open nicholas-maltbie opened 3 years ago

nicholas-maltbie commented 3 years ago

Components to add

This should work by whenever a command is given (this can be a simple debug for the purposes of this issue), a player should delete their current disguise and create a new disguise of a given prop. This will involve three main steps.

  1. Delete current disguise entities, maybe with a entity command buffer to avoid missing entities.
  2. Spawn a new disguise entity and associate it as a child of the player's transformation (so it follows the player). Ensure this command is given on the server so the disguise is associated with all the clients. This may be managed by either synchronizing the id and spawning it locally on each client (or whenever a new client joins) or by spawning a ghost entity on the server that follows the player.
  3. Update the player collider to be the new object shape. This is important to ensure that the player's collider aligns with their new prop shape.

This may involve multiple systems, libraries, or static references to coordinate all of these references and objects depending on the easiest code implementation.

nicholas-maltbie commented 3 years ago

Notes on transforming into props

// If the floor has a MovementTracking component, set the parent of
//  the player entity to be the floor so the player can move along
//  with the floor
if (changedParent && !grounded.Falling && movementTrackingGetter.HasComponent(grounded.hitEntity))
{
    // Taken from this conversation https://forum.unity.com/threads/how-to-convert-localtoworld-to-localtoparent.845725/
    LocalToWorld parentLTW = localToWoldGetter[grounded.hitEntity];
    LocalToWorld childLTW = localToWoldGetter[entity];

    RigidTransform localToWorld_parent = new RigidTransform(parentLTW.Value);
    RigidTransform localToWorld_child = new RigidTransform(childLTW.Value);

    RigidTransform worldToParent = math.inverse(localToWorld_parent);
    RigidTransform localToParent = math.mul(worldToParent, localToWorld_child);

    LocalToParent newLocalToParent = new LocalToParent { Value = new float4x4(localToParent) };
    Parent newParent = new Parent { Value = grounded.hitEntity };
    if (!parentGetter.HasComponent(entity))
    {
        ecbParallelWriter.AddComponent<Parent>(entityInQueryIndex, entity, newParent);
    }
    else
    {
        ecbParallelWriter.SetComponent<Parent>(entityInQueryIndex, entity, newParent);
    }
    if (!localToParentGetter.HasComponent(entity))
    {
        ecbParallelWriter.AddComponent<LocalToParent>(entityInQueryIndex, entity, newLocalToParent);
    }
    else
    {
        ecbParallelWriter.SetComponent<LocalToParent>(entityInQueryIndex, entity, newLocalToParent);
    }

    ecbParallelWriter.SetComponent<Translation>(entityInQueryIndex, entity, new Translation { Value = localToParent.pos });
    ecbParallelWriter.SetComponent<Rotation>(entityInQueryIndex, entity, new Rotation  { Value = localToParent.rot });
}
else
{
    if (parentGetter.HasComponent(entity))
    {
        LocalToWorld childLTW = localToWoldGetter[entity];

        RigidTransform localToWorld_child = new RigidTransform(childLTW.Value);

        ecbParallelWriter.SetComponent<Translation>(entityInQueryIndex, entity, new Translation { Value = localToWorld_child.pos });
        ecbParallelWriter.SetComponent<Rotation>(entityInQueryIndex, entity, new Rotation  { Value = localToWorld_child.rot });

        ecbParallelWriter.RemoveComponent<Parent>(entityInQueryIndex, entity);
        ecbParallelWriter.RemoveComponent<LocalToParent>(entityInQueryIndex, entity);
    }
}