Unity3dFPS游戏教程2.docx
《Unity3dFPS游戏教程2.docx》由会员分享,可在线阅读,更多相关《Unity3dFPS游戏教程2.docx(41页珍藏版)》请在冰豆网上搜索。
Unity3dFPS游戏教程2
FPS游戏教程2
Part2:
Enhancements第二部分增强
Thisintermediate-leveltutorialextendsupontheBasicFPStutorialbyintroducinggameelementssuchasmultipleweapons,damageandenemies.
这个中级教程是FPS基本教程的扩展,介绍游戏元素例如多种武器、毁伤和敌人。
Prerequisites
ThistutorialassumesthatyouarefamiliarwiththeUnityinterfaceandbasicscripting
concepts.Additionally,youshouldalreadybefamiliarwiththeconceptsdiscussedin
Part1oftheFPStutorialseries.
这个指南已经默认了你已经熟悉了Unity界面和基本的脚本概念。
你已经熟悉了第一部分的FPS概念的讨论。
Beforewebegin-levelsetup
在我们开始层面设置之前
DownloadFPS_Tutorial.zip,unzip,andopentheprojectfolderinUnity.Ifyou
havecompletedPart1,thenunzipthefilestoanewfolder.
下载FPS_Tutorial.zip解压缩并且在U你体验中打开项目,如果你有已完成的第一部分,这时解压缩它们到一个新的目录。
ImporttheStandardAssetsUnityPackage.
导入StandardAssets标准资源包
AddthemainLevelMeshandFPScontrollerprefabtothescene.
增加mainLevelMesh和FPS控制预制物体到场景中。
NOTEInthistutorialnonewscriptsneedtocreated.We’llbeusingtheonesthat
weredownloadedfromtheUnityPackage.
注意在这个指南中没有新的脚本需要建立,我们将使用下载的Unity软件包中的一些东西。
Weaponswitching武器开关
Beforewediscusshowtocreateeachindividualweapon,weneedtowritesomecodetomanagehowtheweaponsareinitializedandswitchedfromonetoanother.Let’slookattheJavascriptforPlayerWeapons.js:
在我们讨论如何建立每一个个体的武器之前,我们需要写一些代码以便管理这些武器怎么被初始化并且能被另一个(武器)关闭,让我们看一下PlayerWeapons.js:
这个脚本代码:
functionAwake()
{
//Selectthefirstweapon选择第一个武器
SelectWeapon(0);
}
Thisfunctioninitializesweapon0asthedefaultweapon.
这个函数初始化武器0为缺省的武器。
functionUpdate()
//Didtheuserpressfire?
用户按开火?
if(Input.GetButton("Fire1"))
BroadcastMessage("Fire");
if(Input.GetKeyDown("1"))
elseif(Input.GetKeyDown("2"))
SelectWeapon
(1);
Thisfunctiondetectskeyboardinput;thefirebutton,the“1”buttonforweapon1orthe“2”buttonforweapon2.TheweaponswillbechildrenobjectsoftheMainCamera.
functionSelectWeapon(index:
int)
for(vari=0;i{//Activatetheselectedweapon激活选择的武器if(i==index)transform.GetChild(i).gameObject.SetActiveRecursively(true);//Deactivateallotherweapon失效所有其它的武器elsetransform.GetChild(i).gameObject.SetActiveRecursively(false);}}这个函数检测键盘输入;开火按钮,“1”按钮是武器1,“2”按钮时武器2。武器将被作为主照相机的子对象。Thisactivatesthecorrespondingweapondependingonkeyboardinput.Let’susetheabovecode.激活响应的武器依赖键盘输入,让我们看上面的代码CreateanemptygameobjectcalledWeapons.MovethissothatitisachildobjecttoMainCamera(insideFPScontroller).Ourweaponswillbeaddedaschildrenofthisobject.建立一个空的叫“Weapons”的游戏对象,移动它以便将它作为主照相机的子对象(在FPS控制器内),我们的武器将被增加为它的子对象。AssignthePlayerWeapons.jsscripttotheWeaponsgameobjectunderMainCamera.分配PlayerWeapons.js脚本到主照相机下的Weapons游戏对象上。We’llnowcreateourfirstweapon.我们将建立我们的第一个武器RocketLauncher火箭发射器Thissectionwilldescribehowtomakearocketlauncherstyleweapon.这一节将描述如何制造一个火箭发射器类型的武器Launcher发射器Therocketlauncherisresponsibleforinstantiatingarocketandgivingitaninitialvelocity.Therocketwillbelauncheddirectlyatwherevertheuserispointingandwillbedestroyedwheneveritcollideswithanothercollider.这个火箭发射器将承担初始化一个火箭并且给它一个初始速度的任务。这个火箭将被发射到用户指定的任何地方并且当它另一个碰撞器发生碰撞时火箭随即被销毁。AddanemptygameobjectandnameitRocketLauncher.PositionthegameobjectintheapproximatepositionwheretheFPSController’shandswouldbe.增加一个空的游戏对象并且命名它为RocketLauncher。定位游戏对象到FPS控制器的手的附近AddtheRocketLauncherasachildtotheWeaponsgameobjectinsidetheMainCameraintheHierarchyView.ThisallowsustoshootwhereverthecameraispointingandalsomakessurethattheRocketLaunchergameobjectfollowstheFPSControllerasitmovesaround(asMainCameraisachildofFPSController).在层次面板视窗中的主照相机的Weapons游戏对象上增加RocketLauncher子对象。ClickonObjects/weapons/rocketLauncherintheProjectwindowandmakesurethattheFBXImporterScaleFactorissetto1,otherwisethemodelwillimportataverysmallscale.在项目窗口中单击Objects/weapons/rocketLauncher并且确保使FBXImporterScaleFactor(比例因子)被设置为1,否则模型将以一个非常小的比例被导入DragObjects/weapson/rocketLaunchermodelsothatitisachildoftheRocketLaunchergameobject.拖拽Objects/weapson/rocketLauncher模型以便它作为RocketLauncher游戏对象的子对象。ThecodefortheRocketLauncher.jsscriptisasfollows:随后是RocketLauncher.js的脚本代码:varprojectile:Rigidbody;varinitialSpeed=20.0;varreloadTime=0.5;varammoCount=20;privatevarlastShot=-10.0;functionFire(){//Didthetimeexceedthereloadtime?难道时间超过重载时间了?if(Time.time>reloadTime+lastShot&&ammoCount>0){//createanewprojectile,usethesamepositionandrotationastheLauncher.//就像发射器一样,在同样的位置建一个新的发射体varinstantiatedProjectile:Rigidbody=Instantiate(projectile,transform.position,transform.rotation);//Giveitaninitialforwardvelocity.Thedirectionisalongthez-axisof//themissilelauncher'stransform.//给它一个初始方向速度,沿着导弹发射器的Z轴instantiatedProjectile.velocity=transform.TransformDirection(Vector3(0,0,initialSpeed));//Ignorecollisionsbetweenthemissileandthecharactercontroller//在导弹和特性碰撞器之间忽略碰撞//译者注:有时我们不太注意,将发射点放到了玩家或发射武器内了,而武器和弹药都有碰撞属性,为防止发射出去的弹药乱飞,下面这句非常必要Physics.IgnoreCollision(instantiatedProjectile.collider,transform.root.collider);lastShot=Time.time;ammoCount--;}}Thiscodeensuresthattheweaponcan’tfirefasterthanreloadTime.Italsochecksthattheusercanfireonlywhentheyhavesufficientammo.这段代码确保了武器开火速度不能比重装(弹药)的时间还快,它还可以检查用户是否有足够的弹药开火ThebehaviorfortheRocketLauncherissimilartothatinthepreviousFPStutorialwiththeexceptionofthereloadtimeandammocountdescribedabove.这个RocketLauncher的行为与以前的FPS教程中的相似,除了上面所说的重载时间和弹药计数以外。AttachtheRocketLauncher.jsscripttotheRocketLaunchergameobject.MakesurethatyouarenotattachingthisscripttotherocketLauncherchildgameobject.附加RocketLauncher.js脚本到RocketLauncher游戏对象上,要确保你不是把脚本附加到rocketLauncher子游戏对象上了。Rocket火箭Wewillnowbuildtherocketinthesceneanduploadthefinalversiontoaprefab.我们现在在场景中构建火箭并且上载最后的版本到一个预制物体上。ClickonObjects/weapons/rocketintheProjectwindowandmakesurethattheFBXImporterScaleFactorissetto1,otherwisethemodelwillimportataverysmallscale.在项目窗口的Objects/weapons/rocket上单击并且确保FBXImporterScaleFactor(比例因子)被设置为1,模型将以一个非常小的比例被导入DragtheObjects/weapons/rocketmodelintotheSceneview.拖拽Objects/weapons/rocket模型到场景视窗中。AttachtheWeaponScripts/Rocket.jsscripttoit.附加WeaponScripts/Rocket.js脚本给它Addaboxcollidertotherocketgameobject.Maketheboxcolliderslightlylargerthantheactualrockettopreventtunnelingofcollisions.Tunnelingofcollisionsiswhathappenswhensmall,fastgameobjectsavoidcollisiondetectionduetotheirsizeandspeed.Makingtheboxcolliderz-axislargerensurescollisionsworkcorrectlyfortheseobjects.增加一个盒子碰撞器给火箭游戏对象。使盒子碰撞器稍稍大于实际的火箭,以阻止穿透碰撞。当碰撞器很小时穿透碰撞就会发生,快的游戏对象避免碰撞检测取决于它们的尺寸和速度,使得盒子碰撞器的在Z轴变得更大以确保这些对象的碰撞工作能正确的发生。IntheRigidbodyoftherocketgameobject,deselectUseGravity.Thisensuresthattherocketdoesnotfallundergravity.在火箭游戏对象的刚体中,不选择使用UseGravity选项,这能确保火箭不会再重力作用下坠落。Createaparticlesystem:GameObject>CreateOther>ParticleSystem.建立一个粒子系统:GameObject>CreateOther>ParticleSystemModifytheEllipsoidx,y,zsizesto0.1.编辑Ellipsoid的X、Y、Z的尺寸到0.1ModifytheRndVelocityto0.1ineachaxisalso.编辑RndVelocity的每个轴向数据到0.1ChangetheparticleemitterMinSizeandMaxSizeto0.5.改变例子发射器的最小尺寸和最大尺寸到0.5Changethenumberofparticlesemittedto100(MinandMaxEmission).改变粒子发射器的数目到100(最小和最大排放物数目)DragtheParticleEffects/smokeontotheparticlesystem.拖拽粒子效果/烟雾到粒子系统上IntheParticleAnimatorsection,seteachoftheWorldRotationAxisvaluesto0.5.在例子的动画片段,设置每个世界旋转轴的坐标值为0.5SettheSizeGrowvariableto3.设置尺寸生长变量到3EnableAutodestructontheparticlesystem.Thisensuresthattheparticlesystemisremovedfromthegameaftertherockethasbeendestroyed.选中粒子系统中的自毁选项,这能确保在火箭被销毁以后粒子系统也能被从游戏中删除DragtheparticlesystemintheHierarchyViewsothatitisachildoftherocket.Resetthetransformoftheparticlesystemsothatitiscentredontherocket,thenmodifythepositionsothatitisattherearoftherocket.在层次视窗中拖拽粒子系统以便它作为火箭的一个子对象,重设粒子系统的transform以便它位于火箭的中心,然后编辑它的位置让它靠近火箭。 SelecttherocketintheHierarchyviewandcheckthatthesmoketrailfollowsitaroundintheSceneviewifyoumoveitaround.在层次视窗中选择火箭并且在周围移动它,在场景视图中检查烟尾。We’venowmadeourrocket,completewithsmoketrail.We’renowreadytouploadourchangestotheprefab.我们现在制造火箭,完成烟尾.准备上载(火箭)到预制物体中。Firstly,createanemptyprefabtouploadourchangesto.Calltheprefab‘Rocket’.首先,建立一个空的预制物体以上载我们的改变,叫预制物体为‘Rocket’SelecttherocketintheHierarchyviewanddragitontothenewRocketprefab.在层次面板视窗中选择火箭并且拖动它到新的火箭预制物体上。CreateanewdirectoryintheProjectviewcalled‘WeaponPrefabs’tostoreourweaponprefabsin.在项目视窗中建立一个新的目录叫‘WeaponPrefabs’,在里面存储我们的武器预制物体。Here’stheJavascriptforRocket.js://Thereferencetotheexplosionprefabvarexplosion:GameObject;vartimeOut=3.0;//Killtherocketafterawhileautomatically//一会儿自动销毁火箭functionStart(){Invoke("Kill",timeOut);}这里是Rocket.js的Javascript脚本TheKillfunction,firstly,findstheparticleemitterinthechildhierarchyandturnsitsemitteroff.Next,itdetachesanychildren(e.g.Smoketrailparticlesystem)fromtheobjectthescriptisattachedto(therocket)anddestroystherocket.Kill函数,首先,在子层次上找到粒子发射器并且关闭它的发射,下一步,它被分派到被附加脚本的对象的另一个子对象(例如烟尾粒子系统)并且销毁火箭。functionOnCollisionEnter(collision:Collision){//Instantiateexplosionattheimpactpointandrotatetheexplosion//在碰撞点初始化爆炸物体并且调整爆炸物体方向//sothatthey-axis
//Activatetheselectedweapon激活选择的武器
if(i==index)
transform.GetChild(i).gameObject.SetActiveRecursively(true);
//Deactivateallotherweapon失效所有其它的武器
else
transform.GetChild(i).gameObject.SetActiveRecursively(false);
这个函数检测键盘输入;开火按钮,“1”按钮是武器1,“2”按钮时武器2。
武器将被作为主照相机的子对象。
Thisactivatesthecorrespondingweapondependingonkeyboardinput.
Let’susetheabovecode.
激活响应的武器依赖键盘输入,让我们看上面的代码
CreateanemptygameobjectcalledWeapons.Movethissothatitisachildobject
toMainCamera(insideFPScontroller).Ourweaponswillbeaddedaschildren
ofthisobject.
建立一个空的叫“Weapons”的游戏对象,移动它以便将它作为主照相机的子对象(在FPS控制器内),我们的武器将被增加为它的子对象。
AssignthePlayerWeapons.jsscripttotheWeaponsgameobjectunderMain
Camera.
分配PlayerWeapons.js脚本到主照相机下的Weapons游戏对象上。
We’llnowcreateourfirstweapon.
我们将建立我们的第一个武器
RocketLauncher火箭发射器
Thissectionwilldescribehowtomakearocketlauncherstyleweapon.
这一节将描述如何制造一个火箭发射器类型的武器
Launcher发射器
Therocketlauncherisresponsibleforinstantiatingarocketandgivingitaninitialvelocity.Therocketwillbelauncheddirectlyatwherevertheuserispointingandwillbedestroyedwheneveritcollideswithanothercollider.
这个火箭发射器将承担初始化一个火箭并且给它一个初始速度的任务。
这个火箭将被发射到用户指定的任何地方并且当它另一个碰撞器发生碰撞时火箭随即被销毁。
AddanemptygameobjectandnameitRocketLauncher.PositionthegameobjectintheapproximatepositionwheretheFPSController’shandswouldbe.
增加一个空的游戏对象并且命名它为RocketLauncher。
定位游戏对象到FPS控制器的手的附近
AddtheRocketLauncherasachildtotheWeaponsgameobjectinsidetheMainCameraintheHierarchyView.ThisallowsustoshootwhereverthecameraispointingandalsomakessurethattheRocketLaunchergameobjectfollowstheFPSControllerasitmovesaround(asMainCameraisachildofFPSController).
在层次面板视窗中的主照相机的Weapons游戏对象上增加RocketLauncher子对象。
ClickonObjects/weapons/rocketLauncherintheProjectwindowandmakesure
thattheFBXImporterScaleFactorissetto1,otherwisethemodelwillimportat
averysmallscale.
在项目窗口中单击Objects/weapons/rocketLauncher并且确保使FBXImporterScaleFactor(比例因子)被设置为1,否则模型将以一个非常小的比例被导入
DragObjects/weapson/rocketLaunchermodelsothatitisachildoftheRocketLaunchergameobject.
拖拽Objects/weapson/rocketLauncher模型以便它作为RocketLauncher游戏对象的子对象。
ThecodefortheRocketLauncher.jsscriptisasfollows:
随后是RocketLauncher.js的脚本代码:
varprojectile:
Rigidbody;
varinitialSpeed=20.0;
varreloadTime=0.5;
varammoCount=20;
privatevarlastShot=-10.0;
functionFire()
//Didthetimeexceedthereloadtime?
难道时间超过重载时间了?
if(Time.time>reloadTime+lastShot&&ammoCount>0)
//createanewprojectile,usethesamepositionandrotationastheLauncher.
//就像发射器一样,在同样的位置建一个新的发射体
varinstantiatedProjectile:
Rigidbody=Instantiate(projectile,
transform.position,transform.rotation);
//Giveitaninitialforwardvelocity.Thedirectionisalongthez-axisof
//themissilelauncher'stransform.
//给它一个初始方向速度,沿着导弹发射器的Z轴
instantiatedProjectile.velocity=transform.TransformDirection(
Vector3(0,0,initialSpeed));
//Ignorecollisionsbetweenthemissileandthecharactercontroller
//在导弹和特性碰撞器之间忽略碰撞
//译者注:
有时我们不太注意,将发射点放到了玩家或发射武器内了,而武器和弹药都有碰撞属性,为防止发射出去的弹药乱飞,下面这句非常必要
Physics.IgnoreCollision(instantiatedProjectile.collider,transform.root.collider);
lastShot=Time.time;
ammoCount--;
Thiscodeensuresthattheweaponcan’tfirefasterthanreloadTime.Italsochecksthattheusercanfireonlywhentheyhavesufficientammo.
这段代码确保了武器开火速度不能比重装(弹药)的时间还快,它还可以检查用户是否有足够的弹药开火
ThebehaviorfortheRocketLauncherissimilartothatinthepreviousFPStutorialwiththeexceptionofthereloadtimeandammocountdescribedabove.
这个RocketLauncher的行为与以前的FPS教程中的相似,除了上面所说的重载时间和弹药计数以外。
AttachtheRocketLauncher.jsscripttotheRocketLaunchergameobject.MakesurethatyouarenotattachingthisscripttotherocketLauncherchildgameobject.
附加RocketLauncher.js脚本到RocketLauncher游戏对象上,要确保你不是把脚本附加到rocketLauncher子游戏对象上了。
Rocket火箭
Wewillnowbuildtherocketinthesceneanduploadthefinalversiontoaprefab.
我们现在在场景中构建火箭并且上载最后的版本到一个预制物体上。
ClickonObjects/weapons/rocketintheProjectwindowandmakesurethattheFBXImporterScaleFactorissetto1,otherwisethemodelwillimportataverysmallscale.
在项目窗口的Objects/weapons/rocket上单击并且确保FBXImporterScaleFactor(比例因子)被设置为1,模型将以一个非常小的比例被导入
DragtheObjects/weapons/rocketmodelintotheSceneview.
拖拽Objects/weapons/rocket模型到场景视窗中。
AttachtheWeaponScripts/Rocket.jsscripttoit.
附加WeaponScripts/Rocket.js脚本给它
Addaboxcollidertotherocketgameobject.Maketheboxcolliderslightlylargerthantheactualrockettopreventtunnelingofcollisions.Tunnelingofcollisionsiswhathappenswhensmall,fastgameobjectsavoidcollisiondetectionduetotheirsizeandspeed.Makingtheboxcolliderz-axislargerensurescollisionsworkcorrectlyfortheseobjects.
增加一个盒子碰撞器给火箭游戏对象。
使盒子碰撞器稍稍大于实际的火箭,以阻止穿透碰撞。
当碰撞器很小时穿透碰撞就会发生,快的游戏对象避免碰撞检测取决于它们的尺寸和速度,使得盒子碰撞器的在Z轴变得更大以确保这些对象的碰撞工作能正确的发生。
IntheRigidbodyoftherocketgameobject,deselectUseGravity.Thisensuresthattherocketdoesnotfallundergravity.
在火箭游戏对象的刚体中,不选择使用UseGravity选项,这能确保火箭不会再重力作用下坠落。
Createaparticlesystem:
GameObject>CreateOther>ParticleSystem.
建立一个粒子系统:
GameObject>CreateOther>ParticleSystem
ModifytheEllipsoidx,y,zsizesto0.1.
编辑Ellipsoid的X、Y、Z的尺寸到0.1
ModifytheRndVelocityto0.1ineachaxisalso.
编辑RndVelocity的每个轴向数据到0.1
ChangetheparticleemitterMinSizeandMaxSizeto0.5.
改变例子发射器的最小尺寸和最大尺寸到0.5
Changethenumberofparticlesemittedto100(MinandMaxEmission).
改变粒子发射器的数目到100(最小和最大排放物数目)
DragtheParticleEffects/smokeontotheparticlesystem.
拖拽粒子效果/烟雾到粒子系统上
IntheParticleAnimatorsection,seteachoftheWorldRotationAxisvaluesto0.5.
在例子的动画片段,设置每个世界旋转轴的坐标值为0.5
SettheSizeGrowvariableto3.
设置尺寸生长变量到3
EnableAutodestructontheparticlesystem.Thisensuresthattheparticlesystemisremovedfromthegameaftertherockethasbeendestroyed.
选中粒子系统中的自毁选项,这能确保在火箭被销毁以后粒子系统也能被从游戏中删除
DragtheparticlesystemintheHierarchyViewsothatitisachildoftherocket.Resetthetransformoftheparticlesystemsothatitiscentredontherocket,thenmodifythepositionsothatitisattherearoftherocket.
在层次视窗中拖拽粒子系统以便它作为火箭的一个子对象,重设粒子系统的transform以便它位于火箭的中心,然后编辑它的位置让它靠近火箭。
SelecttherocketintheHierarchyviewandcheckthatthesmoketrailfollowsitaroundintheSceneviewifyoumoveitaround.
在层次视窗中选择火箭并且在周围移动它,在场景视图中检查烟尾。
We’venowmadeourrocket,completewithsmoketrail.We’renowreadytoupload
ourchangestotheprefab.
我们现在制造火箭,完成烟尾.准备上载(火箭)到预制物体中。
Firstly,createanemptyprefabtouploadourchangesto.Calltheprefab‘Rocket’.
首先,建立一个空的预制物体以上载我们的改变,叫预制物体为‘Rocket’
SelecttherocketintheHierarchyviewanddragitontothenewRocketprefab.
在层次面板视窗中选择火箭并且拖动它到新的火箭预制物体上。
CreateanewdirectoryintheProjectviewcalled‘WeaponPrefabs’tostoreourweaponprefabsin.
在项目视窗中建立一个新的目录叫‘WeaponPrefabs’,在里面存储我们的武器预制物体。
Here’stheJavascriptforRocket.js:
//Thereferencetotheexplosionprefab
varexplosion:
GameObject;
vartimeOut=3.0;
//Killtherocketafterawhileautomatically
//一会儿自动销毁火箭
functionStart()
Invoke("Kill",timeOut);
这里是Rocket.js的Javascript脚本
TheKillfunction,firstly,findstheparticleemitterinthechildhierarchyandturnsitsemitteroff.Next,itdetachesanychildren(e.g.Smoketrailparticlesystem)fromtheobjectthescriptisattachedto(therocket)anddestroystherocket.
Kill函数,首先,在子层次上找到粒子发射器并且关闭它的发射,下一步,它被分派到被附加脚本的对象的另一个子对象(例如烟尾粒子系统)并且销毁火箭。
functionOnCollisionEnter(collision:
Collision){
//Instantiateexplosionattheimpactpointandrotatetheexplosion
//在碰撞点初始化爆炸物体并且调整爆炸物体方向
//sothatthey-axis
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1