【问题标题】:Floating texts in UnityUnity 中的浮动文本
【发布时间】:2019-01-04 23:05:28
【问题描述】:

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

【问题讨论】:

  • 我不知道您是否尝试过,但是您是否尝试过将游戏对象存储在某种缓冲区中并根据需要获取它们?如果没有更多可用的,则实例化一个新的并存储在缓冲区中。所以当你需要的时候,你从那里挑选,当你完成后,放回去

标签: c# unity3d floating cross-fade


【解决方案1】:

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

// 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&lt;string&gt;)。您已经对动画进行了编码,您所需要的只是队列和确定动画是否完成的方法。

【讨论】:

  • 您使用的是资产商店中的资产吗? assetstore.unity.com/packages/tools/animation/…
  • 是的。就是那个。但就像我说的,你想处理动画的任何方式都可以,只要你有办法检测到动画当前正在运行。
  • 好的,我会试试这个资产。我还没有制作动画,还在思考该怎么做。
  • DOTween 是否与 TMPro 一起使用?虽然gameObject.GetComponent&lt;Text&gt;().DOText() 似乎有效,但我正在使用大量带有子脚本等的富文本,并且希望使用gameObject.GetComponent&lt;TextMeshProUGUI&gt;().DOText()。你用的是专业版的dotween吗?
  • 我有免费版,我自己还没有查看DOText()
【解决方案2】:

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

【讨论】:

  • 让我试试这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多