昨日、私はGDCカナダから、属性/行動エンティティシステムに関するプレゼンテーションを読みました。ただし、理論上だけでなく、実際に使用する方法もわかりません。まず、このシステムの仕組みを簡単に説明します。
各ゲームエンティティ(ゲームオブジェクト)は、属性(=データ、動作によってアクセスできるだけでなく、「外部コード」によってもアクセス可能)および動作(= OnUpdate()
およびを含むロジック)で構成されますOnMessage()
。したがって、たとえば、ブレイクアウトクローンでは、各ブリックは(例!)で構成されます:PositionAttribute、ColorAttribute、HealthAttribute、RenderableBehaviour、HitBehaviour。最後の例は次のようになります(C#で書かれた単なる機能しない例です)。
void OnMessage(Message m)
{
if (m is CollisionMessage) // CollisionMessage is inherited from Message
{
Entity otherEntity = m.CollidedWith; // Entity CollisionMessage.CollidedWith
if (otherEntity.Type = EntityType.Ball) // Collided with ball
{
int brickHealth = GetAttribute<int>(Attribute.Health); // owner's attribute
brickHealth -= otherEntity.GetAttribute<int>(Attribute.DamageImpact);
SetAttribute<int>(Attribute.Health, brickHealth); // owner's attribute
// If health is <= 0, "destroy" the brick
if (brickHealth <= 0)
SetAttribute<bool>(Attribute.Alive, false);
}
}
else if (m is AttributeChangedMessage) // Some attribute has been changed 'externally'
{
if (m.Attribute == Attribute.Health)
{
// If health is <= 0, "destroy" the brick
if (brickHealth <= 0)
SetAttribute<bool>(Attribute.Alive, false);
}
}
}
このシステムに興味がある場合は、こちら(.ppt)をご覧ください。
私の質問はこのシステムに関連していますが、一般的にはすべてのコンポーネントベースのエンティティシステムです。これらのどれも実際のコンピューターゲームで実際にどのように機能するかを見たことがありません。良い例が見つからず、見つかったとしても文書化されておらず、コメントもありませんので、理解できません。
だから、私は何を聞きたいですか?動作(コンポーネント)の設計方法。GameDev SEで、ここで読んだ最も一般的な間違いは、多くのコンポーネントを作成し、単純に「すべてをコンポーネントにする」ことです。私はそれがコンポーネントでレンダリングをしないことが示唆だと読んで、それ(その代わりに外でそれを行うましRenderableBehaviour、それは多分あるべきRenderableAttribute、およびエンティティがいる場合RenderableAttributeが trueに設定され、その後、Renderer
(クラスに関連していませんコンポーネントですが、エンジン自体に)画面上に描画する必要がありますか?)。
しかし、動作/コンポーネントはどうですか?のは、私がレベルを持っている、とのレベルでは、そこだと言ってみましょうEntity button
、Entity doors
とEntity player
。プレイヤーがボタンと衝突すると(圧力によって切り替えられるフロアボタンです)、ボタンが押されます。ボタンが押されると、ドアが開きます。さて、今それをどうやってするのですか?
私はこのようなものを思いつきました:プレイヤーはCollisionBehaviourを持っています。これはプレイヤーが何かと衝突するかどうかをチェックします。彼がボタンと衝突した場合、それCollisionMessage
はbutton
エンティティに送信されます。メッセージにはすべての必要な情報が含まれます:ボタンと衝突した人。ボタンにはToggleableBehaviourがあり、これを受け取りCollisionMessage
ます。誰が衝突したかをチェックし、そのエンティティの重みがボタンを切り替えるのに十分な大きさである場合、ボタンが切り替えられます。次に、ボタンのToggledAttributeをtrue に設定します。さてさて、しかし今は何ですか?
ボタンは、他のすべてのオブジェクトに別のメッセージを送信して、切り替えられたことを通知する必要がありますか?このようなことをすべてやると、何千ものメッセージが出て、かなり面倒になると思います。したがって、これはより良いかもしれません。ドアは、それらにリンクされているボタンが押されているかどうかを常にチェックし、それに応じてOpenedAttributeを変更します。しかし、それはドアのOnUpdate()
方法が絶えず何かをしていることを意味します(それは本当に問題ですか?)。
2番目の問題:ボタンの種類が増えた場合はどうなるか。1つは圧力で押され、2つ目はそれを撃つことで切り替えられ、3つ目は水がかけられると切り替えられます。
Behaviour -> ToggleableBehaviour -> ToggleOnPressureBehaviour
-> ToggleOnShotBehaviour
-> ToggleOnWaterBehaviour
これは実際のゲームの仕組みですか、それとも私はただのバカですか?たぶん、ToggleableBehaviourを1つだけ持つことができ、ButtonTypeAttributeに従って動作します。それがaの場合ButtonType.Pressure
、これを行い、aの場合ButtonType.Shot
、何か他のことをします...
だから私は何が欲しいのですか?私はそれを正しくやっているのか、それとも愚かでコンポーネントのポイントを理解していないのかを尋ねたいと思います。コンポーネントがゲームで実際にどのように機能するかの良い例は見つかりませんでした。コンポーネントシステムの作成方法を説明するチュートリアルをいくつか見つけましたが、使用方法は説明しませんでした。