由UDN上一个小白错误想开去
偶然在UDN中看到如下这一段,觉得很无语,这不是死循环么?但鉴于UDN上讲得这么振振有词,觉得还是有必要去Check一下,看是否是UScript的特殊情况;
Ⅰ,UDNTutorial中的死循环
Continue
Continue命令将会使得当前正在执行的循环跳过此轮循环中的剩余代码并开始下一轮循环。将会判断任何开始或结束条件,如果必要将会退出循环。当该命令和嵌套循环结合使用时,则仅最内部的循环受到这个命令的影响。
让我们看一个在上面的While循环例子中使用Continue命令的示例。
i = 0;
while( i<5 )
{
if(i==3)
continue;
`log(“i is equal to”@i);
i++;
}
正如在前面的示例中所说的,这将会输出每次循环中i的值。但是这次,当i等于3时,将会跳过循环中的代码。循环的最终输出是:
i is equal to 0
i is equal to 1
i is equal to 2
i is equal to 4
您可以看到当i的值等于3时没有输出语句。但是,如果没有Continue命令的话结果将会和之前一样。
Ⅱ,实践检验
相应代码
结果显而易见
到了这里,真相大白了,这应该是Epicd的一个疏忽,估计文档作者太随意了,但遇到问题,就应该解决问题,由于UScript的这个死循环,游戏完全卡死了(我把测试函数在PostBeginPlay()中。
问题来了
1,之前提到过,UVM(Unreal脚本虚拟机),按说它是多线程的,事实不应如此啊?为何主线程会卡死?
2,再遇到这类可能的情况,有无办法防止主线程卡死?
Ⅲ,Answer&Think
先第二个问题,虽然没有意义(实际中不应该出现如此情况),经过若干尝试,初始化函数调用位置?不行,使用latent、但需要Native代码,只有UDK也不行,DLLBing可以一试,但为了一个死循环似乎太蛋疼了,但前一篇中的《Unreal虚拟机相关》是问题的
虽然还有待商榷,但就主线程被卡死这一现象,可以得出结论,目前所知必须从源头制止过长的UScriptFunction,UDN中也做过说明,UScript的执行最要是为消息响应而生,需要大量执行的,Native的C++代码无疑是最佳选择,而且UScript的天然优势决定了你无须为切换,或者数据交换方面多虑;
Ⅳ,一些总结
也正好,看了逍遥剑客前辈的一篇《关于游戏引擎结构上的思考 》也是感悟颇多,也不禁想了下UE的相关特性,对目前的学习做一个小结,UE的特性优点到底在哪里?为何要如此大规模地采用UScript,而其机制到底算什么类型的脚本?
目前对UE的理解还属于比较粗浅的状态,就目前的代码阅读来看,UE的优点我认为主要在以下两点(底层抽象,跨平台,ToolBench,渲染,预处理等尽人皆知,就不再多提):
1,UObject,UActor,Kismet,Matinee,一整套体系,实现了组件,反射,序列化,一步步实现了强大的脚本、动画的视化编辑,便利的存储,及游戏模块的积木式灵活搭建。
2,Material,Animation,PhysX的完善整合,及配套的工具链;
其它还有什么?No,这些已经足够组成一个强大引擎的必备元素了!
究其一切,其中UScript功不可没,问题回到第一个,我的答案是
1,从性能,及相互调用的方便的设计道路,UScript的本质便是穿着Java外衣的C++(+自行组装)代码,所以剔除Unreal虚拟机的概念,其实不妥;
2,欲知详情,从本质来看:
编译:https://udn.epicgames.com/Three/UnrealScriptByteCode
二进制代码:https://udn.epicgames.com/Three/UnrealScriptByteCode
执行:https://udn.epicgames.com/Three/UnrealScriptByteCode
Ⅴ,UE架构体系
最后,通过流程图总结了下,如何在UE的基础上建立一个完整的MMO游戏,左右两边分别代表零散的数据与MMO大概的功能模块,在UnrealEngine的整合下有机的结合,当然,这里只是一个初略的统计,Editor,工具链,游戏流程,状态都未涉及,只是做一个大概的抽象,本文将继续慢慢完善~