unity3d 在UI中显示初始值的Unity最佳实践

cclgggtu  于 2023-01-09  发布在  其他
关注(0)|答案(2)|浏览(164)

我最近遇到了一个情况,我有一个球员对象来存储生命值和法力值,我的UI订阅这些值的变化。
例如:
播放器类

int maxHP;

void Start()
{
    maxHP = 100;
}

现在,我有了一些逻辑,每当maxHP值发生变化时就会触发一个事件,并调用UI中的一个函数
UI类

private void UpdatePlayerHP(int currentHP, int maxHP)
    {
        playerHPText.GetComponent<TextMeshProUGUI>().text = maxHP.ToString()
    }

然而,播放器对象在场景之间是持久的,并且在加载带有UI的场景时已经存在,因此值更改事件不会传输到UI。我认为这可能是一个常见问题,我可能会在项目期间遇到这个问题,因为有很多场景更改...
如果有人能为此推荐一个变通方案(除了将maxHP公开并直接从UI访问它)或给出任何最佳实践建议,我将非常感激:)

chhkpiq4

chhkpiq41#

Unity有一个活动叫做:

SceneManager.sceneLoaded

但是,我不推荐使用这个方法,因为它完全忽略了对象是否启用等问题。
你有没有考虑过让UI持久化?这将解决你的问题,以及当你想要一个记分器,计时器或其他东西时可能遇到的类似问题。
其他每种方法都涉及为UI提供对播放器的引用,这通常是您希望避免的。

o75abkj4

o75abkj42#

作为对此问题的一般回答:在连接侦听器时,您必须手动调用回调一次。
例如,假设您有一个事件和值,如

private int health = 100;
// Readonly access
public int Health => health;
public event Action<int> HealthChanged;

那你就会

theClass.HealthChanged += OnHealthChanged;
OnHealthChanged(theClass.Health);

当然,这有点不可思议--你必须记住立即调用它,至少将值public公开为只读等等。
=〉你可以把它抽象成一种可观察的模式

public class Observable<T>
{
    private T value;
    public T Value => value;
    private event Action<T> valueChanged;

    public Observable(T initialValue)
    {
        value = initialValue;
    }

    public void Subscribe(Action<T> callback)
    {
        // subscribe and call once immediately 
        valueChanged += callback;
        callback?.Invoke(value);
    }

    public void Set(T newValue)
    {
        value = newValue;
        valueChanged?. Invoke (newValue);
    }
}

然后基本上有一个

public Observable<int> Health;

并且订户可以简单地

theClass.Health.Subscribe(OnHealthChanged);

其将包括对所传递的回调的一个立即调用。
但是在深入研究之前,我强烈推荐使用UniRX
他们的BehaviourSubject基本上做了一些非常相似的事情,但比我更好,更先进,该软件包提供了一些查询,如过滤器,先进的React式用例,如结合多个可观察性等。
你会做

private readonly BehaviorSubject<int> health = new (100);
public IObservable<int> Health => health;

无论何时你设置它呼叫

health.OnNext(newHealth);

而订阅者会

theClass.Health.Subscribe(OnHealthChanged);

现在,无论何时更改健康状况,都会调用OnHealthChanged,但也会在您进行订阅时调用一次。
此外,Subscribe返回一个IDisposable,您可以简单地Dispose =〉不再订阅。这甚至适用于lambda表达式

相关问题