Moving Entities

Moving Entities

Moving an entity requires three components one of which is part of the Unity Entities namespace this is Translation which is what is used to determine the position of an entity. The two other components are destination and movespeed. Destination is the position of where the entity is supposed to go, and movespeed determines the speed at which an entity will move.

public struct Destination : IComponentData  
{  
	public float3 Value;  
}
public struct MoveSpeed : IComponentData  
{  
	public float Value;  
}  

When the components are set up the system for moving an entity can be implemented. This system will be called MoveSystem and implements JobComponentSystem. This makes sure that the system will be multithreaded.

public class MoveSystem : JobComponentSystem

When implementing JobComponentSystem the function JobHandle needs to be overridden. This function will be overridden with our logic for moving an entity.

protected override JobHandle OnUpdate(JobHandle inputDeps)  
{  
	var job = new MoveJob() {dt = Time.deltaTime};  
	return job.Schedule(this, inputDeps);  
}

In this function we setup the MoveJob which is the job that move the entities. Because deltaTime can’t be retrived inside a job and this parameter is need in order to move the entities the correct amount, this is passed on into the job.

MoveJob needs the three components Translation, MoveSpeed and Destination and extends IJobForEach. This is because we want to iterate over all entities with the required components in no particular order.

struct MoveJob : IJobForEach<Translation, MoveSpeed, Destination>    

In addition to the three components MoveJob also needs deltaTime. This is passed to it from outside the job and is, therefore, a Public parameter. Because the parameters inside MoveSpeed and Destination is only read and not written to, these are marked with [Read Only], so other jobs can access them.

struct MoveJob : IJobForEach<Translation, MoveSpeed, Destination>  
{  
	public float dt;  
	public void Execute(ref Translation translation, [ReadOnly]ref MoveSpeed speed, [ReadOnly]ref Destination destination)  
	{	  
	}
 };

Now that the job has been set up the moving logic can be added. This is done by calculating the maximum distance the entity can move in this frame. Afterward, the distance between the entity’s current position and its destination is calculated. This distance is then clamped to make sure the entity does only move the maximum distance allowed by its MoveSpeed. At last, this distance is added to the entity’s Translation. This results in the entity moving a tiny bit every frame.

struct MoveJob : IJobForEach<Translation, MoveSpeed, Destination>  
{  
	public float dt;  
	public void Execute(ref Translation translation, [ReadOnly]ref MoveSpeed speed, [ReadOnly]ref Destination destination)  
	{	  
		float maxDist = speed.Value * dt;  
		float3 dist = destination.Value - translation.Value;  
		dist = math.clamp(dist, -maxDist, maxDist);  
		translation.Value += dist;  
	}
 };

In order to get more performance this job is marked with [BurstCompile].

[BurstCompile]  
struct MoveJob : IJobForEach<Translation, MoveSpeed, Destination>  
{  
	public float dt;  
	public void Execute(ref Translation translation, [ReadOnly]ref MoveSpeed speed, [ReadOnly]ref Destination destination)  
	{	  
		float maxDist = speed.Value * dt;  
		float3 dist = destination.Value - translation.Value;  
		dist = math.clamp(dist, -maxDist, maxDist);  
		translation.Value += dist;  
	}
 };

All Code

// Compenents 
public struct Destination : IComponentData  
{  
	public float3 Value;  
}
public struct MoveSpeed : IComponentData  
{  
	public float Value;  
}  

// Move System
public class MoveSystem : JobComponentSystem
{
	// Job
	[BurstCompile]  
	struct MoveJob : IJobForEach<Translation, MoveSpeed, Destination>  
	{  
		public float dt;  
		public void Execute(ref Translation translation, [ReadOnly]ref MoveSpeed speed, [ReadOnly]ref Destination destination)  
		{	  
			float maxDist = speed.Value * dt;  
			float3 dist = destination.Value - translation.Value;  
			dist = math.clamp(dist, -maxDist, maxDist);  
			translation.Value += dist;  
		}
	 };
	 
	// Need for JobComponentSystem
	protected override JobHandle OnUpdate(JobHandle inputDeps)  
	{  
		var job = new MoveJob() {dt = Time.deltaTime};  
		return job.Schedule(this, inputDeps);  
	}
}

Comments

Popular posts from this blog

Conway's Game of Life