This page has been translated automatically.
编程
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
应用程序接口
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
CIGI Client Plugin
Rendering-Related Classes
注意! 这个版本的文档是过时的,因为它描述了一个较老的SDK版本!请切换到最新SDK版本的文档。
注意! 这个版本的文档描述了一个不再受支持的旧SDK版本!请升级到最新的SDK版本。

Editor(编辑器)插件

警告
Game Framework is deprecated and no longer supported. We can't guarantee the stable work of the framework.

Game Framework Editor(游戏框架编辑器)能使您在Unigine Editor中正确创建游戏。

Game Framework Editor中有3个主要区域:

Game Framework Editor
  • New Game(新建游戏) - 创建新游戏
  • Open Game(打开游戏) - 打开游戏
  • Save Game(保存游戏) - 保存当前游戏
  • Play Level(播放关卡) - 播放关卡
  • Settings(设置) - 打开设置窗口

关卡(Levels)

其代表的是罗列的关卡以及对这些关卡所进行的操作:

  • New Level(新建关卡) - 创建新关卡
  • Remove Level(移除关卡) - 删除所选关卡

实体(Entities)

其代表的是罗列的实体以及对这些实体所进行的操作:

  • New Entity(新建实体) - 创建新实体
  • Remove Entity(移除实体) - 删除所选实体
  • Assign Entity(分配实体) - 将实体分配给节点引用或节点

Info

其作用是显示所选元素的信息。

创建游戏(Game)

要想创建新游戏,须点击New Game(新建游戏)按钮。 这时,游戏创建的对话框窗口将被打开:

游戏创建的对话框窗口
  • Name(名称) - 指游戏的名称。 它可以包含任意字符或者干脆为空。 其默认值为new_game
  • File(文件) - 指*.game文件的路径名称(相对于data目录的路径),该文件包含了有关游戏(game),关卡(levels),实体(entities)的所有信息,也包含了游戏和Editor的所有附加参数。 其默认值为games/new_game/new_game.game
  • Entity(实体) - 指*.prop文件的路径名称(相对于data目录的路径),该文件包含了有关基本实体(Entity)的所有信息。 它会由Editor自动生成。 其默认值为games/new_game/entity.prop
  • Property List(属性列表) - 指*.prop_list文件的路径名称(相对于data目录的路径),该文件罗列出了所有的游戏属性。 它会由Editor自动生成。 其默认值为games/new_game/properties.prop_list
注意
如果游戏的名称发生了更改,那其它的所有目录也都会被自动更改。 如果有任何一个目录是被手动更改的,那该值将不能在游戏创建期间被自动更改。

如果您将选项栏中的某一个给填错了,那警告图标就会出现。 当您将鼠标悬停在该图标上时,就会显示警告信息。

如果所有的选项栏都填写正确,在点击完Create(创建)按钮之后,游戏和所有的附加文件就会被创建。 而游戏也将被Editor瞬间打开。 所有这些设置在以后都可以更改。

编辑游戏(Game)

通过点击Open(打开)按钮打开要进行编辑的游戏。 在标题栏上可以看到*.game文件的目录。 Game的设置可以在Editor的Settings窗口(Game framework settings/Game settings/Game)中更改:

Game设置
  • Name(名称) - 指游戏的名称(可选项)
  • Developer(开发者) - 指游戏的开发者(可选项)
  • Version(版本) - 指游戏的版本(可选项)
  • Copyright(版权) - 指版权(可选项)
  • Window Title(窗口标题) - 指游戏被加载时窗口的标题(默认留空)
  • Description(描述) - 指游戏的描述(可选项)
  • Entity Property(实体属性) - 指*.prop文件的路径名称(相对于data目录的路径),该文件包含了有关基本实体(Entity)的所有信息。 它会由Editor自动生成。 其默认值为games/new_game/entity.prop

    如果您更改了该文件的名称或目录,那它就会被重命名以及被自动重新定位,不过它具有默认值。

  • Property List(属性列表) - 一个*.prop_list文件。 指属性列表的路径名称(相对于data目录的路径),该文件罗列出了所有的游戏属性。 它会由Editor自动生成。 其默认值为games/new_game/properties.prop_list

    如果您更改了该文件的名称或目录,那它就会被重命名以及被自动重新定位,不过它具有默认值。

您可从Game launch选项栏更改游戏加载的相关设置(Settings/Game/Game Launch):

  • System script(系统脚本) - 指system(系统)脚本的路径名称,该型脚本是启动游戏所必需的。 引擎为框架提供了默认的system(系统)脚本,它存放在路径下文件data/framework/game/game_system_script.cpp中。
  • Extern Define(外部定义) - 指外部定义的列表(例如,如果您是用作移动平台开发的,就要使用RENDER_SIMPLE来定义)
  • Extern Plugin(外部插件) - 指用户C++插件的列表

所有的游戏更改都应通过点击Save Game(保存游戏)按钮来保存。

创建关卡(Level)

要想创建新关卡,须点击New Level(新建关卡)按钮。 这时,关卡创建的对话框窗口将被打开:

关卡创建的对话框窗口

General(一般)

  • Name - 指关卡的名称。
  • %name - 指相对的关卡名称,其会被自动设置为*.level文件,*.world文件和*.h文件的名称。
  • Level File - 指*.level文件的路径名称(相对于data目录的路径),该文件包含了有关关卡的所有信息。

World(世界)

  • File - 指新关卡的*.world文件的路径名称(相对于data目录的路径)。 如果*.world文件之前还未被创建,那它就将通过路径下文件data/framework/plugin/editor/templates/level/template.world中存放的模型来进行自动创建。

Logic(逻辑)

  • Use Custom Logic - 指要使用自定义逻辑。 如果禁用了该参数,就会使用标准的框架关卡逻辑;否则,用来指定自定义逻辑的附加选项栏Logic ClassLogic File将被激活。
  • Logic Class - 指类的名称,在关卡加载时该类的实例将被创建。
  • Logic File - 指*.h文件的路径名称(相对于data目录的路径),该文件包含了关卡逻辑。

    如果具有指定名称的该文件不存在,那它就将基于标准模型(存放在路径下文件data/framework/plugin/editor/templates/level/logic.h中)来进行自动创建,该模型是从基本的关卡逻辑类Level继承而来。

注意
同一关卡逻辑类可用于不同的关卡。

如果您想要更改关卡创建的自动填写参数,须打开Editor的Settings窗口(Game framework settings/Game settings/File Path Settings For New Levels):

File Path Settings For New Levels Field(新关卡选项栏的文件路径设置)

引擎会为如下文件自动设置指定目录:

  • Level (*.level) - 指*.level文件的路径名称
  • Logic (*.h) - 指带有关卡逻辑的*.h文件的路径名称
  • World (*.world) - 指*.world文件的路径名称
注意
所有的路径都应相对于*.game文件来指定。

如果您将选项栏中的某一个给填错了,那警告图标就会出现。 当您将鼠标悬停在该图标上时,就会显示警告信息。

如果所有的选项栏都填写正确,在点击完Create(创建)按钮之后,关卡文件和所有的附加文件就会被创建。 而关卡也将Editor打开。 所有这些设置在以后都可以更改。

编辑关卡(Level)

当关卡被选中之后,就可以在Level(关卡)标签页内对它进行编辑:

关卡编辑的标签页
  • Name - 指关卡的名称
  • World - 指新关卡的*.world文件的路径名称(相对于data目录的路径)。
  • Logic - 指*.h文件的路径名称(相对于data目录的路径),该文件包含了关卡逻辑。 如果具有指定名称的该文件不存在,那它就将基于标准模型(存放在路径下文件data/framework/plugin/editor/templates/level/logic.h中)来进行自动创建,该模型是从基本的关卡逻辑类Level继承而来。
  • Logic class - 指类的名称,在关卡加载时该类的实例将被创建。
注意
如果您不想使用自定义逻辑,只需删除Logic选项栏和Logic class选项栏中所有的值即可。

>所有的游戏更改都应通过点击Save Game(保存游戏)按钮来保存。

要想加载或重新加载某个虚拟世界,只需双击关卡列表中的关卡即可,这样,Editor就会生成并重新加载所有的属性,也会为您的关卡加载所需的虚拟世界,如此一来您就能对它进行编辑,参数更改,添加,删除或编辑节点的操作了。 已加载的关卡会以蓝色来高亮显示。

当适用某个关卡的虚拟世界在Editor中被加载了之后,Play level(播放关卡)按钮会在运行时(rumtime)中变为可用,换句话说,游戏被启动了。 Play level(播放关卡)按钮会为要启动的游戏在运行时(runtime)中加载不止一个引擎的实例。

注意
其它的引擎实例的版本将与Editor所具有的版本相同。

您可从Editor的关卡播放选项窗口更改关卡加载的相关设置(Game framework settings/Editor settings/Play level options):

Play Level Options(播放关卡选项)选项栏
  • Binary - 用来指定播放关卡时要加载的二进制文件
  • Debug - 用来指定是否启用debug模式
  • Video API - 指视频API切换器。 可设置的值有:
    • OpenGL - OpenGL API(适用Windows,OS和Linux系统)
    • Direct3D9 - Direct3D9 API(适用Windows系统)
    • Direct3D11 - Direct3D11 API(适用Windows系统)
  • Resolution - 指引擎窗口的分辨率
  • VSync - 指垂直同步
  • Fullscreen - 指全屏模式
  • Engine Config - 指引擎的配置文件
  • Engine Log - 指引擎的日志文件
  • Editor Config - 指Editor的配置文件

自定义关卡逻辑

自定义逻辑可被应用给游戏中的所有关卡。 它可以是每个关卡独有的,又或是所有关卡都通用的。

注意
自定义逻辑类和带有逻辑的*.h文件的路径名称可以在Logic class选项栏和Logic选项栏中进行设置。

要想游戏能正确运行,逻辑文件就应该从基本的框架关卡类继承。 该类存放在路径下文件data/framework/game/level.h中。

如果用户代码不正确,游戏就不能被加载。 而相应的警告消息也会出现在控制台和日志文件中。

您可通过点击Logic选项栏旁边的Edit Logic(编辑逻辑)按钮来快速访问逻辑文件。 默认情况下,带有指定逻辑的文件夹将被打开。 您可在Editor标签页内的Open Cmd File(打开Cmd文件)选项栏中指定逻辑文件的名称,这样,文件自身就会在点击Edit Logic(编辑逻辑)按钮时被打开:

Open Cmd File选项栏

自定义逻辑的用法举例:

源代码 (UnigineScript)
#ifndef _MYLEVEL_H_
#define _MYLEVEL_H_

/******************************************************************************\
 *
 * class MyLevel
 *
\******************************************************************************/

class MyLevel : Level {
    
  private:
     int first_update = true;
   public:
  
     MyLevel() {
       log.message(“MyLevel constructor called\n”);
     }
 
    ~MyLevel() {
      log.message(“MyLevel desstructor called\n”);
    }
    
    // 在所有实体(entities)创建之前调用该函数
    void onWarm() {
      // 在此放置您的警告代码
      log.message(“MyLevel onWarm() called\n”);
    }
    
    // 在所有实体(entities)创建之后调用该函数
    void onInit() {
      // 在此放置您的init代码
      log.message(“MyLevel onInit() called\n”);
    }
    
    void onShutdown() {
      // 在此放置您的shutdown代码
      log.message(“MyLevel onSutdown() called\n”);
    }
    
    void onPreUpdate() {
      // 实体(entities)更新之前调用
      // 在此放置您的update代码
    }
    
    void onPostUpdate() {
      // 实体(entities)更新之后调用
      // 在此放置您的update代码
      if(first_update) {
        log.message(“MyLevel onPostUpdate() called\n”);
        first_update = false;
      }
    }
    
    void onRender() {
      // 在此放置您的render代码
    }
    
    void onFlush() {
      // 在此放置您的flush代码
    }
};

#endif /* _MYLEVEL_H_ */

类的实例将会在关卡加载时由游戏自动创建,所有的函数也都会以适当的顺序被调用。

您可创建属于您自己的基类,该基类被从框架关卡类继承,而后从它继承您的其它类。 为此,只需在您的关卡逻辑文件中包含基类文件的文件头即可:

源代码 (UnigineScript)
#ifndef _MYLEVEL_0_H_
#define _MYLEVEL_0_H_

#include <data/....my_project_path.../scripts/my_level.h>

/******************************************************************************\
 *
 * class MyLevel_0
 *
\******************************************************************************/

class MyLevel_0 : MyLevel {
    
  private:
  
   public:

    onInit() {
      super.onInit();
      log.message(“my custom logic init\n”);
    }

};

#endif /* _MYLEVEL_0_H_ */
注意
请您确保已在Level(关卡)标签页内指定了自定义类的名称和逻辑文件的路径名称。

创建实体(Entity)

要想创建新实体,须点击New Entity(新建实体)按钮。 这时,实体创建的对话框窗口将被打开:

实体创建的对话框窗口

General(一般)

  • Name - 指实体名称,其会将名称赋予给对应的实体类和属性。
  • %name - 指相对的实体名称,其会被自动设置为*.entity文件,*.h文件,*.prop文件和*.node文件的名称。
  • File - 指*.entity文件的路径名称(相对于data目录的路径),该文件包含了有关实体的所有信息。

Logic(逻辑)

  • Parent - 指基本实体的名称,新实体及其属性的实例都是从该基本实体继承而来。
  • File - 指*.h文件的路径名称(相对于data目录的路径),该文件包含了实体逻辑。

    如果具有指定名称的该文件不存在,那它就将基于标准模型(存放在路径下文件data/framework/plugin/editor/templates/entity/logic.h中)来进行自动创建,该模型是从基本的实体类Entity继承而来。

  • Property - 指*.prop文件的路径名称(相对于data目录的路径),该文件包含了属性信息。 如果具有指定名称的该文件不存在,那它就会被自动创建。
注意
同一逻辑类不能用于不同的实体。

Node(节点)

  • Use Node - 用来指定是否使用已分配的节点来创建实体。 如果禁用了该参数,那新实体就会在不使用任何已分配节点的情况下被创建,这样,当您在节点层级中选中它时,它就没有Node(节点)标签页。 在将这样的一个实体放进虚拟世界中(通过拖拽操作)时,分配有该实体的伪节点就会出现。 与其它类型的节点一样,伪节点也能被分配属性。

    对于未分配实体的节点而言,它们拥有相同的update逻辑和shutdown逻辑(指onInit()onUpdate()onFlush()onRender()onShutdown()这几个函数的调用),不过,它们实体初始化的逻辑是不同的。 如果实体被分配给了节点引用,那该实体的类的实例就会由Node::setVariable方法放进根节点中;但是如果实体是被分配给节点的,那类的实例将不会被放在任何地方,它也不能从节点获得。 不过,您却可以通过onInit()函数来手动获取它。 让我们举个例子来说明:假设将被称为MyEntity的一个空(未分配节点)实体分配给了带有复杂层级的节点。 我们知道,作为子节点,它会拥有一个被称为"my_mesh"的mesh(网格),而该mesh则可由相交(intersection)方法获得。 如果作为变量的指定类的实例会由此mesh获取,那我们就能从该节点获得指定实体的类的实例:

    源代码 (UnigineScript)
    class MyEntity : Entity {
        
      private:
        ObjectMesh my_mesh;
      public:
        
        void onInit() {
          my_mesh = getNode(“my_mesh”);
          my_mesh.setVariable(this);
        }
        
        void onShutdown() {
          my_mesh.setVariable(NULL);
        }
    };
    注意
    如果您通过Node::setVariable()方法设置了实体或其它逻辑类,那您就需要在shutdown()阶段调用Node::setVariable(NULL)方法。
  • Node File - 指新实体的*.node文件的路径名称(相对于data目录的路径)。

    如果*.node文件之前还未被创建,那它就将通过路径下文件data/framework/plugin/editor/templates/entity/template.node中存放的模型来进行自动创建。

如果您想要更改实体创建的自动填写参数,须打开Editor的Settings窗口(Settings/Game/File Path Settings For New Entities):

File Path Settings For New Entities Field(新实体选项栏的文件路径设置)

引擎会为如下文件自动设置指定目录:

  • Entity (*.entity) - 指*.entity文件的路径名称
  • Logic (*.h) - 指带有实体逻辑的*.h文件的路径名称
  • Node (*.node) - 指*.node文件的路径名称
  • Property (*.property) - 指*.prop文件的路径名称
注意
所有的路径都应相对于*.game文件来指定。

如果您将选项栏中的某一个给填错了,那警告图标就会出现。 当您将鼠标悬停在该图标上时,就会显示警告信息。

如果所有的选项栏都填写正确,在点击完Create(创建)按钮之后,实体文件和所有的附加文件就会被创建。 所有这些设置在以后都可以更改。

编辑实体(Entity)

当实体被选中之后,就可以在Entity(实体)标签页和Fields(字段)标签页内对它进行编辑:

实体编辑的标签页
  • Name - 指实体的名称。
  • Parent - 指基本实体的名称,新实体及其属性的实例都是从该基本实体继承而来。
  • Node - 指*.node文件的路径名称。
  • Logic - 指*.h文件的路径名称(相对于data目录的路径),该文件包含了实体逻辑。

    如果具有指定名称的该文件不存在,那它就将基于标准模型(存放在路径下文件data/framework/plugin/editor/templates/entity/logic.h中)来进行自动创建,该模型是从基本的实体类Entity继承而来。

  • Property - 指*.prop文件的路径名称(相对于data目录的路径),该文件包含了属性信息。

    如果具有指定名称的该文件不存在,如果具有指定名称的该文件不存在,那它就会被自动创建。

  • 描述 - 指实体的自定义描述。

字段编辑的标签页
  • Init order - 用来定义实体(entities)初始化的顺序。 该字段仅适用关卡初始化和被放进虚拟世界的实体。 它对动态创建的实体无影响。
  • Enabled - 用来指明是否启用实体及其节点引用。
  • Rendereable - 用来指明onRender()方法是否供该实体调用。
  • Flushable - 用来指明onFlush()方法是否供该实体调用。
  • Updateable - 用来指明onUpdate()方法是否供该实体调用。
  • Update order - 用来定义调用onRender()onFlush()onUpdate()这几种方法的顺序。
注意
所有这些参数都可以在代码中动态更改。

每次游戏被加载或关卡被加载时,实体列表都会被依照用户类中类的层级自动生成 。 为使Editor能正确加载游戏并生成实体列表,就必须编译用户代码。 如果用户代码还未被编译,那游戏将不能被加载,而相应的警告消息也会出现在控制台和日志文件中。

要想将实体的实例放进关卡,只需将其从列表拖出并将其拽进已加载的关卡即可。 分配有属性的节点引用会被自动添加给Editor:

实体的添加

还有另一种将实体添加进关卡的方法:

  • 在Unigine Editor中选择节点引用。
  • 在Game Framework Editor(游戏框架编辑器)中选中实体并点击Assign Entity(分配实体)按钮。

这样,实体的属性就被分配给了节点引用,而该节点引用也就变成了实体。

注意
如果实体之前已被分配给了节点引用,那实体就将被重新分配,所有的属性参数也都将拥有属于它们的默认值。

所有的实体都用蓝色框框出了:

实体框
注意
如果某个实体是节点引用的一部分,那您就需要为其设置entity_traversal属性。 否则,该实体将不能被初始化。

自定义实体逻辑

实体的层级构建以及属性的生成都基于动态编译的用户代码。

注意
要想实体能正确运作,就必须要有逻辑文件,属性文件和节点文件。

如前所述,Fields(字段)代表着实体的属性或自定义设置。 它们都是基于用户代码的属性特征(attributes)被自动生成的,并且这些字段也会依照实体的层级进行分组。

自定义实体的例子:

源代码 (UnigineScript)
#ifndef _MYENTITY_H_
#define _MYENTITY_H_

/******************************************************************************\
 *
 * class MyEntity
 *
\******************************************************************************/

class MyEntity : Entity {
    
  private:
    float rotate_speed = 15.0f;
    float angle = 0.0f;
  public:
    
    MyEntity() {
      
    }
    
    ~MyEntity() {
      
    }
    
    void onInit() {
      // 在此放置您的init代码
    }
    
    void onShutdown() {
      // 在此放置您的shutdown代码
    }
    
    void onUpdate() {
      // 在此放置您的update代码
      // 只是旋转节点
      angle += rotate_speed * game.getGameIFps();
      setRotation(quat(0.0f,0.0f,1.0f,angle));
    }
    
    void onRender() {
      // 在此放置您的render代码
    }
    
    void onFlush() {
      // 在此放置您的flush代码
    }
};

#endif /* _MYENTITY_H_ */

上例向您展示了速度等于rotate_speed值的节点旋转的算法。 要想在框架编辑器中正确更改该速度,您就可以使用Fields(字段)。 只需为Editor中显示的参数添加具有特殊的属性特征(attributes)的setter方法和getter方法即可:

源代码 (UnigineScript)
#ifndef _NEWENTITY_H_
#define _NEWENTITY_H_

/******************************************************************************\
 *
 * class NewEntity
 *
\******************************************************************************/

class NewEntity : Entity {
    
  private: 
    
    float rotate_speed = 15.0f;
    float angle = 0.0f;
    
  public:
    
    NewEntity() {
      
    }
    
    ~NewEntity() {
      
    }
    
    void onInit() {
      // 在此放置您的init代码
    }
    
    void onShutdown() {
      // 在此放置您的shutdown代码
    }
    
    void onUpdate() {
      // 在此放置您的update代码
    }
    
    void onRender() {
      // 在此放置您的render代码
    }
    
    void onFlush() {
      // 在此放置您的flush代码
    }

    [get_float:Rotation Speed]
    float getRotateSpeed() {
      return rotate_speed;
    }
    
    [set_float:Rotation Speed]
    void setRotateSpeed(float value) {
      rotate_speed = value;
    }
};

#endif /* _NEWENTITY_H_ */

待关卡重启完之后,在Fields(字段)标签页内就会出现一个新的float型字段Rotation Speed(旋转速度)

自定义字段(Field)

待实体(entity)的实例被添加给虚拟世界之后,其属性也将能在Nodes(节点)面板中进行调节。 这些属性位于所选实体(节点引用)的Fields(字段)标签页内:

Editor中的自定义字段(Field)
最新更新: 2017-10-20
Build: ()