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

语言特点

动态输入#

与C++使用静态输入不同,UnigineScript使用动态输入。这就意味着输入检测动作会在执行期间进行而不会在变量声明期间进行。基于这种情况,可能会碰到以下境况:

  • 在文档内的许多地方虽然可看到使用具体类型或具体函数参数类型声明的变量,这些类型标记对用户而言是一种提示。即可以定义一种整型变量并未此变量分配一个字符串。
  • 在解译器开始对表达式求值之前,并不会执行输入检查。如果需要某种指定类型的数据或是某种指定自定义类的数据,需使用 typeof()typeinfo() 函数对数据进行检查。
  • 有时可能会在函数声明中见到变量类型。变量并不是一种真实的类型而且这条消息甚至不会被保留下来。变量伪类型意味着某种函数知晓其可以接收不同类型的数据并将基于变量参数的类型作出不同的反应。
  • 当然还有数种基本类型,这些基本类型的名称会得以保留。我们会在此处对这些基本类型进行简略地检查。当然您也可以定义自己想要的类型-类。

内存管理#

UnigineScript提供一种垃圾回收器,这种回收器会自动对在UnigineScript中创建对象的内存进行管理:在需要时对内存进行分配,当内存不再被对象引用时便释放内存。针对数帧会启动垃圾回收器。对于所有分配的内存块,垃圾回收器会检查是否仍存在对这些内存块的引用;如果某个内存块不再为任意对象所引用,此时便会释放此内存块。当然如果脚本运行结束,也会释放所有分配的内存。

注意
从C++部分导出的对象会一直存在直到对象析构函数的显示调用发生。也可在对外部类的内存管理中查看相关信息

可查看 析构函数和 delete方法

序列化#

Unigine序列化机制可以将对象的状态保存为二进制文件并在稍后进行状态的复原。无需程序员做什么动作,纯UnigineScript类会被自动进行保存并复原。但如果此类使用了从C++中导出的对象且此对象不对自身实施序列化操作,此时就应定义两种特殊的方法:

  • __save__()
  • __restore__()
这些方法名得以保留,将其看作一种应被用于执行对象序列化的接口。第一种方法__save__()会在保存虚拟机状态之前被调用。第二种方法__restore__()会在保存虚拟机状态之后被调用。
注意
可在无参的情况下定义__save__()__restore__()两种方法或者定义 __save__(Stream) __restore__(Stream)。但不可将两种方式混淆在一起。没有必要采用两种类型的定义方式,在这种情况下采用Stream参数的函数会得到调用。
源代码 (UnigineScript)
class Foo {
	
	// Foo.__save__()会在保存虚拟机状态之前被调用。
	void __save__() {
		save_to_file(“file.xml”);
	}

	// Foo.__restore__() 会在复原虚拟机状态之后被调用。
	void __restore__() {
		load_from_file(“file.xml”);
	}
	
	// 保存为文件
	void save to file(string filename) {
		// …
		log.message(“saving\n”);
	}

	save to file
	void load_from_file(string filename) {
		// …
		log.message(“loading\n”);
	}
};

engine.console.run(“state_save”);

也可查看:Unigine C++ API内的 序列化

C++和UnigineScript的句法区别#

以下为两种语言句法之间的主要差异。

  1. 矢量初始化与C++不同。将矢量项放在圆括号中而不是提供一张将矢量项放在一对花括号中的列表。
  2. 构造函数与类的声明分开定义且构造函数具有不同的特征码,参看 构造函数及new方法
  3. 析构函数与类的声明分开定义且析构函数具有不同的特征码,参看 析构函数及 delete方法
  4. 使用dot运算符访问成员。
  5. 无受保护的访问级修饰符,仅有公共修饰符及私有修饰符。默认情况下所有的类成员都是公共类型。
  6. UnigineScript使用命名空间,此空间代表函数库。使用dot运算符将命名空间的名称与函数名分隔开来。请注意命名空间的名称可包含点号,因此为避免歧义仅将最后一个点号作为命名空间与函数之间的分隔符使用。
    注意
    也存在指定变量及函数作用域的“普通”命名空间
  7. 矢量数据类型对象允许使用swizzling对其成员进行访问,即如果有vec3类型的my_vector对象,可通过如下方式访问其成员:my_vector.xmy_vector.zyx等。
  8. UnigineScript不支持结构(struct)。
  9. UnigineScript提供大量额外的语句,这些语句能影响控制流: forloopforeachforeachkeyyieldwait
  10. 在UnigineScript中有一种叫做 call 的特殊函数。此函数可对所有函数进行求值运算,这些函数的名称或标识符会被作为参数进行传递。
  11. 在UnigineScript中不存在"virtual"关键字。当某个用户类继承自另一个类时,两个类都将自动支持虚拟方法。
最新更新: 2018-12-27