本文基于Delta3d 2.8 版本
1, OnEnteredWorld()函数,在Actors和proxy均有此函数。在actor在第一次加入到GameManager中时调用。In Proxy's OnEnteredWorld,This is a good place to register Invokables with MessageTypes.
在GameManager 的函数中AddActor(GameActorProxy& gameActorProxy, bool isRemote, bool publish)调用Proxy 的 InvokeEnteredWorld()函数
此函数在GameActorProxy::InvokeEnteredWorld()中调用,如下
void GameActorProxy::InvokeEnteredWorld() { /** * We will perform a check to make sure this actor actually is a GameActor */ GameActor* ga = dynamic_cast<GameActor*>(GetDrawable()); if (ga == NULL) { // throw exception throw dtGame::GeneralGameManagerException( "ERROR: Actor has the type of a GameActor, but casting it to a GameActorProxy failed.", __FILE__, __LINE__); } ga->OnEnteredWorld(); CallOnEnteredWorldForActorComponents(); OnEnteredWorld(); }
2. CreateDrawable() 函数(2.75版本这个函数叫 叫crateActor),这个是ProxyActor 必须要实现的,用来创建proxy对应的actor,然后调用SetDrawable();
如下面代码片段
* @code * void MyProxy::CreateDrawable() * { * MyDrawable* draw = new MyDrawable(); * assert(draw); * SetDrawable(*Drawable); * } * @endcode
void BaseActorObject::Init(const dtCore::ActorType& actorType) { SetActorType(actorType); CreateDrawable(); // These are called to make it validate that they aren't Null // before proceeding. GetActorType(); GetDrawable(); BuildPropertyMap(); }
创建可调用体,在创建自定义“可调用体时”,要使用继承的可调用体,确保也要调用继承类的BuildInvokables(); 注意:不要忘记注册你的“可调用体”感兴趣的消息类型,一般在OnEnteredWorld()函数中调用RegisterForMessages()进行注册。否则,你的“可调用体”函数,如ProcessMessage,将得不到执行);
此函数的调用位置如下:
void GameActorProxy::Init(const dtCore::ActorType& actorType) { BaseClass::Init(actorType); BuildInvokables(); BuildActorComponents(); // The actor components are stored on the game actor, unlike the other stuff GameActor &ga = GetGameActor(); ga.BuildActorComponents(); }
dtCore::RefPtr<BaseActorObject> ActorPluginRegistry::CreateActor(const ActorType& type) { dtCore::RefPtr<BaseActorObject> proxy = mActorFactory->CreateObject(dtCore::RefPtr<const ActorType>(&type)); proxy->Init(type); proxy->InitDefaults(); return proxy; }
4. void GameActorProxy::BuildPropertyMap() 函数。
创建此proxy所关联的属性信息,注册到子类PropertyContianer中。在 BaseActorObject::Init(const dtCore::ActorType& actorType)中创建,见上面分析。
5. virtual void BuildActorComponents(); 函数
actor 和proxy均有此方法。同样在 void GameActorProxy::Init(const dtCore::ActorType& actorType)中创建的,见上分析。
void GameActor::AddComponent(ActorComponent& component) { ActorComponentBase::AddComponent(component); // add actor component properties to the game actor itself // note - the only reason we do this is to make other parts of the system work (like STAGE). // In the future, STAGE (et al) should use the actor components directly and we won't add them to the game actor // Remove the props from the game actor - This is temporary. See the note in AddComponent() GetGameActorProxy().AddActorComponentProperties(component); // initialize component component.OnAddedToActor(*this); OnActorComponentAdded(component); // if base class is a game actor and the game actor is already instantiated in game: if (GetGameActorProxy().IsInGM()) { component.SetIsInGM(true); component.OnEnteredWorld(); } }