Ez.Threading allows you to start asynchronous tasks in Unity. These tasks can be performed on the Update or FixedUpdate, and it is possible to define more.
Moving an object each frame at a give speed is as simple as :
public class MoveOnUpdate : MonoBehaviour
{
public float Speed;
void Start()
{
UnityContext.Update
.CreateTask()
.RelativeToLast()
.ProcessWith(deltaTime =>
{
var direction = new Vector3(
Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical"));
transform.position += direction * Speed * deltaTime;
});
}
}
Starting a physics movement is as simple as :
public class DashBehavior : MonoBehaviour
{
public float Duration;
public float Speed;
public RigidBody rigidBody;
void Update()
{
if(Input.GetButtonDown("Fire1"))
UnityContext.FixedUpdate
.CreateTask()
.EndingIn(Duration)
.RelativeToLast()
.ProcessWith(deltaTime =>
{
var direction = transform.up;
rigidBody.MoveTo(transform.position + (direction * Speed * deltaTime));
});
}
}
- Copy the library to your project
- Add a _UnityContext to the scene, the prefab can be found in "_Libraries\Ez\Prefabs_UnityContext"
- You are now ready to use the system
The namespace Ez.Threading.UnityContext exposes 2 task managers
- Update : will run tasks on the Update
- FixedUpdate : will run tasks on the FixedUpdate
From there you can easily start an action on each frame :
// this will execute on each frame
UnityContext.Update
.CreateTask()
.RelativeToLast()
.ProcessWith(deltaTime =>
{
var direction = new Vector3(
Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical"));
transform.position += direction * Speed * deltaTime;
});
Or you can start a task on each physics update :
var rigidBody = GetComponent<RigidBody>();
// this will execute on each physics update
UnityContext.FixedUpdate
.CreateTask()
.RelativeToLast()
.ProcessWith(deltaTime =>
{
var direction = new Vector3(
Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical"));
rigidBody.MoveTo(transform.position + (direction * Speed * deltaTime));
});
// this will execute on each frame
var task = UnityContext.FixedUpdate
.CreateTask()
.ProcessWith(now =>
{
// here comes the code that will be executed
// optionally you can tell the task to finish early by returning false
});
// this will execute on each physics update
var task = UnityContext.FixedUpdate
.CreateTask();
.ProcessWith(now =>
{
// here comes the code that will be executed
// optionally you can tell the task to finish early by returning false
});
task
.ProcessWith(message =>
{
# # // you can tell the task to finish early by returning false
# # // you can tell the task to finish early by returning false
# // you can tell the task to finish early by returning false
})
// this will execute on each frame
var task = UnityContext.FixedUpdate
.CreateTask()
.ContinueWith(completed =>
{
// optionally you can tell the task to finish early by returning false
});
// this will execute on each physics update
var task = UnityContext.FixedUpdate
.CreateTask();
.ContinueWith(completed =>
{
// here comes the code that will be executed when the task is completed
});
The Ez.Threading.TaskExtension and Ez.Threading.TimeExtension classes provide may useful methods :
task
.Where(message =>
{
// return true if the message should be processed,
// return false otherwise
})
.ProcessWith(validMessage =>
{
// only the messages filtered will reach here
// optionally you can tell the task to finish early by returning false
});
task
.Select(message =>
{
// return the message converted
})
.ProcessWith(convertedMessage =>
{
// the messages here are the converted messages
// optionally you can tell the task to finish early by returning false
});
UnityContext.Update
.StartingIn(timeToWaitInSeconds)
.ProcessWith(now =>
{
// the first time this code is executed is timeToWaitInSeconds later
// optionally you can tell the task to finish early by returning false
});
UnityContext.Update
.EndingIn(timeToWaitInSeconds)
.ProcessWith(now =>
{
// this will be executed until the timeToWaitInSeconds has passed
# // optionally you can tell the task to finish early by returning false
# // optionally you can tell the task to finish early by returning false
});
task.PublishCompletion(false);
It uses one MonoBehaviour to push messages through Ez.Threading.UnityContext.
- There is an overhead of creating objects when creating a task and a garbage collection when a task is completed
- This can impact performances
- This might get improved in future versions