嗯,我知道这已经被问到了,我也碰巧知道最简单的方法。
现在我的问题更多的是关于你是否有更好的方法的建议。
我希望在启用或创建组件时只调用一次我的方法。 请参阅我可以创建一个组件但是禁用它,然后当我第一次启用它时,我希望调用Init方法。该组件包含在“附加”对象中。
所以我有
的组件internal bool _runOnce;
然后我有了MainObject
List<Component> _listComp = new List<Component>();
void Update(){
foreach(Component c in _listComp){
if(!c.enable)continue;
if(c._runOnce){
c.Init();
c._runOnce = false;
}
c.Update();
}
}
我主要担心的是,每个对象的每个组件都会检查_runOnce。我知道这只是一个布尔检查而且没有任何价值,但我只是想问是否有人会知道这个目的的模式比这更好。
由于
答案 0 :(得分:2)
您还可以仅列出已启用的组件....
List<Component> _listEnabled = _listComp.Where(item => (item.enable == true));
foreach(Component c in _listEnabled ){
if(c._runOnce){
c.Init(); // if at all possible, _runOnce should be set to false
c._runOnce = false; // IN THE OBJECT, after calling Init();
}
c.Update();
}
答案 1 :(得分:1)
我会质疑Update()
是否是Init()
动态组件的合适生命周期设计。
似乎有一个名义上称为GameObject.ActivateComponent(AbstractComponent C)
调用C.Init()
和AbstractComponent::Init
调用OnInit
的方法更有意义,这是组件覆盖和实现的内容。 AbstractComponent::Init
将进行_runonce检查并提前返回。这是一个方法调用,但它使代码更抽象,并且可以选择扩展为稍后有OnReinitialize
代码路径,如果你需要为'这是第二次或以后我是init'提供钩子d”。 (比方说,统计重置选项...)
Update()
探测像“runonce”这样的实现细节以了解Component
的初始化状态肯定是错误的。
List<Component> _listComp = new List<Component>();
void Update(){
foreach(Component c in _listComp){
c.Update();
}
}
AbstractComponent
public bool Enable { get;set;}
private bool _initialized = false;
void Update(){
if (!Enable) return;
Init();
OnUpdate();
}
protected virtual void OnUpdate()
{
// filled in by user script
}
private void Init()
{
if (_initialized) return;
OnInit();
_initialized = true;
}
protected virtual void OnInit()
{
// filled in by user script
}
答案 2 :(得分:1)
My main concern is that the check for _runOnce will happen every frame for every component on each object.
由此我假设您经常致电Update
。我担心的是组件的Update
方法,它很可能比布尔检查贵得多。这称为微优化:你付出了很多努力,而不是一个根本不存在问题的东西。
但是,我建议封装初始化。您的MainObject
无需知道任何相关信息。 _runOnce
应该是组件的私有成员,enable
应该是属性(btw:_runOnce
应该在某处初始化为true)。每次启用组件时,您都可以检查_runOnce
并在需要时调用初始化:
public class MyComponent
{
private bool _isInitialized; // I think this is a better name than _runOnce
private bool _enable;
public bool Enable
{
get
{
return _enable;
}
set
{
if (_enable == value)
{
return;
}
if (value == true && !_isInitialized)
{
Init();
}
_enable = value;
}
}
private void Init()
{
// initialization logic here ...
_isInitialized = true;
}
}
另一个想法是将初始化推迟到Update
方法。这基本上是你已经拥有的,但在面向对象的设计中:
public void Update()
{
if (_enable && !_isInitialized)
{
Init();
}
// update logic here ...
}
答案 3 :(得分:0)
如果只是Component的常规构造函数?
public Component()
{
Init();
}