UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Landscape Tool
Using Editor Tools for Specific Tasks
FAQ
编程
Fundamentals
Setting Up Development Environment
Usage Examples
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

KeyLine系统

介绍

在许多情况下根据时间或其它的情况(例如光照条件),需要动态改变某些“处于游戏中”的参数。例如基于时间需要改变某些参数;可将参数动画保存为动画帧的序列:值和动画帧的时间。要在任意时刻计算参数值,需要找到上一个键和下一个键并在这两种值之间进行插值。

KeyLine系统处理键的顺序并负责键值之间的插值同时也为数据操作提供GUI。其为某种数据驱动系统,元信息以XML格式进行保存。

KeyLine脚本位于Unigine SDK的 data/scripts/keyline目录下。

实体

Param(参数)

Param(参数)是原子参数的一种类型,原子参数值需要动态改变(参看ParamBase类)。 参数可被序列化成XML与也可使用元数据(ParamDef)将其反序列化。 存在与参数相关联的方法,这些方法指定在某些环境中使用参数值的方式(setter)或从中进行检索(getter)。

存在一套预定义“基本”参数类型,此类型在ParamFloat, ParamInt, ParamVec4 类的盒子外可用。

ParamDef

ParamDef 是一种参数的定义。(类型,ParamEditor, 最小/最大值,默认值,setter/getter 方法)。 ParamDef 类通过其定义用来创建参数实例。

ParamEditor

ParamEditor是一种GUI编辑器类型的定义,用来对参数值进行编辑。(参看ParamEditorBase类)。

Key(键)

Key(键)是一组由某个面向对象进行分组的参数 (参看 KeyBase类)。

KeyDef

KeyDef是一种键的定义(其参数定义的集合)。 KeyDef类通过其定义被用来创建键的实例。

KeyLine

KeyLine是一系列的 (这些键具有相同的类型),每个键通过其位置进行识别。 KeyLine负责在键之间进行平滑插值。 如果KeyLine的光标位置(当前位置)位于结尾键的后面,KeyLine就会在结尾键和第一个键之间进行插值(参看KeyLine类)。

KeyLineManager

KeyLineManager处理一系列的KeyLines (参看 KeyLineManager)。 其也负责最小/最大位置的全局设置。

文件格式

keyman

*.keyman文件包含以XMLKeyLineManager为格式的设置。

keyline_manager节点必须为节点分级的根。此节点具有下列强制性整数属性:min (针对KeyLineManager内所有KeyLines的最小位置)和max (用于所有KeyLines的最大位置)。除此之外,整数属性的持续时间 指定一个时间段,在此时间段期间KeyLineManager将从最小位置处传递到最大位置处。

keyline_manager节点可包含0个或更多的子keyline节点,每个节点都包含file属性,此属性指向 *.keyline文件。例如:

源代码 (XML)
<?xml version="1.0" encoding="utf-8"?>
<keyline_manager min="0" max="86399" duration="1440">
	<keyline file="demos/tropics/tropics_sky.keyline"/>
	<keyline file="demos/tropics/tropics_render.keyline"/>
</keyline_manager>
根据此节点,真实世界中的1440 秒相当于游戏中的86399 秒,及游戏中的一天。这就意味着keyline使用真实时间1 秒将穿过60 个位置(86399 秒 / 1440 秒 = 60) 另外游戏中的一天对应真实世界中的24 分钟(1440 秒 / 60  秒)。
注意
KeyLineManager类可以编程的方式定义持续时间 和浮点型乘数,它们控制着时间变化的速度。为了能达到这样的目的,其拥有成员函数setDuration() 和 getDuration() 以及setMultiplier() 和getMultiplier()。

keyline

*.keyline文件包含以XML为格式的keyline数据。 文件内仅能保存一个keyLine。

keyline节点必须为节点分级的根。此节点具有强制性name属性: minmax属性与 keyline_manager属性具有相同的意义,当会忽略这些属性的值因为KeyLineManager对其进行覆盖。 keyline必须拥有 key_def节点并将其作为后代。

key_def节点可通过两种不同的方式进行定义:

源代码 (XML)
<!--
key_def (键定义) 节点: 基准格式。
(所需)文件 - 用来指定文件,此文件包含使用下列格式的键定义。
-->
<key_def file="demos/tropics/tropics_timeline.keydef"/>
or
源代码 (XML)
<!--
key_def 节点 - 完全格式化。
attributes:
keyline (所需,如果key_def被放置到单独文件中且为可选选项,如果key_def被放置到keyline节点内)。
用来识别 key_def。
-->
<key_def keyline="scattering">
	<!--
	在此放置参数的定义
	-->
	<!--
	param_def (参数定义) 节点。
	属性:
	type (必需) - 参数类型的字符串识别器。通过其名称用来创建参数实例。
	name (必需) - 唯一的参数名。用来识别键中的参数。
	editor (必需) 参数编辑器类型的字符串识别器。用来生成GUI从而用于对键进行编辑。
	-->
	<param_def type="float" name="energy" editor="float_slider">
		<!--
		用于参数的getter 方法名 (可选)
		-->
		<getter>engine.render.getScatteringEnergy</getter>
		<!--
		用于参数的gsetter方法名 (可选)
		-->
		<setter>engine.render.setScatteringEnergy</setter>
		<!--
		用于参数的最小值(可选)
		-->
		<min name="energy">0</min>
		<!--
		用于参数的最大值(可选)
		-->
		<max name="energy">40</max>
		<!--
		用于参数的默认值(可选)
		-->
		<default_value name="energy">15</default_value>
	</param_def>
</key_def>

keyline节点有后代key节点,此节点包含键的数据。 如果在keyline内不存在键,将自动创建一个键。 将使用参数对此键进行填充,此参数通过环境中的getter方法得到检索(当从先前调整的非序列参数开始时,这种做法很有用)。

key节点拥有下列格式:

源代码 (XML)
<!--
关键节点。包括一系列参数值。
属性:
pos (必需且唯一) -帧在 keyline上的位置。
-->
<key pos="43200">
	<!--
	param 节点。包含参数数据。 
	属性:
	name (必需且唯一) - 参数名,此参数名同样也被系统作为参数辨识器进行使用
	-->
	<param name="areal">30</param>
	<param name="greenstein">0.9</param>
	<param name="mie_color">1 0.972549 0.858824 1</param>
</key>

keydef

*.keydef文件包含以XML为格式用于键类型的定义。

definition节点必须为节点分级的根。 version 属性用于将来的使用。 definition 节点包含一套使用完整格式的key_def节点,在keyline文件定义内进行描述。

例如:

源代码 (XML)
<?xml version="1.0" encoding="utf-8"?>
<definitions version="1.0">
	<key_def keyline="scattering">
	<!-- ... -->
	</key_def>
	<key_def keyline="sky">
	<!-- ... -->
	</key_def>
	<key_def keyline="render">
	<!-- ... -->
	</key_def>
</definitions>

使用方式

开始

第一步。准备用于参数的getter和setters方法

源代码 (UnigineScript)
namespace Foo {
	
	void setterFunc(DataType v) {
		// 设置参数的一些操作
	}
	
	DataType getterFunc() {
		// 检索参数值 
	}
}

第二步。准备keyline文件管理器

创建keyline文件管理器(例如test.keyman)。 定义keylines:

源代码 (XML)
<?xml version="1.0" encoding="utf-8"?>
<keyline_manager min="0" max="86399" duration="2160">
	<keyline file="test.keyline"/>
</keyline_manager>

创建keyline 文件(例如test.keyline):

源代码 (XML)
<?xml version="1.0" encoding="utf-8"?>
<keyline name="test keyline">
	<key_def>
		<param_def type="float" name="param 1" editor="float_editline">
			<getter>Foo::getterFunc</getter>
			<setter>Foo::setterFunc</setter>
		</param_def>
	</key_def>
</keyline>

第三步。将keyline管理器的标头包括到脚本中

源代码 (UnigineScript)
// 包括所有必需的keyline管理器标头:
#include <keyline.h>
// 如果要使用浮点型, vec4 或整型参数类型及其编辑器,需包括基本参数(可选):
#include <params_basic.h>

第四步。初始化keyline管理器

源代码 (UnigineScript)
KeyLineManager manager;

void init() {
	// 将基本参数注册从而允许通过名称来创建(从文件中进行加载时需要)
	KeyLine::registerBasicParams();
	
	// 创建并加载keyline
	manager = new KeyLine::KeyLineManager();
	manager.load("test.keyman");
}

第五步。在需要时,更新位置并调用应用

源代码 (UnigineScript)
int update() {
	if(play_mode) { 
		manager.play();     // 更新位置   
	}
	manager.apply();        // 提交参数(在管理器内为每个参数调用setter方法)
}

将GUI用于编辑

KeyLine提供GUI编辑器,这样用户可以操纵键并更改参数值。 参考下列内容在项目中使用GUI编辑器。

第一步。包括标头

源代码 (UnigineScript)
#include <keyline/keyline_window.h>

第二步。编写初始化,关机及更新代码

源代码 (UnigineScript)
void init() {
	Gui gui = engine.getGui();
	KeylineWindow::init(gui);
	KeyEditorWindow::init(gui);
}

void shutdown() {
	KeylineWindow::shutdown();
	KeyEditorWindow::shutdown();
}

void update() {
	KeylineWindow::update();
	KeyEditorWindow::update();
}

第三步。显示窗口

源代码 (UnigineScript)
void show_window() {
	// 设置回调(可选) 
	KeylineWindow::setOnSaveCallback("on_save_manager");
	KeylineWindow::setOnResetCallback("on_reset_manager");
	KeylineWindow::setOnHideCallback("on_editor_closed");
	KeylineWindow::setOnSetCaptionCallback("gen_pos_caption");
	
	// 显示窗口
	KeylineWindow::show(manager);
}

/* 回调(可选) 
*/
void on_save_manager() {
	/* 用户若想将keyline管理器保存到文件中,暂时中断  */
}
void on_reset_manager() {
	/* 用户若想撤销更改并重新加载keyline管理器,暂时中断 */
}
void on_editor_closed(int is_changed) {
	/* 编辑器窗口关闭时,暂时中断。如果keyline管理器内存在未保存的更改,is_changed == 1*/
}
string gen_pos_caption(float pos) {
	/* 生成用于keyline窗口GUI的位置标题。返回一个格式化的字符串 */
}

使用自定义参数

如果基本参数未能满足所有需求,可编写自己的参数类型。

要完成这样的操作,必须继承来自KeyLine::ParamBase的类并覆盖或至少加载,保存并复制方法。 来创建继承自 KeyLine::ParamEditorBase类的参数编辑器。 接着必须编写用于创建参数的方法:

源代码 (UnigineScript)
/* 用于自定义参数的creation方法
*/
ParamBase createCustomParam() {
	// 在有需要的情况下,在此处添加一些额外的初始化
	return new CustomParam("foo");
}

/* 用于自定义参数编辑器的creation方法
*/
ParamEditorBase createCustomParamEditor(ParamDef def,Gui gui) {
	// 在有需要的情况下,在此处添加一些额外的初始化
	return new CustomParamEditor(gui);
}
并在系统中进行注册这些参数:
源代码 (UnigineScript)
addParamType("foo","createCustomParam");
addEditorType("foo_editor","createCustomParamEditor");

GUI

KeyLine系统会自动生成GUI用于对键进行编辑。

KeyLine主窗口

KeyLine 的设置

Key编辑器窗口
最新更新: 2018-06-04