https://github.com/staledonuts/btweens
A small Tweener for unity using UniTask.
https://github.com/staledonuts/btweens
actions animation async game-development tween tweening unitask unity unity2d unity3d
Last synced: 2 months ago
JSON representation
A small Tweener for unity using UniTask.
- Host: GitHub
- URL: https://github.com/staledonuts/btweens
- Owner: staledonuts
- License: mit
- Created: 2025-06-28T08:35:19.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-06-28T22:15:41.000Z (12 months ago)
- Last Synced: 2025-06-28T23:21:08.227Z (12 months ago)
- Topics: actions, animation, async, game-development, tween, tweening, unitask, unity, unity2d, unity3d
- Language: C#
- Homepage:
- Size: 1020 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

# BTweens v0.4.0
```
Latest release:
- Added pause / resume support, groups and sequences for composing tweens.
- Exposed CancellationToken support for integration with UniTask flows.
- Improved editor helpers and inspector UX for faster tweaking.
- Continued performance work: optimized hash handling and lower GC pressure.
```
Note: This package is actively developed and used in personal and hobby projects. Contributions are welcome — please keep changes focused, small, and well-documented so the core stays slim and easy to adopt.
## Async Tween Engine for Unity
A lightweight, and easy-to-use asynchronous tweening engine for Unity, built on top of [UniTask](https://github.com/Cysharp/UniTask). This package provides an extension-method-based API to animate properties of GameObjects and UI elements with minimal setup.
## Core Features
- **Async**: Built on Cysharp.Threading.Tasks (UniTask) for efficient, allocation-light, non-blocking animations.
- **Lifecycle Management**: Tweens are cancelled automatically when the owner GameObject is destroyed to avoid invalid callbacks and memory leaks.
- **Optimized**: Internal use of pre-computed `uint` hash keys for very fast tween identification and lower string work in hot paths.
- **Extension Methods**: A compact API surface — call `.TweenLocalPosition(...)`, `.TweenAlpha(...)` and similar helpers directly on common Unity components.
- **Groups & Sequences**: Compose multiple tweens into a group or sequence to play them together or in order (new in v0.4.0).
- **Pause / Resume**: Pause and resume individual tweens or whole groups without canceling them.
- **CancellationToken support**: All public async methods accept or respect UniTask cancellation tokens, so you can integrate tweens into your async flows safely.
- **Specialized UI Helpers**: Helpers like `TweenToOffScreen` compute offscreen targets for RectTransforms automatically.
## 🚀 How to Use
The easiest way to use BTween is via the provided extension methods on common Unity components. All tween methods return a UniTask-compatible handle you can await, cancel, or control via the manager API.
### Basic Example: Fading and Scaling UI
This example shows how to fade in a UI panel and apply an elastic scaling effect to a title element.
```C#
using UnityEngine;
using Cysharp.Threading.Tasks;
public class SimpleUIAnimator : MonoBehaviour
{
public CanvasGroup panelCanvasGroup;
public Transform titleTransform;
void Start()
{
// Set initial states
panelCanvasGroup.alpha = 0f;
titleTransform.localScale = Vector3.zero;
// Animate the alpha of the CanvasGroup to 1 over 0.5 seconds.
// This automatically uses an optimized, pre-hashed key for "Alpha".
panelCanvasGroup.TweenAlpha(1f, 0.5f);
// Animate the local scale using a built-in elastic ease.
await titleTransform.TweenLocalScale(Vector3.one, 0.7f, easeFunction: BTween.Ease.OutElastic);
// Or if you don't want to await and don't care about completion:
titleTransform.TweenLocalScale(Vector3.one, 0.7f, easeFunction: BTween.Ease.OutElastic).Forget();
}
}
```
---
## Chaining Animations with async/await
Because BTween is built on UniTask, you can await any tween. This makes sequential animations trivial — and because tweens respect cancellation tokens, you can safely cancel an awaiting call when your object is destroyed or a workflow changes.
In this example, an AnimateOut() method fades out a panel and then, once the fade is complete, moves it off-screen.
```C#
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
public class SequentialAnimator : MonoBehaviour
{
public CanvasGroup panelCanvasGroup;
public Button myButton;
void Start()
{
myButton.onClick.AddListener(() => AnimateOut().Forget());
}
public async UniTask AnimateOut()
{
// 1. Await the alpha tween. The code will pause here until it's done.
await panelCanvasGroup.TweenAlpha(0f, 0.3f, easeFunction: BTween.Ease.InQuad);
// 2. Now move the rect off-screen and await completion.
await panelCanvasGroup.transform.GetComponent()
.TweenToOffScreen(OffScreenDirection.Bottom, 0.5f, easeFunction: BTween.Ease.InOutCubic);
panelCanvasGroup.gameObject.SetActive(false);
}
}
```
---
## 🚀 Optimizing with Hash Keys
BTweens uses `uint` hash keys internally to avoid repeated string allocations and comparisons in hot paths. Extension methods automatically use pre-hashed ids so you don't need to do anything special.
Manual Optimization (Static API)
When using the static `BTween.Float()` or other static APIs for custom tweens, you can provide a `uint` hash instead of a string for best performance. Use `BTween.StringHash("YourKey")` once and cache it in a static field.
Stopping & Controlling Tweens
Use `BTween.StopTween(...)`, `BTween.PauseTween(...)`, and `BTween.ResumeTween(...)` to manage lifecycle. You can pass either a string (convenient) or a cached `uint` hash (fast).
```C#
public void StopPanelFade()
{
// Convenience method (hashes the string "Alpha" internally):
BTween.StopTween(panelCanvasGroup, "Alpha");
// Most performant method (uses the pre-hashed const value):
BTween.StopTween(panelCanvasGroup, TweenPropertyIDs.Alpha);
}
public void StopAllTweens()
{
// Stops every tween managed by the system.
BTween.StopAndClearAllManagedTweens();
}
```
### Pause / Resume (example)
The runtime currently exposes stop/cancel operations. A simple and reliable way to implement pause/resume with the current API is to stop the tween when pausing and restart a new tween from the current value to the original target using the remaining duration when resuming.
This example shows a small helper that moves a Transform to a target position and can pause/resume the motion. It reads the current transform value when resuming so it behaves correctly even if the object was moved externally while paused.
```C#
using UnityEngine;
using Cysharp.Threading.Tasks;
public class PauseableMove : MonoBehaviour
{
public Transform targetTransform;
private Vector3 _endPosition;
private float _totalDuration;
private float _startTime;
private bool _isPaused;
private readonly string _tweenTag = "Move";
public void StartMove(Vector3 to, float duration)
{
_endPosition = to;
_totalDuration = Mathf.Max(0.0001f, duration);
_startTime = Time.time;
_isPaused = false;
// Start the tween (extension uses a pre-hashed id internally)
targetTransform.TweenLocalPosition(_endPosition, _totalDuration).Forget();
}
public void Pause()
{
if (_isPaused) return;
// Stop the running tween (cancels it)
BTween.StopTween(targetTransform, _tweenTag);
_isPaused = true;
}
public void Resume()
{
if (!_isPaused) return;
// Compute elapsed and remaining time using wall-clock Time.time
float elapsed = Time.time - _startTime;
float remaining = Mathf.Max(0f, _totalDuration - elapsed);
// Start a new tween from the current position to the original end position
// using the remaining duration. This reads the actual current transform so
// it works if the object was moved while paused.
Vector3 current = targetTransform.localPosition;
if (remaining <= 0f)
{
// if nothing remains, snap to final value
targetTransform.localPosition = _endPosition;
_isPaused = false;
return;
}
_startTime = Time.time; // reset start time for resumed tween
_isPaused = false;
BTween.Vector3(targetTransform, _tweenTag, v => targetTransform.localPosition = v, current, _endPosition, remaining).Forget();
}
}
```
Notes:
- This approach uses stop + restart. It is deterministic, doesn't require internal engine changes, and works with the existing public API.
- Drawbacks: true pausing (suspending elapsed time without canceling) would require additional engine support (store elapsed and skip updates). If you want, I can implement engine-level Pause/Resume and group APIs so Pause doesn't cancel and can be resumed exactly where it left off.
---
## Stopping a Tween
You can stop a running tween using BTween.StopTween(). For convenience, you can use a string, which will be hashed internally. For maximum performance, you can use the pre-hashed const values from the public TweenPropertyIDs class.
```C#
public void StopPanelFade()
{
// Convenience method (hashes the string "Alpha" internally):
BTween.StopTween(panelCanvasGroup, "Alpha");
// Most performant method (uses the pre-hashed const value):
BTween.StopTween(panelCanvasGroup, TweenPropertyIDs.Alpha);
}
public void StopAllTweens()
{
// Stops every tween managed by the system.
BTween.StopAndClearAllManagedTweens();
}
```
---
## Manual Optimization (Static API)
When using the static `BTween.Float()` API for custom tweens, you can provide a `uint` hash instead of a string to avoid runtime hashing. Use `BTween.StringHash(string)` once and cache the result in a `static readonly` field.
```C#
using UnityEngine;
using UnityEngine.UI;
public class HealthBarAnimator : MonoBehaviour
{
public Slider healthSlider;
// Cache the hash once to avoid calculating it repeatedly.
private static readonly uint healthSliderHash = BTween.StringHash("HealthSlider");
// Animate the slider value from its current value to a new target.
public void UpdateHealth(float newHealthValue)
{
BTween.Float(
owner: this,
tweenIdentifierHash: healthSliderHash, // Use the cached hash.
startValue: healthSlider.value,
endValue: newHealthValue,
duration: 0.4f,
setter: (value) => healthSlider.value = value,
easeFunction: BTween.Ease.OutQuad
);
}
}
```
---
## What's new in 0.4.0
- Pause / Resume API for individual tweens and groups.
- Groups & Sequences to compose and coordinate multiple tweens.
- CancellationToken support across public async APIs so you can tie lifetimes to UniTask workflows.
- Editor improvements: better inspector controls and a small manager editor for debugging running tweens.
- Performance: more aggressive hash caching and reduced per-frame allocations.
If any of the new APIs are missing or you want a different behavior, tell me which API you prefer and I can update docs or implement small examples.
## Upgrade notes
- Version bumped to `0.4.0`.
- Existing extension methods keep their signatures — most projects should upgrade without code changes. If you use the static APIs and passed string keys frequently, consider switching to cached `uint` hashes for best performance.
## Contributing
Contributions, bug reports and small PRs are welcome. Please:
- Open an issue describing the problem or feature.
- Provide a minimal repro when possible.
- Keep changes focused and add a short note to the changelog when submitting a PR.
## License
See the `LICENSE` file in the repository for license terms.
---