Skip to content

Instantly share code, notes, and snippets.

@mrtrizer
Last active September 5, 2023 09:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrtrizer/cfe9439a74b7131680a21c16e6a2c1cf to your computer and use it in GitHub Desktop.
Save mrtrizer/cfe9439a74b7131680a21c16e6a2c1cf to your computer and use it in GitHub Desktop.
Basic Tweener for Unity3d
static bool initialized;
static Action staticUpdate;
public static Task Tween<T>(T startValue, T endValue, float duration, Func<T, T, float, T> function, Action<T> callback, CancellationToken? cToken = null)
{
if (!initialized)
{
initialized = true;
var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop();
const int updateSubSystemIndex = 5;
playerLoop.subSystemList[updateSubSystemIndex].updateDelegate += () => staticUpdate?.Invoke();
UnityEngine.LowLevel.PlayerLoop.SetPlayerLoop(playerLoop);
}
float startTime = Time.time;
float endTime = startTime + duration;
var taskCompletionSource = new TaskCompletionSource<bool>();
void Update()
{
if (Time.time < endTime)
{
if (cToken?.IsCancellationRequested ?? false)
{
taskCompletionSource.SetCanceled();
staticUpdate -= Update;
return;
}
float t = (Time.time - startTime) / duration;
T currentValue = function(startValue, endValue, t);
callback(currentValue);
}
else
{
taskCompletionSource.SetResult(true);
staticUpdate -= Update;
callback(endValue);
}
}
staticUpdate += Update;
return taskCompletionSource.Task;
}
public static Vector3 SmoothStepVector3(Vector3 start, Vector3 end, float t)
{
return new Vector3(Mathf.SmoothStep(start.x, end.x, t), Mathf.SmoothStep(start.y, end.y, t), Mathf.SmoothStep(start.z, end.z, t));
}
static async void Test(VisualElement myElement)
{
CancellationTokenSource cts = new CancellationTokenSource();
await Task.WhenAll(
Tween(1.0f, 0.0f, 1, Mathf.SmoothStep, value => myElement.style.opacity = value, cts.Token),
Tween(Vector3.zero, Vector3.one, 1, SmoothStepVector3, value => myElement.transform.position = value, cts.Token),
Tween(1.0f, 360.0f, 2, Mathf.Lerp, value => myElement.transform.rotation = Quaternion.EulerRotation(new Vector3(0, value, 0)), cts.Token)
);
await Tween(360.0f, 1.0f, 2, Mathf.Lerp, value => myElement.transform.rotation = Quaternion.EulerRotation(new Vector3(0, value, 0)), cts.Token);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment