我知道如果在运行时经常使用它,最好缓存一个组件。如果我将组件缓存为静态变量并在运行时访问它怎么样?让我举个例子:
public class AudioManager : MonoBehaviour
{
public static AudioManager audioManager;
void Awake()
{
audioManager = this;
}
}
然后,如果我从另一个类访问它,我应该使用AudioManager.audioManager
还是事先缓存它(在性能方面说话)?
P.S。如果有什么不清楚,请告诉我。
编辑:我想我不知道我对Singletons到底在做什么,但为了说清楚,这是一个关于性能的新手问题:
在Awake中 1)_audioManager = AudioManager.audioManager
,然后在更新
_audioManager.someVariable
VS
2)更新
中的AudioManager.audioManager.someVariable
答案 0 :(得分:2)
您无需在任何情况下缓存自己的组件速度。访问本身时,组件不会支付性能损失。
您可能正在考虑的用例是缓存对其他组件或对象的访问,这样您就不必使用GetComponent或GetComponentWithChildren进行查找。这确实节省了时间,但这不是一个复杂的模式:只是在第一次遇到其他组件或游戏对象时进行查找,将其存储在此组件内的字段中,并且您很好:
class Example: MonoBehavior
{
public GameObject _TargetCharacter;
private Transform _cachedTransform;
private Animator _cachedAnimator;
void Awake()
{
if (_TargetCharacter != null)
{
_cachedTransform = _TargetCharacter.transform;
_cachedAnimator = _TargetCharacter.GetComponent<Animator>();
}
}
void Update()
{
DoSomething (_cachedTransform, _cachedAnimator);
}
}
GetComponent和GetComponentInChildren相对昂贵,你不想每帧都这样做。但是,直接访问设置为字段的内容并不昂贵,因此无需对其进行缓存。
使它成为Singleton:在这个上下文中,你需要创建一个不是Component的单独的类,并且让它成为单例 - 你不能阻止某人将许多给定的MonoBehavior附加到Unity编辑器,因此您不希望假设只有一个组件浮动。在AudioManager示例中,您必须假设许多不同的组件可能都在查看同一个AudioManager。
这是一个很好的例子comparing shared behavior using Singletons vs shared behavior in a static class。两种方式达到同一目的,优势和劣势略有不同。
更新响应OP的评论如下:
如果原始代码的要点是使用常见的Unity缓存技巧来提高速度,则不需要它。如果OP在下面的评论中建议将经理变成其他类可以调用的“服务提供者”,那么有两条路可走:
标准的统一技巧是将缓存行为添加到需要访问AudioManager的其他类中。例如:
class SomeOtherComponent: MonoBehavior
{
AudioManager _manager;
void Awake()
{
AudioManager[] AllAudioManagers = GetComponents<AudioManager>();
if (AllAudioManagers.Count == 1)
{
_manager = AllAudioManagers[0];
}
else
{
throw new RuntimeError ("Expecting one (and only one) AudioManager in scene");
}
}
}
或多或少地切换到正确的Singleton实现只需要在上面的Awake
方法中获取样板并集中到单例类中,允许您替换它。
对于单一模式的扩展讨论,请尝试this book
答案 1 :(得分:0)
我遵循一个简单的规则,如果我要多次调用一个组件,超过5个,那么我将其缓存。同样的规则我适用于单身人士。如果只有一个电话,那么我只使用Singleton.getInstance()
。
Unity组件,例如Transform。
缓存Transform
之类的东西的逻辑来自于查看文档。变换不是变量,而是属性,恰好包含getter和setter。这些对你来说是隐藏的,但这就是它的实现方式。该属性恰好用C或C ++编写。因此,这会降低您的性能。