我的2D平台游戏级别在地图上都放置了百宝箱,当收集到宝箱时,我需要显示一条消息。邮件包含在List<string>
中,并在收集宝藏时一一显示。
这些消息将显示在UI> Text gameObject中,该对象固定在画布的顶部中心。我想通过更新此gameObject的文本组件,将这些文本显示为在收集宝藏时向上浮动(淡入/淡出)。但是,当在完成前一个动画的动画之前收集了两个或更多个宝藏时,就会出现问题。我可以轻松地将新消息连接到现有消息,但是我希望旧消息淡出而新消息淡入。这可以通过创建多个UI> Texts来完成,但是有很多消息,但我不这样做想创建这么多多余的游戏对象。有没有解决此问题的好方法?
答案 0 :(得分:2)
在我的一个项目中,我处理此问题的方式是创建要显示的消息队列(因为即时性不是问题,但一次只能显示一个)。这听起来很像您自己的问题。
// 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>
)。您已经对动画进行了编码,您所需要的只是队列以及确定动画是否完整的方法。
答案 1 :(得分:1)
如果您使用Flyweight模式(对象池),则生成的对象不会超出系统的处理能力。 Unity在其网站上有一个Object Pooling tutorial。