Hi all -
I’m sure you’ve all seen this kind of effect in mobile games:
- User does something (kills a monster, collects a treasure, opens a chest box)
- User gets loot (coins, crystals, diamonds, etc)
- The image of the loot “flies” towards its corresponding UI label (e.g., the gold coin flies towards the UI element showing the user’s current coin balance)
- Upon reaching the label, the coin disappears
Usually, this movement is accomplished not in a straight line but along a Bezier curve, with easing and what not involved.
Now, I’ve been able to accomplish this using DOTween’s DoPath() method - but I’ve been told that it’s not and quite inefficient. Profiler data seems to agree - triggering such an animation “costs” 1.4kb of garbage right off the bat, plus an additional 0.5ms of processing per frame.
I will test this on my mobile later today to see if the performance impact of this is significant (assume that such flying animations are triggered by the user twice a second). I was, however, wondering if the above is as good as it gets or if there’s a better and more standard way that other mobile developers do this?
Your thoughts would be appreciated. For those so inclined, and in the spirit of sharing, here is the code (I suspect I might be recreating the Tween with each instance - might be worth investigating):
using UnityEngine;
using DG.Tweening;
public class MoveToCoin : MonoBehaviour
{
public float duration;
UI_InteractiveLabel target;
Vector3 deviationPosition;
Tween tween;
private void OnEnable()
{
if (target == null) { target = UI_Controller.Instance.topLabelCoin.GetComponent<UI_InteractiveLabel>(); }
deviationPosition = new Vector3(transform.position.x + Random.Range(-1, 1), transform.position.y + Random.Range(0.1f, 2f));
transform.DOPath(new Vector3[] { deviationPosition, UI_Controller.Instance.topLabelCoin.position }, duration, PathType.CatmullRom, PathMode.Ignore, 5, null)
.OnStart(() => { transform.DOPunchScale(new Vector3(0.75f, 0.75f, 0), duration, 0, 0); transform.DORotate(new Vector3(0, 0, 360), 1f, RotateMode.FastBeyond360); })
.OnComplete(() => { target.Bounce(); gameObject.SetActive(false); })
.SetEase(Ease.InOutCirc)
.SetAutoKill(false);
}
private void OnDisable()
{
transform.rotation = new Quaternion(0, 0, 0, 0);
transform.localScale = new Vector3(0.5f, 0.5f, 1);
}
}