Kanda Interactions 0.7.1
Loading...
Searching...
No Matches
Socketing Objects

The Socket system allows users to snap/attach an entity to a specific Socket entity. We called the socketed entity Socketable.

The main case we can use Socket-Socketable is when we want an object/entity to be placed in a specific position and rotation every time.

Whenever user move the Socketable entity close/touching the Socket's collider, the Socketable entity will be snapped to the Socket's position. For this to happen, both socket and socketable must have same SocketFilterData.

Important: Both Socket and Socketable needs to be Ghost entity because they need to be synched between server and client.

Core Components

Socket

Marks an entity as socket and keep the reference to the SocketableEntity socketed to it:

public struct Socket : IComponentData, IEnableableComponent
{
public Entity SocketableEntity;
}

Socketable

Marks an entity as socketable that is allowed to be socketed to a socket:

public struct Socketable : IComponentData, IEnableableComponent
{
public bool HintOverriden;
}

SocketFilterData

Buffer added to socket and socketable during authoring so that both can hold a list of socket filters:

[InternalBufferCapacity(2)]
public struct SocketFilterData : IBufferElementData
{
public FixedString64Bytes SocketFilter;
}

SocketableHintTemplate

Specify source entities that will be used when initializing hint entities at runtime when the socket hint is shown whether it is available or overlapped.

public struct SocketableHintTemplate : IComponentData
{
public Entity HintAvailableTemplateEntity;
public Entity HintOverlapTemplateEntity;
}

SocketableHintTemplatesInitialized

Tags the socketables, whose hints templates have not been created yet.

public struct SocketableHintTemplatesInitialized : IComponentData, IEnableableComponent { }

SocketableHintTemplateInstance

Tags the hint template entities created at runtime from either Socketable itself or SocketableHintTemplate.HintAvailableTemplateEntity/HintOverlapTemplateEntity.

public struct SocketableHintTemplateInstance : IComponentData, IEnableableComponent
{
public Entity Socketable;
public bool IsAvailable;
}

SocketableHintVisual

Tag the instantiated hint entities from socketable's template entities when socketable is grabbed. It keeps reference to the instantiated hint entity. SocketVisualSystem caches the entities with this component to avoid creating and destroying every frame. It also allows querying all the instantiated hint objects easily.

public struct SocketableHintVisual : IComponentData
{
public Entity Instance;
}

SocketOverlap

Marks that a socketable overlaps with a socket entity. The overlapped socket entity is also saved in the component:

public struct SocketOverlap : IComponentData, IEnableableComponent
{
public Entity SocketEntity;
}

SocketFilter

SocketFilter is a scriptable object to be used to define socketable-socket pairs. It can be created by Create->SocketSystem/SocketFilter.

Intended Use

Basic Setup

Socket

To make an entity socket, add Socket and PhysicsCollider components:

// Create basic entity
var entity = EntityManager.CreateEntity(
typeof(LocalTransform),
typeof(LocalToWorld),
typeof(Socket));
// Add Physics Collider
EntityManager.AddComponentData(entity, new PhysicsCollider
{
Value = BoxCollider.Create(
new BoxGeometry
{
Center = float3.zero,
Orientation = quaternion.identity,
Size = new float3(0.2f),
},
CollisionFilter.Default
),
});

Socketable

To make an entity socketable, add Socketable, SocketOverlap, SocketableHintTemplate components.

// Create socketable entity
var entity = EntityManager.CreateEntity(
typeof(LocalTransform),
typeof(LocalToWorld),
typeof(Interactable),
typeof(ActiveInteractable),
typeof(Attachable),
typeof(Movable),
typeof(Socketable),
typeof(SocketOverlap));
// Add SocketableHint
EntityManager.AddComponentData(entity, new SocketableHintTemplate()
{
HintAvailableTemplateEntity = GetEntity(authoring.HintOverride, TransformUsageFlags.Dynamic), // usually has blue transparent material
HintOverlapTemplateEntity = GetEntity(authoring.HintOverride, TransformUsageFlags.Dynamic) // usually has white transparent material
});
// Add SocketFilterData
var socketFilterDatas = AddBuffer<SocketFilterData>(entity);
foreach (
var socketFilterData in from socketFilter in authoring.SocketFilters
where socketFilter != null
select new SocketFilterData { SocketFilter = socketFilter.GUID ?? string.Empty }
)
{
socketFilterDatas.Add(socketFilterData);
}
// Enable Socketable & Disable SocketOverlap
EntityManager.SetComponentEnabled<Socketable>(entity, true);
EntityManager.SetComponentEnabled<SocketOverlap>(entity, false);
// Add Physics Collider
EntityManager.AddComponentData(entity, new PhysicsCollider
{
Value = BoxCollider.Create(
new BoxGeometry
{
Center = float3.zero,
Orientation = quaternion.identity,
Size = new float3(0.2f),
},
CollisionFilter.Default
),
});

Base Flow

  • Socketable hints entities are generated as children of socketables in SocketHintInitializationSystem.
  • When any socketable entity is grabbed, a new hint entity is instantiated from SocketableHintTemplate.HintAvailableTemplateEntity in the location of all of the sockets with same SocketFilter.
  • When the grabbed socketable entity is overlapping with socket entity, SocketOverlap in socketable entity is enabled. Then a new hint entity is instantiated from SocketableHintTemplate.HintOverlapTemplateEntity under the overlapped socket.
  • When the grabbed socketable entity is released while it is overlapping, the socketable entity will be socketed to the socket entity.
  • When the socketable entity is grabbed by the interactor (hand) while it is socketed, the socketable entity will desocket from its socket making the socket to be available again.