游戏演员的脚本

时间:2012-09-03 23:53:36

标签: c++ scripting lua game-engine actor

我想为我的模特/演员添加一些脚本。当加载新模型或更改脚本时,actor会做出反应。

现在,我有一个基础Lua类,例如,它有一个Update()函数,每个模型/ actor都应该重载这个函数。但是如何实现呢?主要问题是每个模型都需要一个唯一的类名,......

  1. 我在考虑一个表,其键值是actorID(唯一),值是从基类继承的类,但是当脚本重新加载时有点困难。

    Objects[ActorID] = Model(paramater)

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

  2. 也许也可以为每个演员创建一个新的lua状态。

  3. 我从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
    

    可以工作;)

1 个答案:

答案 0 :(得分:2)

youtube视频中的引擎工作方式不依赖于重载的Update功能。他们拥有基类的原因是为其对象提供默认行为和通用接口,但与实际更新任何内容无关。

他们使用操作系统提供的功能来监听文件更新(有关详细信息,请参阅this SO question),然后只需在游戏的lua_State中执行脚本。由于脚本只修改了类型定义(表和元表),当你重新加载脚本时(通过简单的luaL_dofile或我认为的等价物),新的定义会覆盖旧的定义,并且lua愉快地使用更新的行为。如果您真的斜视并查看视频在编辑器中显示的代码,您会发现它们只是定义函数,而不是运行Update方法。

作为最后一点 - 如果你为每个actor创建新的lua_States,那么你将无法在Lua中自由传递它们之间的东西,并且必须编写C ++代码以手动在两个(或更多)之间传递数据lua_States。

编辑:关于从公共基础对象继承:修改其元表将改变所有对象的行为,因此我们需要防止这种情况。一种方法是用防护包围实体脚本以防止修改实际的公共元表。在加载脚本之前,我们保存对基本元表的引用,并将其替换为脚本可以使用的副本。

通过这种方式,脚本不需要创建自己的元表,也不需要知道引擎的其余部分将如何引用它。相反,它只使用实体一个。一旦脚本完成定义它的派生行为,我们就可以为其Entity副本提供一个新名称(一个基于脚本文件的名称,一个世界对象的名称等),并将Entity恢复为原始引用。 / p>

除此之外,我们还获得了不通过不同更新持续更改的额外好处。每次我们想要在运行时更改脚本时,我们都会重复该过程,并且可以确信如果在先前的更新中添加了某些内容,则在执行删除它的更新后它将不会保留。如果我们只是让脚本覆盖元数据,那么我们就无法删除函数和成员而不将其明确设置为nil