Unity 中的浮动文本

Floating texts in Unity

我的 2D 平台游戏关卡在整个地图上都放置了宝箱,当收集宝箱时我需要显示一条消息。消息包含在 List<string> 中,并在收集宝物时一一显示。 这些消息将显示在锚定在 canvas 顶部中心的 UI>Text 游戏对象中。我想通过更新此游戏对象的文本组件,在收集宝藏时将这些文本显示为向上浮动(淡化 in/out)。然而,当在前一个的动画完成之前收集了两个或更多的宝物时,问题就出现了。我可以轻松地将新消息连接到现有消息,但我希望旧消息淡出,新消息淡入。这可以通过创建多个 UI>Texts 来完成,但是有很多消息而且我不想创建那么多多余的游戏对象。这个问题有什么好的解决方法吗?

如果您使用享元模式(对象池),您将不会生成超过系统处理能力的对象。 Unity 在他们的网站上有一个 Object Pooling tutorial

我在我的一个项目中处理这个问题的方法是创建一个要显示的消息队列(因为即时性不是问题,但一次只能显示一个是问题)。这听起来与您自己的问题非常相似。

// NotificationItem is just a wrapper around some text and accompanying image
private static List<NotificationItem> notificationQueue = new List<NotificationItem>();

// reference to the on-screen object
public GameObject notification;

// "Hey! I want to display a notification!"
public static void ShowNotification(NotificationItem item) {
    notificationQueue.Add(item);
}

// I was using the DO Tween asset here, but the logic can be converted to
// coroutines or straight update cycles
private void Update() {
    // If there is no currently displayed notification (ie the notification object is
    // not being animated) and there is at least one item to display
    if(!DOTween.IsTweening(notification.transform) && notificationQueue.Count > 0) {
        // ...get the first one
        NotificationItem item = notificationQueue[0];
        // ...pop it from the list
        notificationQueue.RemoveAt(0);
        // ...set the notification object to the details
        notification.transform.Find("Title").GetComponent<Text>().text = item.title;
        notification.transform.Find("Text").GetComponent<Text>().text = item.text;
        notification.transform.Find("Img").GetComponent<Image>().sprite = item.image;

        // ...start the animation
        // (in my case, the notification animates down from the top of the screen
        // waits 2.5 seconds, then animates back up)
        notification.transform.DOMoveY(Screen.height - 85, 0.5f, false).SetEase(Ease.InOutQuad).OnComplete(PauseCallback);
    }
}

// An admittedly hacky way of getting the notification to do nothing for 2.5 seconds:
// Animate it to where it already is.
private void PauseCallback() {
    notification.transform.DOMoveY(Screen.height - 85, 2.5f, false).SetEase(Ease.InOutQuad).OnComplete(ReturnCallback);
}

private void ReturnCallback() {
    notification.transform.DOMoveY(Screen.height + 2, 0.5f, false).SetEase(Ease.InOutQuad);
}

我的实现与您的实现之间的区别主要在于动画(以及您的队列列表的类型;例如,您可以只使用 List<string>)。您已经对动画进行了编码,您所需要的只是队列和一种确定动画已完成的方法。