关键词不能为空

当前您在: 主页 > 英语 >

udk教程

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-03-01 02:07
tags:

-

2021年3月1日发(作者:ascension)



原文见


/bbs/?tid=5



第一步:



首先,我们从



主页下载最新版(此文以


UDK-2010-01< /p>


版为


例)



安装 完成后,


我们找到


UDK-2010-01

文件夹,


对其复制粘贴创建一个副本,


将目


录名改成你喜欢的名字,比如我创建为


KingdomWorld


,以后文章都以


KingdomWorld


为例。< /p>



(


以下步骤将对其进行大量修改,创建 副本的目的是为了保留原版


)



第二步



2.1.

进入


KingdomWorldDevelopmentSrc

目录,找到


UTGameContent


文件夹将


其全部删除。



2.2.


进入


KingdomWorldDevelopmentSrcUTGame


目录,


删除



以及


Classes


文件夹下面的所有文件,但是保留

Classes


文件夹。



2.3 .


进入


KingdomWorldDevelopmentSr cUTGameClasses


目录,创建一个


do_not_


,键入以下内容



1.



class do_not_delete extends object;


2.



defaultproperties


3.



{


4.



}


复制代码



创建此文件的目的是因为让


UTGame


目录顺利编译成


UTGa me.u


文件,因为


UDK


免费版的原 因,启动编辑器和游戏他会自动寻找


UTGame.u


文件,所 以此包无法


全部删除(除非你有源代码级授权,就可以修改


UT Game


目录指向)




第三步



进入


KingdomWorldUTGameContent


目录,删除所有文件

< p>



文件和


Kingdo mWorldUTGameContentUIUI_Fonts_


文件除外,


这两个是系


统需要的底层


pak


包,字体和空场景,最好别删。




第四步



由于我们已经删除了所有关于 原始的


UTGame


的资源和代码文件,现在的文件夹


已经相对于来说是非常干净的了,那么,我们需要重新制作一个类似于


c ++


里面



main

< br>函数,因为


UTGame


目录已经被我们咔嚓掉了。他的 引用不到。



4.1.


来到

< p>
KingdomWorldDevelopmentSrc


目录,创建文件 夹


KWGame,


在其创建


Class es


文件夹



4.2.


进入


KingdomWorldDevelopmentSrcKWGameC lasses


目录




4.3.


创建一个



,键入以下 内容



1.



class KWInfo extends GameInfo;


2.



DefaultProperties


3.



{


4.



//


设置角色控制类



5.



PlayerControllerClass=class'erController'


6.



}


复制代码



4.


创建一个



,键入以下内容



1.



class KWPlayerController extends GamePlayerController;


2.



DefaultProperties


3.



{


4.



}


复制代码



第五步



我们已完成了创建了我们自己 的初始化函数


KWInfo


和控制类函数


KWPlayerController,


那么我们需要吧编辑器的引用指向他们。< /p>



5.1.


进入


KingdomWorldUTGameConfig


目录。




5.2.


打开



文件。找到


[fo]


中的

< p>


tGame


并修改成


D efaultGame=


tServerGame


并修改成< /p>


DefaultServerGame=


Controller ClassName


并修改成


PlayerControlle rClassName=erController



第六步



在这里,我们基本完成了整个 目录的精简,只留下我们需要的部分了,最后,我


们需要对整个工程进行优化,


去掉不存在和不需要的包的引用。


加入我们的引用


目录。



6.1.


进入


KingdomWorldUTGameConfig


目录。




6.2.


打开

< p>


文件。找到


[Engine]

中的



tPackages


并修改 成


ModEditPackages=KWGame(



ModEditPackages


最前面的


;


去掉


)


6.2.2.


删除


+EditPackages=UTGameContent


这句



6.2.3.


找到< /p>


[rdUser]


中的


MyDocume ntsSubDirName


并修改成


MyDocuments SubDirName=KWGame



========2 010-01-29


修改新增


==============< /p>



6.3.


打开



文件。找到


[raction]


中的< /p>



Name


并修改为

UISkinName=tSkin



6.4.


打开



文件。找到


[]< /p>


部分。



6.4.1.

< br>将


[]


部分改为如下


(


其实就是吧


UTGame


改成

< br>Engine,


并且


去掉前缀


U T)


1.



[]


2.



ConsoleClassName=e


3.



EditorEngine=orEngine


4.



UnrealEdEngine=alEdEngine


5.



DefaultOnlineSubsystemName=SubsystemPC


6.



UseStreaming=True


7.



ScoutClassName=


8.



GameViewportCl ientClassName=ewportClient


9.



;DefaultPostProcessName=FX_Process


eenKismetWarnings=true


tweenPurgingPendingKillObjects=30


ntName=nt


FontName=MultiFont'UI_Fonts__Medium'


ontName=MultiFont'UI_Fonts_..MF_Large'


leFontName=MultiFont'UI_Fonts__Medium'


hadowVolumes=False


layerClassName=layer


ticleResize=1024


ticleResizeWarn=10240


20.;DemoRecordingDevice=cDriver


eColorClear=TRUE


复制代码



(


例如


ConsoleClassName=ole


改为


ConsoleClassName=ole)


6.4.2.


找到


[oreClient]


部分删除节点所有文件,新增一行



+PlayerD ataStoreClassNames=Store_OnlinePlayerData


如下:



1.



[oreClient]


2.



+PlayerDataSto reClassNames=Store_OnlinePlayerData


复制代码





6.4.3.


找到


[Store_On linePlayerData]


改为如下


(

< br>其实就是吧


UTGame


改成


E ngine,


并且去掉前缀


UT)


1.



[Store_OnlinePlayerData]


2.



ProfileSetting sClassName=ProfileSettings


3.



FriendMessages ProviderClassName=Provider_OnlineFri


end Messages


4.



Frie ndsProviderClassName=Provider_OnlineFriends


复制代码





6.4.4.


找到


[pPackage s]


改为如下



1.



[pPackages]


2.



bSerializeStar tupPackagesFromMemory=TRUE


3.



bFullyCompressStartupPackages=FALSE


4.



Package=DefaultUISkin


5.



Package=EngineMaterials


6.



Package=EngineSounds


7.



Package=EngineFonts


8.



Package=EngineBuildings


9.



-Package=SoundClassesAndModes


复制代码





6.4.5.


找到


[esToForc eCookPerMap]


去除所有节点。




6.5.


打开



文件。找到


[nfo]


部分。



6.5.1.




EmitterPoolClassPath






EmitterPoo lClassPath=


6.5.2.




DecalManagerClassPath






DecalMa nagerClassPath=



7.


删除


KingdomWorldUTGameConfig


下 所有


UT


开头的


ini


文件,并且重新进


入编辑器,就会自动生成


UT


开头的


ini



< /p>


========2010-01-29


修改新增


==============





总结:



至 此,你已经完成


UDK


目录的精简,并且删除了


UTGame


的全部内容,在接下来


的章节,我会一步 步介绍如何在这个精简工程中,全部制作属于自己的东西



这时 候你打开


UDK


编辑器,


可能需要等待 一会的时间,


因为他在重新编译一些东


西,耐心等待一下就可以 了。




下一章节预告【跟着楼主做游 戏之】《建立一个空工程


-


下》建立一个空的

< br>VS


工程,并且调试


KWGame


项目。



(请大家提前安装


vs20 08


或者


vs2005


,最好使用


vs2008



vs2003


是不可以的,


因为有个脚本调试插件,他只能在


vs 2008


或者


vs2005


中运行)< /p>



另外本文的大部分内容,阅读者最好有一定的编程基础,多以代 码为例讲解。







如果你确定看完了


《建立一个空工程


-


上》


这 篇,并且没有问题,那么接着和我学习把。




第一步:



首先确保机器已经安装


vs2008(


或者


vs2005


,以后文章都以


vs2008


为例


),


然后安装


nFringe

(nFringe






/?title=Tools:UnrealScript_Stud io:Releases


可以在这里


找到


,


目前附件传的是



也是截止发帖时候 的最新版,此插件有


30


天使用限制,我先看大家的下载次数吧 ,至少


30


天内我暂时不会公开破解补丁


)




第二步:



2.1.

< br>打开


VS2008


,选择左上角菜单中的【文件】


--


【新建】


--


【 项目】



2.2.


选择


UnrealEngine 3 Licensees Project


2. 3.


检查【创建解决方案的目录】的勾是否已被去掉。



2.4.


位置填写为



安装目录


:KingdomWorldDevelopmentSrcKWGa me


2.5.


名称为


KWGame(


注意大小写


),


点击确定


.


2.6.






KingdomWorldDevelop mentSrcKWGameKWGame










KingdomWorld DevelopmentSrcKWGame


2.7.


打开目 录


KingdomWorldDevelopmentSrcKWGame


删除


KWGame


文件夹


(


此时里面那个


文件夹应该没有文件,都被你剪切到上面了


)


2.8.


打开目录


KingdomWorldDevelopmentSrcKWGame


使用


vs2008


打开



工程




第三步:



3.1.


选择左上角菜单中的【项目】


--



KWGame


属性】



3.2.


设置如下参数。




General




Game


中的


Target Game



UnrealEngine 3 Mod


UCC Path




安装目录


:


Reference Source Path




安装目录


:KingdomWorldDevelopmentSrc


Build




Script


Outputs




Manually


set


UCC


output


directory







< br>:KingdomWorldUTGameScript


Debug




Start Action


中的


Start Game Executable




安装目录


:


Load


map


at


startup


为你的地图文件名,如我们为默认上次没删的



则填写为


EnvyEntry


Start with speacified game




勾上


Enable unpublished mods


勾上


Open log window at postions


并且设置为


0 Left,0 Top





第四步:



4.1.

< br>进入目录


KingdomWorldDevelopmentSrcKWGame


,将


Classes


文件夹改名为


Classes1


4.2.


< p>
vs2008


里选中


KWGame


工程点击右键,选择【添加】


--


【新建文件夹】







4.3.


讲其文件夹名命名为


Classes


4.4.


关闭


vs2008


,进入目录


KingdomWorld DevelopmentSrcKWGame


,删除


Class es


文件夹,



Classes1


改名回


Classes


(


因为在上篇文章里这个文件夹下有


2


个文件,


先改名是为了防止


vs2008


里创建同名文件 夹


失败


)


4.5.

< br>打开目录


KingdomWorldDevelopmentSrcKWGame


使用


vs2008


打开



工程



4.6.



vs2008


里选中


KW Game


工程中,选中


Classes


目录,点击右键,选择【添加】


--


【添


加现有项】




< br>KingdomWorldDevelopmentSrcKWGameClasses

< br>目








(上篇教程中创建)







4.7.



vs2008


里选中


KWGame


工程


(


选择工程路径不是


Classes< /p>


文件夹


)


点击右键,选择【添

< p>
加】


--


【添加现有项】



选择


KingdomWorldUTGameConfig


目录下的





(特别注


意添加文件的时候,在窗体那里添加按钮旁边有个小三角,选 择添加为链接)







总结:



至此,你可以在


VS2008


中调试你 的


UDK


项目了,在下面章节中,我们将会对这个工程继


续讲解。来做一个类似大菠萝的视角的游戏。









在以上的章节中,我们已经创建了 一个可以调试的


UDK


空环境,并且保证除了底层


Engine


部分,其他的资源都已经剔除掉了,在这里,我们接着开发属于 自己的游戏。




第一步:



我们先吧制作好的场景


(可以参考其他教程或者等待其他人更新场景制作教程,


在此系列就








UDK














< br>给








KingdomWorldU TGameContentMaps


中。



附带一个我随便制作的场景:




第二步:



进入


KingdomWorldDevelopmentSrcKWGame


目录,打开< /p>



工程。



修改工 程属性的


Debug



Start Action


中的


Load map at startup< /p>



1001(


地图名

)





保存


(ctrl+s)


好后,我们可以在工程里按下菜单里的 【调试】


--


【启动调试】


(F5)< /p>


来看效果。







如果能正确显示如上画面后,代表 你的


vs


工程配置没有问题了。



接下来我们需要按下键盘的



键,呼出控制台 ,输入


exit


并按下回车退出游戏界面







要注意的是,这时候虽然游戏关闭了,但是你的


VS

< p>
工程并没有关闭,



我们需要点击菜单里的【调试 】


--


【停止调试】


(Shift+F 5)


来停止工程。







第三步:



现在我们在


vs


工程里双击打开


Classes

< br>里的



进行编辑。







可以发现,我们编写的


KWPlayerController


类实际上继承了


GamePlayerController


类。




GameP layerController


类是做什么的呢?(具体我们可以参考


API


手册


,


文章末尾的附件 )



其实是一个角色控制类。这么说吧,比如像在控制台里面的 命令,鼠标,键盘的操作,全部


都在这个控制类。


< p>
你可以吧他看成一个


Input


控制类。



所以,当你的鼠标点击的时候,我们可以在这个类里编写代码来实现你 需要的功能。



在学习写第一个类的时候,

我们可以加一小段调试代码,


从而观察环境里的这个类是否被运

行。



3.1.


新增一个


PostBeginPlay


方法



1.



simulated event PostBeginPlay()



2.



{



3.





ginPlay();



4.





`Log(


角色控制类运行




5.



}



复制代码





新增代码后的效果:















ayerCon troller






Controller



Controller


中,则有一个


simulated event PostBeginPlay


,所以我们可以重写,


他也会被自动调用


(


这是


UDK



uc


脚本机制


)


其实追溯源头应该是



,而在此类有一个


event


PostBeginPlay();


在他继承的类中


重写,则会被自动调用。



而大部分类的主父类都集成了它,基本上类在运行后,都会首次寻找是否有


PostBeginPlay


方法来执行。你可以吧他看做这个类的构造函数吧。



因为重写了他,


因为我们并不知道继承的 这个类的上面那些乱七八糟类里同样方法里做了一


些什么事情,所以我们试用

< p>
super


来调用父类的这个函数。在后面再插入我们自己需要编写


的代码。







第四步:



由于我们之前已经在



里的


DefaultProperties


方法里,


对< /p>


PlayerControllerClass


的指


针已经赋值到了我们新做的


erController


里。所以这里我们新做的控制类


则会被调用。



在这里说一下,由于我们在



里修改的


[fo]


中的


DefaultGame


指向到



类,那么


KWInfo


你可以看做整个游戏的


main


函数。




PlayerControlle rClass


是默认的用户控制类的指针


(

其他指针可以参考


API


,后面也会对一

< br>个个指针进行讲解)



而我们需要做的就是新建一个类继 承他,然后在


main


里绑定他。


< /p>


现在,我们可以按下


F5


,看一下左边日 志窗口的提示信息。







如果你的界面如上图所示,那么你 的游戏已经成功调用了


erController


类。



很激动吧。你已经完成了你的第一个类的编写,并且通过


VS


已经调试出结果了。



还记得我们之前的步骤吗?按下键盘上的



键呼出控制台,输入< /p>


exit


,并且在


vs

< br>里点击停


止调试就可以回到我们的界面来继续编码。




总结:



现 在你已经基本搭建好一个良好的


UDK


编写代码环境了,在下一 章节,我们将会继承一个


新的


Camera

类,通过


KWInfo


来绑定,来实现我们自己的游戏界面 的视角。



本文附带源码:















第一步:



我们先把制作好的角色模型


(可以参考其他教程或者等待其他人更新模型制作教


程,在此系 列就不涉及大部分


UDK


编辑器部分



的操作,本系列留给程序员)放



Ki ngdomWorldUTGameContentCharactersHeroesAchilles


中。


(KingdomWorldUTGameContent


后的路径随便你定义,你直接放在


Content

< br>里


也行,这样做的目的仅仅是便于管理而已)



附带一个我随便制作的模型:




第二步:



打开工程。在


Classes


文件夹里添加一个


KWCamera


类。并编写如下代码



1.



class KWCamera extends Camera;


2.



simulated event PostBeginPlay()


3.



{


4.



ginPlay();


5.



`Log(


摄像机类运行



6.



}


复制代码





我们编写了一个继承了摄像机类的 的类,从而完成我们自己的摄像机视角。




第三步:



找到我们之前编写的



文件,



Defau ltProperties


内添


加一行



1.



CameraClass=class'KWCamera'


复制代码








这里要 特别说一下,


DefaultProperties


可以当做是 每个类的函数初始化的地


方,这里是不需要分号来换行的



通过


CameraClass=


来赋值指针 为我们编写的类从而重载。




这时候 可以通过


F5


来调试一下,


看看日志窗 口


`Log(


摄像机类运行


< p>
这句话是


否正确执行。






在控制台输入

exit


退出游戏界面,


记得在


v s


里停止工程,


我们来做一个出生类。




第四步:



打开工程。在


Classes


文件夹里添加一个


KWPawn


类。并编写如下代码



1.



class KWPawn extends GamePawn;


2.



simulated event PostBeginPlay()


3.



{


4.



ginPlay();


5.



`Log(


出生类运行



6.

< p>


}


7.




8.



simulated function name GetDefaultCameraMode( PlayerController


RequestedBy )


9.



{


10. `Log(


开始获取默认摄像机模式



11. `Log(


设置为


Isometric


模式



12. return 'Isometric';


13.}


14.


tproperties


16.{


17. //


删除场景内原有的元素



18. (Sprite)


19. //


创建动态环境光照对象


--


用于

InitialSkeletalMesh


对象


(


使用


LightEnvironment


成员赋 值


)


20. Begin Object Class=DynamicLightEnvironmentComponent


Name=InitLightEnvironment


21. ModShadowFadeoutTime=0.25


22. MinTimeBetweenFullUpdates=0.2


23. AmbientGlow=(R=.01,G=.01,B=.01,A=1)


24. AmbientShadowColor=(R=0.15,G=0.15,B=0.15)


25. LightShadowMode=LightShadow_ModulateBetter


26. ShadowFilterQuality=SFQ_High


27. bSynthesizeSHLight=TRUE


28. End Object


29.


30. //


添加进组件库



31. (InitLightEnvironment)


32.


33. //


创建骨骼模型



34. Begin Object Class=SkeletalMeshComponent


Name=InitialSkeletalMesh


35. CastShadow=true


36. bCastDynamicShadow=true


37. bOwnerNoSee=false


38. //


使用组件库里动态创建的环境光照对象


InitLightEnvironment


39. LightEnvironment=InitLightEnvironment;


40. BlockRigidBody=true;


41. CollideActors=true;


42. BlockZeroExtent=true;


43. //


物理引擎包



44. //PhysicsAsset=PhysicsAsset'Achi lles_es_


Full_Apa'


45. //


动画包


--


序号


0


46. //AnimSets(0)=AnimSet'Achill es_es_Full_A


as'


47. //


动画模板



48. // AnimTreeTemplate=AnimTree'Achilles_es_


F ull_Aat'


49. //


模型文件



50. Sk eletalMesh=SkeletalMesh'Achilles_es_Fu


l l_Amesh'


51. End Object


52.


53. //Mesh


来自


GamePawn


的基类成员


(


貌似是设置出生角色


)


54. Mesh=InitialSkeletalMesh;


55. //


添加进组件库



56. (InitialSkeletalMesh);


57.}


复制代码





这段代码我说明两个地方。



一个是< /p>


defaultproperties


里面的成员,这个我是参考 原本的


UDK-



文件复制过来。并且 我


对如上代码做了相应的注释。由



于 我提供的资源包里只有模型文件。所以其他


资源的属性我都注释掉了。

< br>



另外一个是


simulated function name


GetDefaultCameraMode( PlayerController RequestedBy )


这个方法会在


Camera


启动后调用得到。



之所以我传入


return 'Isometric';


是因为通过观察


< br>里面的


UpdateViewTarget


方法,并没有 这么一个字符串,所以我是随便写的,你也可


以随便写一个,在后面我们继承的


Camera


类中,重写


UpdateVie wTarget


方法


取得值来进行处理。所以这里的

< p>
'Isometric'


你改成


'xx','yy ','bb'


都可以




第五步:



找到我们之前编写的



文件,在


DefaultPropertie s


内添加两行



1.



bDelayedStart=false


2.



//


设置出生类



3.



DefaultPawnClass=class''


复制代码







DefaultPawnClas s


绑定到我们修改的


Pawn


里,这里 不做多说明。




特别说明下


bDelayedStart


成员变量


,bDe layedStart


来自继承的


GameInfo



(有兴趣的可以去



里看这个变量


调用的一些地方做了什么)


bDelayedStart


在此刻是非常重要的,


因为我 们重写


了游戏,而不是使用游戏内的


Kismet


来进行绑定,那么此时游戏内是没有


Pawn


的,我 们需要告诉引擎来调用我们的出



生类,而不是等待,那么,把 他设置成


False



游戏引擎将不再 等待角色的产生,


不再延迟而立即产生了我们的


Pawn


(当


然,如果你需要游戏做过场动画或



者摄像机漫游的时候,以及在登陆界面的时



-


后面说,可以做一个方法来设置他的值将他设置为


True





这时候 ,


我们进行调试,


可以发现我们编写的类已经全部正确调用,< /p>


并且通过键


盘的


WSAD


键进行移动后,发现我们设置的角色已经绑定我们的摄像机一起移动


了。






第六步:



现在我们已经成功了部署整 体架构,还记得我们之前的那个


'Isometric'


吗?我


们现在就得来处理它,完成最后一步,实现自己的摄像机模式。




找到我们之前编写的



文件,对继承的


Camera


类点右键,选择转到


定义。



(


或者打开


)






按下键盘的


Ctrl+F


找到


UpdateViewTarget


方法,复制进我们的


因为我们要在中间部分修改,


所以不好直接调用


ViewTarget()


了。




找到


switch(


CameraStyle


)


部分,< /p>


添加我们前面定义的那个


'Isometric'



case


1.



/****************************************** ********************


***


2.



*


自定义摄像机模式开始



3.



************** *************************************************< /p>


**/


4.



//


从自定义的


Pawn



(KWPawn)



GetDefaultCameraMode


传来



5.



case 'Isometric':


6.



//


修改摄像机位置



7.



= (-55.0f *DegToRad) * RadToUnrRot;


8.



= (0 *DegToRad) * RadToUnrRot;


9.



= (30.0f *DegToRad) * RadToUnrRot;


10.


11. //


修改摄像机的位置和角色的偏移



12. Loc.X = on.X - 64;


13. Loc.Y = on.Y - 64;


14. Loc.Z = on.Z + 156; //


距离位置



15.


16. //


设置缩放



17. Pos = Loc - Vector(Rot) * FreeCamDistance;


18. on = Pos;


19. on = Rot;


20. break;


21./*************************** ***********************************


***


22.*


自定义摄像机模式结束


< /p>


23.************************************* **************************


**/


复制代码





由于复制过来的代码使用了一个成员变量


= DefaultFOV;


所以,



C amera


类里,


找到赋值他的地方添加进我们重写的


KWCamera


类里。



DefaultProperties


方法。

< p>
这样方便我们以后如果对这个值进行修改而不动底


层的东西。



1.



DefaultProperties


2.



{


3.



DefaultFOV=90.f


4.



}


复制代码





/************** ************************************************** *


*


* UpdateViewTarget()


方法介绍



*


*


这个类继承了基类的


Camera


摄像机类


.


*




















GamePawn< /p>






GetDefaultCameraMode(


需要重载


)(ps.


其实


UE3


里< /p>


,


没有虚函数


,


他们


extends



,


都属于重写


,


本身他就有这方法

,


可以进基类的


uc


文件看他怎么 写的


).


*


< br>果




















GamePawn



GetDefaultCameraMode


的方法


.


* /** Camera Mode */var Name CameraStyle;


* Camera


< p>



CameraStyle









过< /p>


GamePawn



GetDefaul tCameraMode


实现的。


(ps.

我觉得这个方法名用


Set


更合适,不过他


不是方法,是需要继承的,所以


Get


也没错


)


*







GamePa wn



(KWPawn)


< p>




Isometri c,




,






里,


找到


UpdateViewTarget


方 法,


将其复制过来


(


其实也可以不复制 ,


复制的好处是原始的摄像机模式保留


)


*



switch(


CameraStyle


)


的地方添 加对


Isometric


的处理(


Is ometric


随便


定义,不过你怎么


case


的就在你定义的


Pawn


里怎 么


Get


*


在这个类里可以设置



*


这是一个可以简单使用且有品质保证的摄像机类上的基本功能,增加或者说


是扩展了另一款同等级


GameCamera


的功能



******************************* **********************************/




我大概说下我的自定义视角里面的代码含义。




首先是


Rot

在这里我们固定摄像机角度进一个或多或少等角的固定角度之内。


(Pitch Roll


Yaw


你可以理解为三个面的旋转方式,就类似


UDK


里面的旋转三跟线)




然后是


Loc

在这里我们定义一个默认的摄像机位置距离


Pawn(


我们 的角色


)


的位置。




最后是


Pos = Loc



Vector(Rot) * FreeCamDistance;


它做的是以现在的摄像机旋转作为方向矢量然后借着


FreeCamDistance


来加


大。



FreeCamDistance


在父类定义中默认值是


256.0 f





最后,


当我们按下


F5


进行调 试,


就可以发现我们可以通过键盘的


WSAD

< br>键来控制


角色进行行走了,并且已经固定为斜


45


度角了。



如果你想修改你的视角,那么对< /p>


'Isometric'


里的代码进行修改。


如果你想添加多种视角,那么添加这里的


case


进行处理,然后在继承了


Pawn


类的


KWPawn


类里控制


GetDefault CameraMode


的返回值来进行完成。






总结:



我们已经通过修改完成了使用 自己的视角来进行游戏,


在下一章节中,


我们将重


写我们的控制方法,使用鼠标来进行角色的移动。并且初步谈谈关于


HUD< /p>


(界面


渲染)。










在前面 的教程中,我们已经把我们创建的角色放入置我们的场景之中了。


现在,我们将重写我们的控制方式,使用我们自定义的方式来控制我们的角色。




第一步:



我们先把制作好的鼠标指针模型


(可以参考其他教程或者等待其他人更新模型制


作教程,


在此系列就不涉及大部分


UDK


编辑器



部分的操作,


本系列留给程序员)


放入


KingdomWorldUTGa meContentEffect


中。


(KingdomWor ld


UTGameContent


后的路径随便你定义,你直 接放在


Content


里也行,这样做的


目的仅仅是便于管理而已)



附带一个我随便制作的模型:




第二步:



2.1.

< br>打开工程。在


Classes


文件夹里添加一个


KWHud


类。并编写如下代码



1.



class KWHud extends GameHUD;


2.




3.



simulated event PostBeginPlay()


4.



{


5.



ginPlay();


6.



`Log(


界面类运行



7.

< p>


}


复制代码





我们编写了一个继承了界面类的的 类,


在这里我们可以在渲染事件里做一些东西


(比如

< p>
UI


,文字等)




2.2.


接着,我们添加一个方法



1.



function vector2D GetMouseCoordinates()


2.



{


3.



local Vector2D mousePos;


4.



local UIInteraction UIController;


5.



local GameUISceneClient GameSceneClient;


6.



UIController = ontroller();


7.



if ( UIController != None)


8.



{


9.



GameSceneClient = lient;


10. if ( GameSceneClient != None )


11. {


12. mousePos.X = osition.X;


13. mousePos.Y = osition.Y;


14. }


15. }


16. return mousePos;


17.}


复制代码





/************************************** ****************************


*


* GetMouseCoordinates()


方法介绍



*


*


这是我们自己定义的一个方法。



*


通过这个方法返回一个


vector2D


* vector2D


包含了我们鼠标在当前场景中的正确位置。



*


其实就是


ontroller().osition;


****************************************** ************************/



< /p>


通过这个方法,我们可以随时取得当前鼠标的位置(在后面用到)




第三步:



找到我们之前编写的



文件



声明如下变量



1.



var Vector2D PlayerMouse;


2.



var Vector MouseHitWorldLocation;


3.



var Vector MouseHitWorldNormal;


4.



var Vector MousePosWorldLocation;


5.



var Vector MousePosWorldNormal;


6.



var vector StartTrace;


7.



var Vector EndTrace;


8.



var vector RayDir;


9.



var Vector PawnEyeLocation;


Actor TraceActor;


复制代码







第四步:



4.1.


找到我们之前编写的



文件



声明如下变量



1.



var


FontRenderInfo TextRenderInfo; //


一个字体渲染类,



以控制他修改 字体



复制代码





4.2.


添加如下方法



1.



function DrawHUD()


2.



{


3.



//


定义一个字符串常量



4.



local string StringMessage;


5.




6.



//


显示我们控制类的当前鼠标位置指向的何种类对象



7.



//(TraceAct or



PostRender


方法中已 赋值


)


8.



if(KWPlayerController(PlayerOwner).TraceActor != none)


9.



{


10. //


将类名赋值给


StringMessage


11. //


在这里我们可以判断当前选中了何种类型的对象



12. //


对不同的对象可以做不同的响应处理



13. //


当然,如果鼠标点击到不同的对象,一样可以通过他取得。



14. //


以后的教程中我们将介绍如何渲染中文字体。



15. StringMessage =


Actor:


16. }


17.


18. //



StringMessage


的内容渲染进

x=250,y=10


的位置



19. lor = MakeColor(255,183,11,255);


20. ( 250, 10 );


21. xt( StringMessage, false, , , TextRenderInfo );


22.}


复制代码





/************** ************************************************** ***


* DrawHUD()


方法介绍



*


*


自定义渲染方法,我们在这里可以渲染一切我们像要的东西。



*************************************** ****************************/




4.3.


添加如下方法



1.



event PostRender()


2.



{


3.



local KWCamera PlayerCam;


4.



local KWPlayerController IsoPlayerController;


5.



nder();


6.



//


取得我们角色当前的控制类的指针



7.



IsoPlayerController = KWPlayerController(PlayerOwner);


8.



//


将我们定义的


GetMouseCoordinates


方法 的返回值保存进


PlayerMouse


变量中



9.



Mouse = GetMouseCoordinates();


10. //


这个方法可以在



类中找到。


这个方法的用途是传入一



2D


坐标获 得他在场景中的


3D


位置和方向。



11. ect(Mouse,


osWorldLocation,


osWorldNormal);


12. //


去的当前空指针的摄像机指针



13. PlayerCam = KWCamera(Camera);


14. //


设置


RayDir


为当前控制类的方向



15. =


osWorldNormal;


16. //

< p>
设置


StartTrace


为当前摄像机位置


+100(z



)


位置


+


控制类的方向


*10


17. race =


(on + vect(0,0,100)) +


* 10;


18. //


设置


EndTrace



StartTrace+


控制类的方向


*500 0(5000


是作为延伸,


够远了


)


19. ce = race


+ * 5000;


20. //


取得当前鼠标在场景中指向的对象。



21. //Trace


需要传入指针方向,起始位置和结束位置



22. //


之所以之前传个


*50 00



EndTrace


< p>
是为了鼠标指在模型上,


好判断



23. //


这个方法会返回一个


M ouseHitWorldLocation



也就是鼠标点击 的这


个对象的


3D


位置


(


我们暂时用不到他


)


24. //


在这里我们每帧都跟踪


MouseHitWorldLocation


的世界坐标



25. //(


这里你能追踪


Actor


对象



的碰撞


,


为了这个简单教程


,


我们 没有对


结果做任何改动


,


但如果你想过 滤掉对地形的点击



26. //,


或玩家点击


npc,


你可以检查


StartFire


函数里的对象碰撞,在那


边做处理


-


后面有说



27. ctor =


Trace(itWorldLocation,


itWorldNormal,


ce, race,


true);


28.


29. //


计算角色的视角位置为了调试光线和检查移动后的碰撞



30. eLocation =


Pawn(rget).Location +


Pawn(rget).EyeHeight * vect(0,0,1);


31. //


开始渲染我们的东西



32. DrawHUD();


33.}


复制代码





PostRender


是来自父类的方法,我们重写后,


nder();


了他,然后


我们才可以继续做 我们自己的事情,



这个方法作为渲染类,他每一帧都会执行一次。



在这里,我们主要是为了取得


TraceActor(


当前指针摸到的对象


)


,以及选择范



(StartTrace



EndT race)



第五步:


< p>
现在,


我们已经可以把鼠标当前摸到的对象以文字的形式通过


DrawHUD


渲染进屏


幕。



但是你要说了,我调试的时候看不到我的鼠标指针啊?



别急,在下一节,我们将会让你加载一个鼠标模型,方便调试。



楼外音:“我靠,你不会就跑了吧?”



当然不是,在这里,我介绍一个简单的办法来显示鼠标位置。



主要是因为这一节太多了,我相信你也得慢慢吸收,不适合一次性讲那么多。

< p>



好。废话少说,还记得我们之前在

< p>
PostRender


类里设置进控制类里的那些变量

吗?



我们不要浪费他们。




5.1.


首先,找到我们之前编写的



文件



声明如下变量



1.



var bool bDrawTraces; //


通过它控制是否显示鼠标

< p>
跟踪调试线。



复制代码





5.2.


添加一个方法来控制


bDra wTraces


它的值



1.



exec function ToggleIsometricDebug()


2.



{


3.



bDrawTraces = !bDrawTraces;


4.



if(bDrawTraces)


5.



{


6.



`Log(


显示鼠标跟踪调试线



7.



}


8.



else


9.



{


10. `Log(


不显示鼠标跟踪调 试线



11. }


12.}


复制代码





/************** ************************************************** **


* ToggleIsometricDebug()


方法介绍



*


*


创建一个控制台命令



*


使用这个命令会开启


bDrawTraces


开 关,在


PostRender


方法中



*



PostRender


方法中我们将会显示当前鼠标的路径。



*


通过他我们可以显示我们的角色一个正确的行走路径。



*


*


必须用


exec function


的声明方式



*


方法名可以任意取,你取啥名,在控制台就输啥命令



*


************************** ****************************************/



5.2.


添加一个方法来显示鼠标



1.



function DrawTraceDebugRays()


2.



{


3.



local KWPlayerController IsoPlayerController;


4.



IsoPlayerController = KWPlayerController(PlayerOwner);


5.




6.



//


绘画选择范围。



7.



//MakeCo lor


的参数为


R,G,B


以及透明通 道。



8.



Draw3DLine(race,


ce, MakeColor(255,128,128,255));


9.



//


绘画移动路线



10. Draw3DLine(eLocation,


itWorldLocation,


MakeColor(0,200,255,255));


11.}


复制代码





/************** ************************************************** ***


* DrawTraceDebugRays()


方法介绍



*


*


渲染显示鼠标跟踪调试线。



* < /p>


这个方法在


PostRender


中,通 过


bDrawTraces


作为开关调用。


************************************ *******************************/




5.3.



PostRender


方法中,找到


DrawHUD()


方法的调用地方,在后面添加如下


代码:



1.



if(bDrawTraces)


2.



{


3.



//


父类有这么一个玩意,可以显示寻路的线路。



4.



ute(Pawn(rget));


5.



DrawTraceDebugRays();


6.



}


复制代码








第六步:



现在,我们需要绑定这个< /p>


Hud


类。



6 .1.


首先,找到我们之前编写的



文件




DefaultProperti es


里添加


一行



1.



//


设置界面类



2.



HUDType=class''


复制代码





现在,你可以调试工程,通过控制 台输入


ToggleIsometricDebug(


你可以输 入


togglei


出现全部的命令后按


tab


再按回车


,


大小写随便


)



发现鼠标移动到的位置,屏幕上就会显示你选择的是何种对象。



楼外音:“楼主你最前面发的那个资源文件是干嘛的?我没看到地方调用啊”

< p>


嗯。。。那个。你也发现了,其实这是第六步,不是总结。


< /p>


细心的同学可能已经发现了,


那个最前面第一步发的资源其实是一 个鼠标指针的


资源。



那么,我们还是 说说怎么加载一个鼠标指针把,而不是用这两根线。




6.2.


打开工程。



Classes


文件夹里添加一个


MeshMouseCur sor


类。


并编写如下


代码

< p>


1.



class MeshMouseCursor extends Actor;


2.



var() StaticMeshComponent Mesh;


3.



DefaultProperties


4.



{


5.



Begin Object Class=StaticMeshComponent Name=MarkerMesh


6.



BlockActors=false


7.



CollideActors=true


8.



BlockRigidBody=false


9.



//


模型文件



10. StaticMesh=StaticMesh'0001mesh'


11. //


重置模型的大小


- 0.3




12. Scale3D=(X=0.3,Y=0.3,Z=0.3)


13. Rotation=(Pitch=-16384, Yaw=0, Roll=0)


14. End Object


15. Mesh=MarkerMesh


16. CollisionComponent=MarkerMesh


17. (MarkerMesh)


18.}


复制代码





你看到的没错,


StaticMesh'0001mesh'< /p>


这玩意就是我最前面提


供的文件里的资源路径名。



现在,我们已经创建了一个


Actor


对象(鼠标指针),如何把他应用到游戏中去





6.3.


找到我们之前编写的



文件



声明如下变量



1.



var MeshMouseCursor MouseCursor; //3D


鼠标指针



复制代码





6.4.



KWPlayerCont roller


类的


PostBeginPlay


方法中


ginPlay();


的后面添加如下代码:< /p>



1.



MouseCursor = Spawn(class'MeshMouseCursor', self, 'marker');


复制代码







6.5.


添加方法



1.



event PlayerTick( float DeltaTime )


2.



{


3.



Tick(DeltaTime);


4.



//


设置当前鼠标的位置为


KWHud



PostRender


方法取到的


MouseHitWorldLocation


5.



ation(MouseHitWorldLocation);


6.



}


复制代码





PlayerTick


是父类的一个方法,我们重载了它。



在这里,我们没必要去调用父类的


Tic k()


了。









PlayerTick



< p>








当然这些都要我们重新来做了,所以无需调用原本的过程了。




使用


MouseHitWorldL ocation


是因为我们让鼠标的位置呈现三维状态,


他一直 跟


着地表(或者物体)走。



当然,你 也可以设置它为一个


2D


位置。




这时候我们调试项目,


可以发现鼠标 的指针已经跟随着我们动了,


并且显示移动


到位置的对象名







楼外音:“这指针好丑啊,黑不拉几一陀”


< br>嗯。。。这位同学,这是代码教程。。。你也可以把他做成


2D

< br>的图片嘛,当然



3D


是为了教 程需要。



当然,


还记得我们自定义的


Pawn


类吗?你可以试着和


KWPa wn


一样,


添加一个灯


光给他。(本文 不做说明,自己动手才有乐趣嘛,当作本节作业)




总结:



这一节主要取得了我们走路需 要的一些关键数据,


并且简单介绍了渲染的方法和


如何区别不同 对象的处理。



在下一节中,我们将会使用我们自己做的这个鼠 标,来进行走路。











在前面的教程中,我们已经将我们的鼠标指针放入场景中了


< /p>


接下来,我们将全面接管引擎的输入。把他的控制方式交给我们来处理。

< br>



第一步:



首先我们把



添加进工程

< p>
(以添加为


链接方式,具体参考第一章第一节)



找到


[Input]


中的



Bindings=(Name=


Binding s=(Name=



这里我特别说明一下



里,引擎会通过 他,找到相应的映射控制方


法。



Na me=


为底层方法,这是一个鼠标滚轮移动事件。


< p>
Command=


后面这个为这个事件将会对应的控制台命令。

< p>



在这里,你可以找到一切你所需要的消息映射 ,比如键盘的按键,鼠标的。以及


Xbox 360


中按键的映射。




1.1.


首先我们修改



Bindings=(Name=


Bindings=(Name=


为如下代码:



1.



Bindings=(Name=


2.



Bindings=(Name=


复制代码




他原本的鼠标滚轮事件激活 了换武器的方法,当然


UTGame


目录下的代码已经给


我们删了,这个事件是不会被调用的。



但是 这个方法名不太好看,


会造成教程的歧义。


你可以修改成自己需 要的功能方


法名,为了教程通俗易懂,我们将方法名就直接改为事件名。




1.2.


建立好映射后, 我们需要实现这个方法的功能。



找到我们之前编写的



文件



添加如下方法:



1.



//


拉近镜头



2.



exec function MouseScrollUp()


3.



{


4.



`Log(


拉近镜头



5.



mDistance -= 64;


6.



}


7.




8.



//


拉远镜头



9.



exec function MouseScrollDown()


10.{


11. `Log(


拉远镜头



12. mDistance += 64;


13.}


复制代码





还记得我们摄像机类


KWCamera


里对我们的摄像机模式


Isometric


的处理吗?



//


设置缩放



Pos = Loc - Vector(Rot) * FreeCamDistance;



通过

MouseScrollUp



MouseScrollD own


方法,


我们可以修改摄像机的缩放位置。



64


个大小为单位(


UDK


里一个单位为


2


厘米)




现在我们可以调试工程,试试你的鼠标滚轮,是不 是可以缩放镜头了。






第二步:



打开



找到


[Input]


中的



Binding s=(Name=


Bindings=(Name=


修改为:< /p>



1.



Bindings=(Name=


2.



Bindings=(Name=


复制代码




Bindings=(Na me=


StopFire


Bindings=(Name=


StopAltFire


修改为:



1.



Bindings=(Name=


| OnRelease LeftMouseButtonUp


2.



Bindings=(Name=


wn | OnRelease RightMouseButtonUp


复制代码





这样做的目的是把


LeftMouseButton


的消息扩充消息,


因 为他有两个消息处理事


件,一个按下和松开的消息,用


|


分开,松开的定义为


OnRelease,


当然,你也可


以设置一个变量名来处理他,比如他之前的


But ton bFire


,在这里我们暂时用


不到,所以去掉了它。




Bindings=(Name=


Bindings=(Name=


StopAltFire



准确的说是鼠标右键绑定了


AltFire

< br>而


AltFire


有两个消息,一个是右键按下为


StartAltFire


,右键松开为


St opAltFire



希望你能看懂这部分的修改的含义。




因为


RightMouseButton


对应的消息有子消息,所以


Cmmand


不能直接为


RightMouseButton



否则他会去代码里寻找


exec function Righ tMouseButton


,而对应的子消息扩


展就会有问题。 所以加了一个


at



RightMou seButtonAt



不然有两个


R ightMouseButton


他不知道怎么映射了,要把


R ightMouseButton


对应的消息名分开



而之前的那个滚轮无所谓,因为滚轮没有扩展消息。




第三步:



3.1.


找到我们之前编写的



文件



声明如下变量:



1.



var bool bLeftMousePressed; //


判断是否按下鼠标


左键



2.



var bool bRightMousePressed; //


判断是否按下鼠标


右键



3.



var float DeltaTimeAccumulated; //


累计鼠标按下时间



复制代码





3.2.


修改


PlayerTick( )


方法




a tion(MouseHitWorldLocation);


后面增加如下代码:



1.



//


统 计左键按下去的时间,


如果你想用右键,


修改为


bRightMousePressed


2.



if(bLeftMousePressed)


3.



{


4.



//


累计鼠标按下去一共多久


.


5.



DeltaTimeAccumulated += DeltaTime;


6.



}


复制代码







3.3.


添加如下方法:



1.



//


按下鼠标左键



2.



exec function LeftMouseButtonDown()


3.



{


4.



MouseButtonDown(0);


5.



}


6.




7.



//


松开鼠标左键



8.



exec function LeftMouseButtonUp()


9.



{


10. MouseButtonUp(0);


11.}


12.


13.//


按下鼠标右键



function RightMouseButtonDown()


15.{


16. MouseButtonDown(1);


17.}


18.


19.//


松开鼠标右键



function RightMouseButtonUp()


21.{


22. MouseButtonUp(1);


23.}


24.


25.//


按下鼠标



on MouseButtonDown(byte MouseMode)


27.{


28. //


重置按下鼠标时间



29. DeltaTimeAccumulated = 0;


30.


31. //


判断按下了哪个键



32. bLeftMousePressed = MouseMode == 0;


33. bRightMousePressed = MouseMode == 1;


34. if(bLeftMousePressed) `Log(


按下了鼠标左键



35. if(bRightMousePressed) `Log(


按下了鼠标右键



36.}


37.


38.//


松开鼠标



on MouseButtonUp(byte MouseMode)


40.{


41. `Log(


总共按下的时间:



42. //


重置鼠标状态



43. if(bLeftMousePressed && MouseMode == 0)


44. {


45. bLeftMousePressed = false;


46. `Log(


松开了鼠标左键



47. }


48. if(bRightMousePressed && MouseMode == 1)


49. {


50. bRightMousePressed = false;


51. `Log(


松开了鼠标右键



52. }


53.


54. //


重置鼠标按下时间



55. DeltaTimeAccumulated = 0;


56.}


复制代码





现在,


我们可以调试一下游戏,


发现游 戏的日志窗口已经正确的捕获了我们鼠标


的左右键的功能。并且能够得到鼠标左键按下去 的时间。







第四步:



4.1.


找到我们之前编写的



文件



声明如下变量:



1.



//


计 算角色位置到


MouseHitWorldLocation


的 距离



2.



var float DistanceRemaining;


3.



//


表 明在可接受的范围目的地中,停止移动



4.



var bool bPawnNearDestination;


复制代码





4.2.


添加一个


state


方法。代码如下



1.



state MoveMouseClick


2.



{


3.



event PoppedState()


4.



{


5.



`Log(


通过鼠标停止移动,清除


StopLingering


计时器



6.



//


因为 通过鼠标停止了移动状态,所以要清除之前创建的计时器



7.



if(IsTimerActive(nameof(StopLingering)))


8.



{


9.



ClearTimer(nameof(StopLingering));


10. }


11. }


12. event PushedState()


13. {


14. //


创建一个计时器,规定角色最长只能走三秒



15. //


这段代码没什么含义,只是初步解释一 下计时器的创建,调用,


和删除



16. //


如果你需要它可以打开下面的注释



17. //SetTimer(3, false, nameof(StopLingering));


18. if (Pawn != None)


19. {


20. //


还记得我们没打开的

< p>
KWPawn



PhysicsAsset


吗?



21. //


这里控制了物理包,这里是控制角色的移动的骨骼动作。



22. ementPhysics();


23. }


24. }


:


26. while(!bPawnNearDestination)


27. {


28. //`Log(


移动中



29. MoveTo(GetDestinationPosition());


30. }


31. `Log(


已移动到目的地



32. PopState();


33.}


复制代码





//SetTimer(3, false, nameof(StopLingering));


这段代码我注释了,这里的意思是 说,创建一个


3


秒为单位的计时器。


3


秒后调



StopLingering



StopLingering


里,< /p>


我们将会停止角色的行走状态,


这里只是初步的介绍一下


计时器的用法。




4 .3.


添加


StopLingering


方法,代码如下:



1.



function StopLingering()


2.



{


3.



//


停止当前所有移动状态



4.



`Log(


已移动了


3


秒,停止移动


< /p>


5.



PopState(true);


6.



}


复制代码





另外我说下


ementPhysics();


我们可以选中


SetMovementPhysics


点击右键选择转到定义。



这个方法是引擎提供的一个播放行走骨骼动画方法。



他会判断你在水面上方还是下方,来播放


SetPhysics(PHY S_Swimming);


还是


SetPhysics(PHY S_Falling);



如果你有在按键要处理一些技能动作 ,


或者定义你自己的物理包骨骼动画名,


么,直接调用


sics(


你的东东


);




4.4.


MoveMouseClick


状态里的


Begin


标签里,我们使用了


MoveTo


进行行走。



引擎会回调一个

< br>PlayerMove


方法给我们,我们重载他,编写如下代码:



1.



function PlayerMove(float DeltaTime)


2.



{


3.



local Vector PawnXYLocation;


4.



local Vector DestinationXYLocation;


5.



local Vector Destination;


6.



local Vector2D DistanceCheck;


7.



Move(DeltaTime);


8.



//


获得玩家距离目的地的距离



9.



Destination = GetDestinationPosition();


10. DistanceCheck.X = Destination.X - on.X;


11. DistanceCheck.Y = Destination.Y - on.Y;


12. DistanceRemaining = Sqrt((DistanceCheck.X*DistanceCheck.X) +


(DistanceCheck.Y*DistanceCheck.Y));


13.


14. //`Log(


当前位置:



15. //`Log(


距离位置:



16.


17. bPawnNearDestination = DistanceRemaining < 15.0f;


18. `Log(


是否即将靠近目的地:



19. PawnXYLocation.X = on.X;


20. PawnXYLocation.Y = on.Y;


21. DestinationXYLocation.X = GetDestinationPosition().X;


22. DestinationXYLocation.Y = GetDestinationPosition().Y;


23. ation(Rotator(DestinationXYLocation -


PawnXYLocation));


24.}


复制代码





第五步:



5.1.

< br>现在,我们来添加一个方法,提供一个激活我们的


MoveMouseClick


事件的


方法。代码如下:



1.



function MovePawnToDestination()


2.



{


3.



`Log(


开始移动



4.



SetDestinationPosition(MouseHitWorldLocation);


5.



PushState('MoveMouseClick');


6.



}


复制代码





5.2.


在我们鼠标左键点击的时候,调用这个方法,我们的角 色即会行走了。



修改


MouseBu ttonDown


方法为如下代码:



1.



//


按下鼠标



2.



function MouseButtonDown(byte MouseMode)


3.



{


4.



//


停止当前所有移动状态



5.



PopState(true);


6.




7.



//


重置按下鼠标时间



8.



DeltaTimeAccumulated = 0;


9.



//


使用鼠标左键走路



10. //


在里面可以通过


TraceActor

来判断点到了啥



11. //

比如点到


npc


或者其他东西不同相应的来处理

< p>


12. if(MouseMode==0)


13. {


14. //


是否移动范围在可视范围之类



15. if(FastTrace(MouseHitWorldLocation, PawnEyeLocation,,


true))


16. {


17. //


移动到点击位置



18. MovePawnToDestination();


19. }


20. else


21. {


22. //


寻路



23. }


24. }


25. //


初始化为


false,


我们可以至少运行一次状态帧和重新计算距离



26. bPawnNearDestination = false;


27. //


判断按下了哪个键



28. bLeftMousePressed = MouseMode == 0;


29. bRightMousePressed = MouseMode == 1;


30. if(bLeftMousePressed) `Log(


按下了鼠标左键



31. if(bRightMousePressed) `Log(


按下了鼠标右键



32.}


复制代码





另外,



MouseButtonUp


中,


我们可以加上


if(


DeltaTimeAccumulated


>


0.13f)


PopState(true);



通过它来判断是否是长按键,你如果想松开鼠标就停止移动< /p>


,


就加上他


,


附 件的



包的代码里有注解。正文不做解释。




总结:



通过调试,


我们的角色已经可以被我们的鼠标所控制了,


细心 的同学可能会发现,


寻路的那部分我注释了没写,难道没问题吗?



这是因为我们的


1001


地图没有 障碍物


(



).


在后面的两节中,


我们主要说明如何


通过按住鼠标不动让角色 跟随我们行动,


以及如何使用虚幻引擎的寻路系统来穿


越障碍物



(ps:


本文花了我一天的时间构思 ,


到下午的时候卡壳了,


不知道怎么继续下去了,


很多地方不知道怎么解释,


不过我的注释写的很清楚了,

还不明白的同学可以先


下载源代码看看吧,不懂的可以再这里跟帖

< br>)










英文地址



/Three/



动画系统概述



?



概述



o



管道



o



工作流程



o



带动画的网格物体



?



动画混合



o



混合树概述



o



构建混合树



?



AnimTree(


动画树


)


节点



?



混合节点



?



动画播放



o



AnimSequence(


动画序列


)



o



AnimSet(


动画集


)



?



骨骼到轨迹的映射



o



AdditiveAnimati on(


叠加型动画


)



o



AnimNodeSequenc e(


动画节点序列


)



?



AnimNodeSequenc e


属性



?



AnimGroups(


动画组


)



?



同步



?



通知



?



组可以进行播放速度控制



设置



?



内部实现



o



根骨骼运动



?



骨骼控制器



?



物理动画



?



有用的控制台命令



?



概述



虚幻引擎动画系统为渲染的网格物体和实体添加运动效果。


带动 画的物体被称为



Skeletal


Meshes(


骨架网格物体


)



。和



Static


Meshes(


静态网格物体


)



(


它只能


通过

Matinee


进行动画


)


不同, 骨架网格物体使用一组骨骼组成一个



skeleton(


骨架


)



。这些骨 骼用于驱动物体的运动及在网格物体上物体的放置位


置。



动画系统有两个主要部分





关键帧动画数据的播放,和动画混合。




管道



动 画系统是虚幻引擎传递途径的一部分。首先,处理一般的动画


(


混合的动画


)



然后应用骨骼控制器< /p>


(


比如


Inverse


Kinematic)


。接下来是为骨架设置物理。然


后物理子系统处理剩余的物理,最后图形子系统渲染所有的物体。






工作流程



一般,

< br>程序员和动画制作人员一同工作来制作所需要的动画内容。


动画制作人员


将设置一个骨架并根据一个达成一致的惯例来为骨骼添加标签。


程序员将 基于管



(


类、函数、标记等


)


把所有的这些结合在一起。




带动画的网格物体



在虚幻引擎中,带动画的网格物体称为



Skeletal Meshes(


骨架网格物体


)



,因


为基于骨骼的骨架动画是用于驱动游戏中物体的动画的主要机制 。


以前,


也有基


于顶点的动画。




动画混合



虚幻引擎


3


使用


'


混合树


'


的观念来把多个动画数据 源混合到一起。


这个方法允许


您简单明了地创建一种多个动画混 合到一起的方式,


并允许您在处理的过程中很


容易地以可预测的 方式来添加更多的动画。




混合树概述



这是一个简单的动画混合树:





树是由一些树节点组成。节点主要有两类:



Blend Nodes(


混合节点


)


(



这些节点有一组子节点,并以某种方式把它们混合


)


到一起。



Data Nodes(


数据节点


)


(



是树的叶子节点,没有子节点但实际上可以生成骨


)


架变换。





在这个例子中,


'Directional

< br>Blend'


节点将会基于


actors


的速度和方向来把连


接到它们的定向动画混合到一起。


这将会产生一个定向行走及跑动的动画。


然后


这些节点插入一个


'Speed-based'


中,


它 将把两个子节点基于


Actor


的速度混合

到一起。最后再将它和


Fire


混合为

'Firing-based


Blend'



基于几种简单在引


擎中定义的基本混合模式来创建特定的混合类型是非常容易的。< /p>



构建混合树



动画树可以使用


AnimTree(


动画树

)


编辑器进行构建,


它是虚幻编辑器的一部分。

< p>
您可以使用通用浏览器创建一个新的


AnimTree(

< br>动画树


)


,然后双击它,便可以


打开


AnimTree(


动画树


)


编辑器,并看到一颗新的空的树。



< /p>


然后您可以在


SkeletalMeshComponent



defaultproperties(


默认属性


)


块中告


诉它使用您的


AnimTree(


动画树


)





defaultproperties


{


Begin Object Class=SkeletalMeshComponent Name=SkeletalMeshComponent


SkeletalMesh=SkeletalMesh'rMesh'


AnimSets(0)=AnimSet'rAnims'


AnimTreeTemplate=AnimTree'rAnimTree'


End Object


}




AnimTree(


动画树


)


分配给


AnimTreeTemplate(


动画树模板


)


是非常重要的,而


不是分配给


Animations(


动画

< p>
)


。当动画播



放开始时 ,将复制


AnimTreeTemplate(


动画树模板


)


引用的


AnimTree(


动画树


)


,然后把这个实例分


配给


Animations(



< /p>



)


,这个实例是游戏播放中真正使用的 ,因为它包含着实


际的状态。




AnimTree(


动画树


)


节点



AnimTree(


动画树


)


节点是建立一个新的


Anim Tree(


动画树


)


时默认存在的节点 。


这是您连接


Animations(


动画


)



Blend


Nodes(


混合节点


)


及< /p>


Morph


Nodes(


顶点变


形节点


)


的地方。您也可以在这里设置一些重 要属性。




Blend Node s(


混合节点


)


AnimSequences (


动画序列


)


将会产生最终的动画。下


一步是应用骨骼控制器。


这 个工作是以单个步骤完成的,


因此骨骼的顺序很重要。


让我们设 想一下以下的情境:人物使用


IK


来移动手臂,使用程序控制 器来处理


手臂的关节。您将会想先使


IK


完成动作,然后关节完成动作,这样它可以产生


最终的姿势。为了解决这个问题,骨架 可以在三



次渲染中进行排列。


< /p>


首先组成的骨骼


(


及它们的子节点


)


一般是


IK Bone


ComposePrePassBoneNames


链。



最后组成的骨骼


(


及它们的子节点


)


一般是< /p>


roll


ComposePostPassBoneNames


bones(


关节


)

< br>。





混合节点



请参照

< br>动画节点


页面来获得关于虚幻引擎中的默认动画节点的更多信息。




动画播放



AnimSequence(


动画序列


)



一个


AnimSequence(


动画序列


)


是一个单独的动画,它是一个关键帧 集合,包含


着许多相关的元数据信息,比如


notifies(


通知


)





AnimSet(


动画集

< p>
)



一个


AnimSet (


动画集


)


是一个

AnimSequences(


动画序列


)


的集合。它们存在于包


中,并且可以像材质、网格物体等以同样的方式在通用浏 览器中进行查看。




< p>
在一个动画集中的所有


AnimSequences(

动画系列


)


必须具有同样数量的轨迹,


且这些轨迹必须指向相同的骨骼。


这些应该当您在


AnimSetViewer(


动画集


)


查看


器中导入一个


PSA

< br>文件时为您进行处理。



骨骼到轨迹的映射




AnimSet(


动画集


)


中的轨迹是通过名称和骨架网格物体中的骨骼相关联的。



是因 为您或许会想在骨骼数量和顺序不同的骨架网格物体上播放同样的动画



集。


要想快速地查找存储着一组


AnimSetMes hLinkup


结构的动画集。


这些是特定

网格物体上的骨骼和


AnimSet(


动画集


)


的轨迹之间的映射



表。




A dditiveAnimation(


叠加型动画


)

< p>


默认情况下,


AnimSequences(


动画序列


)


存储着全部的骨架动画。但 是它也可以


构建并使用叠加型动画。叠加型动画通过在


Anim Set(


动画



)


编辑器中对两个


动画相减来进行构建。然后动画树再使用 几个节点把这个叠加型动画添加回去。



Additive A nimation(


叠加型


)


动画通过 去掉冗余数据从而可以作为一种压缩方


式。


(

< br>比如:放松的走步和瞄准的走步,取出这两种走步,仅保存放松走步和瞄


准走



步的不同作为一个附加部分


)

< p>


尽管是一个进行操作的小技巧,


但它可以在


很大程度上降低所使用的动画的数量并降低所使用的内存空间。




尽管动画集查看器中动画靠它本身便可以达到很好的效果,< /p>


但是在游戏中它需要


被添加到一个基础姿势中,从而看上去更加形 象。



您可以通过使用


AnimNod eAdditiveBlending


节点或者仅通过在一个


A nimNodeSlot (


动画节点元


)


上根据需求播放它们来添加叠加型动画。




自从


2009



12


月份的


QA

< br>版本开始,


Additive(


叠加

)



Target(


目标


)



Base(




)


动画都保持着彼此间的引用。


在不同的动画集中



移动这些动画并维持这些引



(


但不是包


)


是安全的。当导入一个


Target(


目标


)



Base(


基础


)


姿势的更新版


本时,编 辑器将会提醒用户来重新编译相



应的叠加型动画。




如果您想更新现有数据并创建这些引用,您可以运行


FixAdditiveR eferences


命令开关。




AnimNodeSequence(


动画节点序列

< p>
)



这是


AnimNo de(


动画节点


)


的子类,它知道怎样 播放存储在


AnimSets(


动画集


)



的关键帧数据。它一般组成您的混合树的叶子节点。



您想要播放的动画序列可以通过在


Anim NodeSequence(


动画节点序列


)

< br>中的名称


来指定。为了找到那个


AnimSequenc e(


动画序列


)



它将会查找


SkeletalMeshComponen t


中的整个


AnimSets(


动画集


)


数组。


通过名称引用动画序


列而不是通过指针进行引用的优点是:



它允许 您为完全不同的网格物体


/


动画使


用相 同的树。当搜索整个


AnimSets


数组时,它将从末端开始 并向前查找,直到


找到具有那个名称的


AnimSequen ce



AnimSet


。这允许您在数 组中通过添加一


个新的具有同样名称动画序列的


AnimSet


来覆盖特定的序列。



< p>
AnimNodeSequence


属性



如果动画当前正在播放时,设置这项。如果


bPlaying (


播放


)


当前动画暂停时,不设置这项。



如果动画应该循环并永远播放时设置这项


bLooping (


循环


)


为真。



Rate(


速度


)


播放速度



bNoNotifies(


是否没有通知


)


如果设置这项,则不会触发动画通知。



bShowTimeLineSlider(


是否显示时


切换 拖动条来控制时间的位置。



间轴滑块


)




AnimGroups(


动画组


)



当组织很多不同的动画到一起时,


便需要在较高的层次上快速地组织和管理这些


动画。为了解决这个问 题,动画系统使用了


AnimGroups(


动画组

< p>
)


的概念。




通过使用


AnimGroups


,使得同步一 系列节点到一起、仅使组中最重要的节点触


发通知、


及全局地调 整所有这些节点的播放速度成为可能。


它也可以是这些选项


的组 合,不是所有的节点都需要同步。




同步



这个过程在使用一个称为


AnimNodeSynch


的特殊节点前完成。

< br>这个操作自从被集


成到


AnimGroup


系统中时便已经存在。所以我们鼓励移除


AnimNodeSynch





动画同步背 后的原理是可以把不同长度的动画同步到一起。


这是非常有用的,



如,


对于运动循环。


在走动和跑动 间的无缝转换。


这个主意是为了使动画相对同


步。



比如,在整个运动循环中,左脚下降为


0%


,右脚下降为


50%


。现在,如果

< p>
我们保持走步和跑动循环相对地同步到一起,


我们便可以根据任务的速度和 任何


走步循



环的无缝变换来改变每个循环的播放速度。双脚将会被同步。




通知



当 在相似的动画间进行变换时,


也存在一个处理通知的问题。


比如 ,


具有运动动


画的脚步。


当在不同循环 间变换并使用基于权重界线的系统来触发通知时,


您可


能会



以根本没有触发任何通知的情况告终


(< /p>


或者有时候,可以一次触发几个通



)< /p>


。我们真正想要的是一个组中最重要的动画来负责触发通知,这也正事


AnimGroups


所做的工作。




组可以进行播放速度控制



最终,


AnimGroups


也允许在组的层 次上控制动画的播放速度。注意这是除了每


个动画节点速率之外的操作。所以动画节点可 以有不同的


/


各种各样的速度,而


组速 度将在它们独立的播放速率之上来缩放那个组中所有动画节点的速率。




设置



为 了创建一个组,请选择


AnimTree


节点

< br>(


混合树的根节点


)


。展开


AnimGroups



并添加一个新项, 在



组名


)


属性 中为您的组输入您想使用的名称。


RateScale


属性是用 于缩放这个组的全局播放速度。




然后,选择您想添加到这个组中的


AnimNodeSequence

< br>节点。展开它的


Group



分 ,您将会看到以下属性:



bForceAlwaysSlave


节点将会被同步,但是永远不会被选择为主要节点。



默认为真,节点将会被同步。如果您不想同步这个节点,请


bSynch ronize


不要选中此项。



这个节点所属于的组的名称。设置它为和您在


AnimTree


SynchGroupName


AnimGroups


数组中创建的组名称一样的组。



如果 所创建动画不是和其它动画


(


左脚、反向的右脚


)


进行相


SynchPosOffset

< p>
对地同步,那么通过偏移动画来使它匹配是可能的。


Offset


(


偏移


)


是一个相对 位置,从


0.f



1.f






内部实现



分组系统,


当所有的节点被实时计算后,


在第二次中它将会强制更新组中所有的


节点。


所以在混合树中的所有节点都具有最新的权重。

< br>然后每个组将会寻找两个


主要



节点。一个用于同步,另一个用于通知。要使用


2


个主要节点的 原因是不


是所有的节点都需要被同步,


并且也不是所有的节点都 需要触发通知。


所以在每


个种类中的



主要节点都是最相关的节点


(


在树中具 有最高权重的节点,


可以活着


被同步活着触发通知


)



一旦选择了主要节点,


那么所有的组节点都是补充资料,


需要同步的节



点是,需要触发通知的节点也是。





AnimTree


中有几个有用的脚 本函数用于从脚本代码中控制组。添加


/


删除节


点、控制同步位置、播放速度缩放等。




根骨骼运动



请参照


根骨骼运动


页面。




骨骼控制器



当动画已经被提取出来 并混合到一起后,便可以应用骨骼控制器,比如


IK(


逆向


运动学


)


。请查看


SkeletalControllers(


骨架控制器


)


页面来获得关于这个步骤


以及您可以使用的节点类型的更多信息


使用骨架控制器





物理动画



关于结合物理和动画的更多信息,请参照


物理动画


页面。




有用的控制台命令



show bones


-


显示用于渲染骨架网格物体的骨骼的位置。












虚幻引擎中的包



?



?



?



?



?



?



?



?



?



简介



包类型





命名



组织结构



限制



管理



加载



创建新的包类型


(


写给编程人员


)



简介




虚幻引擎中





的概念是一个包含一些可以通过虚 幻引擎进行操作和访问的二


进制数据的文件。




内容包含有各种类型的游戏资源。


这 些资源包括贴图、


静态网格物体、


骨架网格

物体、物理资源、


UI


Scenes

等等!任何添加到游戏引擎中的东西都可以放入到


一个包中。


使用虚幻编辑器中的


内容浏览器



您 可以把资源导入到包中,


到处移


动资源、重命名资源以及再次把 最终的包导出等等。




关卡是作为 一种特殊类型的包出现的。


关卡一般不包含资源。


相反,


它包含着到


包文件内的资源的引用。


这允许多 个关卡来共享资源,


并允许美术工作人员仅需


将包



文件中的资源改变一次,所有引用该资源的关卡将会自动地进行更新。把< /p>


资源直接插入到您的关卡文件中是可能的;


但是一般不建议这样操 作,


因为它会


加大您关卡


< p>
文件的大小,同时也消除了其它关卡可以共享那个资源的可能性。


关卡也可 以充分地利用在


UnrealScript


类中定义的


Actors




< /p>


UnrealScript


类被编译为单独的包。


UnrealScript


包也可以包含到内容及关卡


包中的引用。





包类型




包可以有不同的扩展名,


但是它们在内部是完全一致的。


虚幻引 擎只关心包中的


内容,


而不包含任何处理特定扩展名的特殊情况 。


然而,


有一个大多数授权用户


都会遵 守的通用习惯:



扩展


包含内容





编译过的


UnrealScript


代码。这些文件由


UCC

< p>
编译器生成,它们不包含


U


任何资源;仅包含引用。



关卡的默认 扩展名;包含着在编译后的脚本包中定义的


Actors


和存储在


UDK


内容包中的资源。



UPK


是包含着各种资源的内容包的通用扩展名。




授权用户可以在授权用户文件扩展名


?


页面注册唯一的关卡扩展名。







< /p>


包可以包含多层的组。


可以把它们想象成您硬盘上文件结构中的子 目录。


这些组


的使用完全是为了使人们可以搞清包内容的意思;


引擎不会关心您是否使用这些


组。


< /p>


虚幻引擎支持多层次的组结构;但是,尽管您可以按照您的意愿设计组层

< br>次的深度,


但通常推荐最多建立


3



4


层。


否则,

当使用内容浏览器包的树结构


时,它将会



变得特别不实用。以下是使用多个组来组织装甲资源的例子:





这个例子中的包是



Pickups



(


可能在硬盘的





包中


)



在那个包内可


能有很多组用于组织它内部 的资源。


比如,


假设这个选中的像,


获 得指定资源的


路径将




als



。这


类似于


访问


您的硬


< br>(


也就


是:


。每个组都可以包含资源,就像那个任何目录


可以包含文件一样。

< br>




命名




当 命名您的资源和包时,


我们强烈推荐您为它们使用唯一的名称。


把多个东西命


名为同一个名称有时会导致引擎不能精确地决定您所要加载或者引用的资源 ,



而可



找 到了一个错误资源。这样导致的一些难以发现的问题,并且这些问题很


难调试解决。



所以只要直接彻底地避免这样的问题,


为 您的



资源


/



< /p>


进行唯一


的命名。已经说过,组的名称可以是您想象的任何东西。 它们不需要是唯一的,


因为它们永远不会被直接地引用或搜索。





组织结构




内容包一般存储在您的软件版本的


C ontent(


内容


)


目录内。


它们可以包含代表各


种类型内容比如贴图或


U I


Scenes


的子目录。再次说明,这仅是为了更有利于人


类的可读性和可维护性。



关卡包存储 在您的软件版本中的


Maps


目录中。



编译完成的


UnrealScript


包存储在您的软件的


Scripts(


脚本

)


目录中。



限制



对于一个包文件中可以出现的 资源的数量没有限制,


但是对于整个包的大小的限


制为


2GB



超出这个限制将会导致包不能在某些平 台上加载。


如果包已经接近


2G


的一半 ,


那么尝试把包中的各个部分抽出来并分为多个较小的包是一种明智的做


法。






管理



另 外,


如果包中包含着不同团队人员使用的各种类型的内容,


那么 包可能会变得


很大。这样在


Source Control(< /p>


代码控制


)


中为了存储每个修订本将会创 建一个


非常大的文件拷贝。


为了避免这些问题,


可以考虑一个策略:


您扫描查看您所拥


有的一组包文件 ,



并识别出大于


200-300 < /p>


megs


的包。取出这些较大的包,并把


它们分裂开为较小的包。这可以在磁盘应用方面提供很多帮助。




烘焙将会做很多工作,


来把所有需要 的数据



组合




seek-free(


不用寻道


)


的包


中。另外,当只有较少的内容循环的时候,稍后仅在设备循环中 把包结



合回较


大的包中是非常容易的 。


为了完成这个工作,


简单地把来自一个包中的资源重命


名为另一个。


这将会创建一个指向新位置的重定向物体。


您不能删除旧的


(





)


包,


直到您已 经运行了


FixupRedirects


命令行开关来把所有 到旧的内容位置的


引用重新映射指向新的位置为止。






加载





Native




便








以< /p>




native

C++



(




defaultproperties)


的任何数据都可以在运行代码时被应用。有一些类定义在


C++


和脚本中,它们需要保持同步。




包加载是一个非常复杂的系统,


事实上大多数授权用户都不需要在底层上对其 进


行处理。




Exports (


导出


)


是存在于包中的物体。




Imports(


导入


)


是到其它包中的物体的引用。



< /p>


所以,如果您在包A中有一个材质


MatX


,并且它引用包


A


中的


TexY


和包


B


中的


Tex Z


,那么您将会有:






A:


Exports:


MatX


TexY


Imports:





B:


Exports:


TexZ







native




包< /p>









< p>



EditPackages




PackagesToBeFullyLoadedAtStartup


关键字中的包及它们的所有引用。




当您加载一个包


(


编辑器或游戏


)


,它将会从其它包中加载物体来解决所有的引


用。


它将



不会



加载被引用包中的所有物体。< /p>


它仅从其它包中加载所需的少量物


体。




在编辑器中,


内容浏览器中所列出的 呈现为灰色的包进加载了一部分资源,


因为


它们是由于加载其它 包而加载的。


您可以右击这个包来完全加载它。


每次您启动


编辑器将会自动扫描您的游戏的内容目录来获得包。


任何找到的包将 会显示在内


容浏览器的包的树结构中。




通过点击内容浏览器左下角的文件夹图标,您可以加载外部包


(


不是在引擎的搜


索路径之内能找到的 包


)


。然而,我们强烈推荐您不要在关卡中引用外部包或者


其它包的任何资源,因为这些资源在运行游戏或者命令开关时不能找到。









?



虚幻引擎


EXEC


命令



o



概览



?



在游戏中的按键设置




通用




渲染控制




分析


/


优化




游戏设置




调试



o



命令列表



?



?



?



?



?



概览



Exec


的命令是基于字符串的命令,


您可以在游戏或编辑器中运行。


他们也被称为控制台命令



,因为它们通常在一个控制台窗口中运


行。



要在游戏中执行命令,按


Tab


或< /p>


?


,弹出控制台,键入命令,然


后按


Enter


。这些命令不区分大小写。



要在编辑器中执行命令,


可在主编辑器窗口的左下方文本框中,



在通用浏览器的日志选项卡底部的文本框中输入命令。




在游戏中的按键设置



在某些情况下 ,


EXEC


命令可以绑定到配置文件里的输入键。



输入是通过不同的


C++ exec()


实现的,通常用



ULocalPlayer::Exec()


开始。





命令列表



通用



open mapname -


打开指定名称的地图(不加地图扩展名)。




openmenu scenename -


打开指定名称的场景并显示


( UIScene'' ).


注意



:如果场景名不正确,请 尝试用



(包括引号)




setbind


keyname


command


-


将指定的按键名 绑定到给定的控制台


命令。




shot -


根据屏幕的分辨率(或窗口分辨率,如果游戏在 窗口模式


下运行)截图。




tiledshot resolutionscale pixeloverlap - A high resolution


is screenshot is taken at the given scale of the current


resolution, with a pixel overlap for each tile.


指定比例的高分辨率截图。




togglescreenshotmode -


截屏时显示或隐藏用户界面。





渲染控制



FREEZERENDERING - This will freeze/unfreeze the set of


rendered actors.


当你第一次冻结,系统会记住当前渲染对象。然后,当你解冻时,


只有这些对象将被渲染。


所以,


你可以跑来 跑去,


打开线框模式等,


您将只能看到被冻结的对象。



注:在编辑器中,只会冻结透视图。




FREEZESTREAMING - This will freeze/unfreeze the level


streaming and visibility.


当您解冻,本应被加载的关卡将继续加载。



Note that this does nothing in the editor viewports, as it


already has the Level Streaming Previs button (and simply


turning


off


the


Previs


will


leave


the


visible


levels


alone).



FREEZEALL -


同时执行


F REEZERENDERING



FREEZESTREAMI NG





RECOMPILESHADERS -


重新编译着色。




TOGGLEBPCF - Switches between Uniform PCF and Branching PCF


shadow projection implementations.




游戏



addbots numbots -


添加指定数目的机器人到当前关卡



summon -


添加一个角色



giveweapon -


给玩家一特定的武器



god



god mode :


无敌



loaded




所有武器和弹药



fly




空中飞行



ghost




穿墙飞



walk




飞行时用该指令恢复正常




调试



set class property value -


设置类的属性值


-


设置指定的类的


所有实例的属性为以特定值。



getall


class


property


-


输出指定类的 所有实例的属性值到控制


台和日志。



getallstate


class


-


输出指定类的所有实例的状态到控制台和日


志。



displayall / displayallstate -


同为“getall”,但在屏幕上

< p>
实时输出,类似


stats



display object property -


显示指定的单个对象的属性。



displayclear -


清除所有输出。









简介



?



使用材质表达式



o



打开材质编辑器



?



材质编辑器概述



o



材质编辑器布局



o



菜单条



?



窗口



o



工具栏



?



预览面板



o



属性面板



?



材质



?



应用



?



材质实例



?



对象



o



材质表达式面板



o



材质表达式图表面板



o



控制



?



鼠标控制



?



键盘控制



?



热键



?



使用材质进行工作



o



表达式注释



o



表达式预览



?



材质参考



o



Material Properties (


材质属性


)



?



PhysMaterial (


物理材质


)



?



OpacityMaskClip Value(


不透明蒙板剪切值


)



?



BlendMode(

< p>
混合模式


)



?



光照模型



?



TwoSided(


双面


)



?



线框



?



半透明



?



bDisableDepthTe st(


禁用深度测试


)



?



bAllowFog(

< p>
允许雾


)



?



bUseOneLayerDis tortion(


使用一个层变形


)



?



FallbackMateria l(


后备材质


)



o



应用



?



bUsedAsLightFun ction(


是否用作为光照函数


)



?



bUsedAsSpecialEngineMaterial



?



bUsedWithSkelet alMesh(


是否和骨架网格物体一同使用


)



?



bUsedWith ParticleSystem(


是否和粒子系统一同使用


)< /p>



o



要想打开材质编辑器,可以在


Generic


Browser(


通用浏览器


)


中双


击一个材质。编辑器被分为


5


个 部分,如下所示:



菜单条和工具


可视化和导航工具





2



预览面板



在静态网格物体上的预览材质。



3



属性面板



材质或选中的材质表达式节点的属性。



材质表达式列


4



一系列可用的材质表达式。





材质表达式图

材质表达式在这个面板中连接在一起来创建着色


5





器指令。



1






菜单条




Properties(


属性


):



显示属性面板。


Preview(


预览


):



显示预览面板。



Material Expressions(


材质表达式


):


显示材质表达式图表。





工具栏




以下是关于工具栏中每个按钮的描述,


正如它们在工具条中出现 的


顺序一样从左到右开始介绍。



?




图标




描述






移动材 质表达式,使基础



材质节点出现在主要面板

< br>位


的左上角。







切换在材质预览面板中的



背景网格。







选择标准的形状用于预览


< br>您的材质。








从当前加载的静态网 格物



体下拉列表中选择一个用




于预览的网格物体。







使








在通用浏览器中 选中一个



静态网格物体,并按下这



个按钮来使选中的网格物



体作为预览 网格物体。












-


-


-


-


-


-


-


-



本文更新与2021-03-01 02:07,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/685161.html

udk教程的相关文章