邪修优化2:还在滥用Update来获取其他脚本变量?邪修助你在实时和性能之间取得平衡
其实十分的简单这个问题——既然我们的需求是尽可能实时的获得其他脚本的变量信息,比如著名的UdonChips钱包系统,如果我们需要为其打造一款全新的插件,我们需要去持续的更新钱包的钱数以保证其他的模块能正常运行。对此UdonChips的官方解决方案是——通过在Update方法下每一帧检查钱包脚本的指定参数与本地的备份是否有区别。
在为了优化性能表现,我将其进行了一点点改造,并且将其他模块的Update事件更改为了一个静态事件,解决了这个问题:
解决方案:
子脚本在初始化阶段向主脚本注册,主脚本在监听到指定变量更改之后,向所有的已经注册的脚本发送事件。这样其他的子脚本只要按照要求设置指定事件即可接收到变量更改的信号。
以下为代码示例
主脚本(数据本体):
//注册
public void RegisterOnMoneyChanged(GameObject target)
{
// 检查目标是否为UdonBehaviour
UdonBehaviour udonBehaviour = target.GetComponent<UdonBehaviour>();
if (udonBehaviour == null)
{
Debug.LogError("目标 GameObject 没有 UdonBehaviour 组件");
return;
}
if (Target == null)
{
Target = new UdonBehaviour[0];
}
UdonBehaviour[] newTarget = new UdonBehaviour[Target.Length + 1];
for (int i = 0; i < Target.Length; i++)
{
newTarget[i] = Target[i];
}
newTarget[Target.Length] = udonBehaviour;
Target = newTarget;
//注册Debug
if (NewCodeDebugMode)
{ Debug.Log("注册成功:" + target.name); }
}
//添加-减少参数
public void ChangeMoneyAndUpdate(float Value)
{
money += Value;
ManualSave(NotifyMoneyChanged();
}
//发送事件
private void NotifyMoneyChanged()
{
if (NewCodeDebugMode)
{ Debug.Log("金额发生更改"); }
for (int i = 0; i < Target.Length; i++)
{
Target[i].SendCustomEvent("UdonChipsMoneyChanged");
}
}
子脚本(数据需求方)
public void start()
{
//获取UdonChips组件
udonChips = GameObject.Find("UdonChips").GetComponent<UdonChips>();
//注册为需要更新的组件
udonChips.RegisterOnMoneyChanged(this.gameObject);
}
public void UdonChipsMoneyChanged()
{
currentMoney = udonChips.money;
}