2

モデル/アクターにスクリプトを追加したいと思います。新しいモデルがロードされるか、スクリプトが変更されると、アクターが反応します。

今のところ、たとえばUpdate()関数を持つ基本Luaクラスがあり、各モデル/アクターはこの関数をオーバーロードする必要があります。しかし、それをどのように実装するのですか?主な問題は、各モデルにクラスの一意の名前が必要なことです...

  1. キー値がactorID(unique)で、値がベースクラスから継承されたクラスになるテーブルを考えていましたが、スクリプトがリロードされると少し難しくなります。

    Objects[ActorID] = Model(paramater)

    Objects[ActorID].Update = function() print("Update: actor 1") end

  2. たぶん、アクターごとに新しいlua状態を作成することも可能です。

Leadwerksエンジンからインスピレーションを得ました:http ://www.youtube.com/watch?v = z-EuS1EYk8o

ゲームエンジンでのスクリプト作成に適した本を知っている人がいたら教えてください

私はそれを手に入れたと思います:

ここにいくつかの擬似コードがあります:

OnNewActorCreated:

//Add actor
Objects[param.ID] = createClass(baseclass)

//Check if this actor has a script to run.
if param.hasScript then

   //Add the new ID to the script
   Scripts[param.filename][param.ID]

   Entity = Objects[param.ID]

   doFile(param.filename)

   Entity = nil

end

OnFileChanged:

foreach id in Scripts[changedfile] do

    Entity = Objects[id]

    dofile(changedfile)

    Entity = nil

end

スクリプト例:

//check if Entity is valid
if not Entity then
   print("[Error] Entity is invalid")
else   
    function Entity:Update() 
        print(self.name)
     end
end

動作する可能性があります;)

4

1 に答える 1

2

YouTubeビデオのエンジンの動作は、オーバーロードされた更新機能に依存していません。基本クラスがある理由は、デフォルトの動作とオブジェクトへの共通のインターフェイスを提供するためですが、実際に何かを更新することとは関係ありません。

彼らはOSが提供する機能を使用してファイルの更新をリッスンし(詳細についてはこのSOの質問を参照)、ゲームのlua_Stateでスクリプトを実行するだけです。スクリプトはタイプ定義(テーブルとメタテーブル)のみを変更するため、スクリプトをリロードすると(単純なluaL_dofileまたは同等のものを介して)、新しい定義が古い定義を上書きし、luaは更新された動作を使用して楽しくチャグします。ビデオがエディターに表示するコードを実際に細かく見てみると、Updateメソッドを実行するのではなく、関数を定義しているだけであることがわかります。

最後に、アクターごとに新しいlua_Statesを作成すると、Luaでアクター間で自由に物事を渡すことができなくなり、2つ(またはそれ以上)のlua_States間でデータを手動で渡すためのC++コードを作成する必要があります。

編集:共通ベースオブジェクトからの継承に関して:そのメタテーブルを変更すると、すべてのオブジェクトの動作が変更されるため、それから保護する必要があります。1つの方法は、実際の共通メタテーブルを変更しないように、エンティティスクリプトをガードで囲むことです。スクリプトをロードする前に、ベースメタテーブルへの参照を保存し、スクリプトで使用できるコピーに置き換えます。

このように、スクリプトは独自のメタテーブルを作成する必要はなく、エンジンの残りの部分がそれをどのように参照するかを知る必要もありません。代わりに、エンティティ1を使用します。スクリプトが派生動作の定義を完了したら、エンティティのコピーに新しい名前(スクリプトファイルの名前、ワールドオブジェクトの名前などに基づく名前)を付けて、エンティティを元の参照に復元できます。

上記とは別に、さまざまな更新によって変更を永続化しないという追加の利点があります。実行時にスクリプトを変更するたびに、このプロセスを繰り返し、以前の更新で何かが追加された場合、それを削除する更新を実行した後もスクリプトが残っていないことを確信できます。スクリプトにメタテーブルを上書きさせるだけでは、関数とメンバーを明示的にに設定せずに削除することはできませんnil

于 2012-09-04T10:51:25.243 に答える