CreatingaFirstPersonShooter(FPS)Part3
Author:GrahamMcAllisterRevisedby:JeffAydelotte&
AmirEbrahimi
Timetocomplete:34hours
LastRevision:10July2009
Contents
1. Part3:AdvancedFPSPrerequisites 3Settingup 3Waypoints 3RobotAI 4RobotDamage 5Ragdolls 6Sound 7GUI 8Finally... 9Theendofthebeginning... 10
Part3:AdvancedFPS
PrerequisitesThistutorialassumesthatyouarefamiliarwiththeUnityinterfaceandbasicscriptingconcepts.Additionally,youshouldalreadybefamiliarwiththeconceptsdiscussedinPart1and2oftheFPStutorialseries.
SettingupWe’regoingtobuilduponthepreviousFPStutorial,sowe’llbeginbyopeningthat:
Openthepreviousproject(FPSTutorial2).
WaypointsThissectionwillintroducewaypointstoourgame,theseareusedtoinformtherobots ofthepaththattheycanwalkaround. Let’saddthreewaypointstoourgame:
CreateanemptygameobjectandrenamethistoWaypoint. Makesurethegameobjectisplacedapproximatelyonemeterabovethegroundlevel.
AddAutoWayPointscripttoWaypoint. NoticehowtheemptygameobjectnowdisplaysaWintheSceneView.
DuplicatetheWayPointgameobjecttwiceandarrangethewaypointsinatriangleshape(positionquitefarapart).
ThisadvancedleveltutorialextendsuponthepreviousFPStutorialsbyintroducinggameelementssuchaswaypoints,enemyAI,ragdollsandanimation.
CheckthatthewaypointsarevisibletoeachotherbyfirstlyclickingonanywaypointthenselectingUpdateWaypointfromthecontextmenuoftheAutoWayPointscript(therightmostbuttononthecomponentintheInspectorView). Agreenlinewillbedrawnbetweenvisiblewaypoints,aredlineforthosewhichdon’thaveaclearlineofsight.
Wehavenowdescribedthepaththatanenemycanwalkaround,nowlet’saddanopponenttothescene.
RobotAIThissectionwilladdanenemyrobottoourscene.
SelectRobotArtwork/robotanddragitintotheSceneViewmakingsurealloftherobotisabovetheground.
Let’sgivetherobotsomebehavior.
AddWeaponsScripts/AItorobot. IntheAIscriptsectionorrobot,assigntheFPScontrollerasthetarget(sotherobotknowswhotohuntdown).
AddtheAIAnimationscripttotherobot. Thiscontrolstheanimationofourrobot(whentorun,whentoaimetc). ThiscommunicateswiththeAIscripttofindoutwhattheAIscriptiscurrentlydoing,e.g.arewerunning,shootingetc. Itthencrossfadestheanimationstoprovideasmoothtransition.
Nowweneedtomaketherobotcontrollerobjectalittlelargersothathedoesn’tintersectwiththeground. ThisisbecausethecharactercontrollerwhichisusedtopreventtheenemyfrommovingthroughwallsisusingacapsuletorepresenttheAI. Weneedtomakethiscapsulealittlelargertomatchtheactualgraphics,thiswayhewillnotintersectwiththegroundanymore.
Selecttherobot,thenintheInspectorViewmodifytheheightandradiusvaluesoftheCharacterControllercomponentsothatitenclosestherobot. Pressplaytomakesureitworkscorrectly.
4
Trymakingtheheightandradiusvaluessmallerandlargertoseethedifference.
Nowweneedtogivetherobottheabilitytofirehisgun. Therobotiscontinuouslymovingandanimating. Whenheshootshisgunweplayananimationonthehandsandthegraphicalgunthenspawntherocketfromtransformrelativetotherobot.Thistransformdoesnotanimate,itissimplyplacedapproximatelyatthepointwherethegunwillbewhentheshootanimationfirestherocket.
Createanemptygameobjectandmakeitachildoftherobot(usethehierarchyview).
Renamethegameobjectgun_spawn.
Nowweneedtoplaceitproperly. InthetransforminspectorselectResetfromthecontextmenu,thenmoveitforwardinthezaxis.
Addtherocketlauncherscripttothegun_spawngameobject. Assigntherocketprefabtotheprojectilevariable.
Makeaprefabofthisrobot,callitRobot. Thiswillallowyoutocreatemoreenemieseasily.
Playthegameandcheckthattherobotfiresatyou.
Althoughyoucanshoottherobot,itisnotconfiguredtotakedamage,we’llremedythisinthenextsection.
RobotDamageAttachtheCharacterDamagescripttotheRobotprefab.
Playthegame,shoottherobotwiththemachinegunandheshoulddisappear.
5
RagdollsRagdollsemulateanaturalskeletalbonestructure,thiswillallowourrobottofallnaturallywhenkilled. Thissectionwillshowhowtosetuparagdoll.
Firstly,createanewscene(File>NewScene).We’regoingtosetupourragdollinhere. Saveyourcurrentsceneifnecessary.
Createacube(resizeifnecessary),thiswillbeusedasaplatformforourrobot.DragintherobottotheSceneViewsothatitispositionedabovethecube.
Removetheanimationcomponent. Thisisimportantotherwisetheanimationswillinterferewiththephysics.
Nowusetheragdollwizard:Gameobject>CreateOther>Ragdoll.
Adialogboxappears,nowwehavetoassignallthebonestothecorrectslotsinthewizard. WeassignthebonesbydraggingthevaluesfromtheRobotintheHierarchyViewontothecorrectplaceinthedialogbox.ExpandtheRobotgameobjectintheHierarchyViewifnecessarytorevealthis.
Firstly,rootHandle(HierarchyView)mapsontoroot(inthedialogbox). DragrootHandleontotheplaceholderbesiderootinthedialogbox.
SetTotalMassto4
LegsAssignupleg_LtoLeftHip.
Assignlowleg_LgoestoLeftKnee.
Assignheel_LgoestoLeftFoot.
Repeatfortherightleg.
Upperbody/ArmsAssignupArm_LgoestoLeftArm.
Assignelbow_LgoestoLeftElbow.
Repeatfortherightarm.
Assignspine3goestoMiddlespine.
Finally,headgoestoHead.
Hitcreatethenpressplay,therobotshouldfall,howeverthegunwon’t.
Tomakethegunfall:
SelectthegunintheHierarchyView.
Addarigidbodycomponent.
6
Addaboxcollider. Adjustthesizeoftheboxcollidertofitthegun,you’llneedtoadjustthecenterpositionalso.
Nowweputthefullyriggedrobotintoaprefab.Tocreatetheprefab:
Assets>Create>Prefab.
RenameittoRobotRagdoll.
Dragtherobot(rootlevel)fromthehierarchyviewintotheprefab. Thiswillmakesurethegunisattachedalso.
Nowwhentherobotiskilled,wedeletetheoldrobotandinstantiatethenewragdollrobot,thisallowsourrobottofalltothegroundnaturally.
UsingtheRagdollOpentheoriginalscene(noneedtosavethecurrentscene),selecttherobotfromtheHierarchyViewandintheCharacterDamageinspector,dragintheRobotRagdollprefabtotheDeadReplacement.
Playthegame,shoottherobotanditshouldnowfalldownwhenshot.
Youmaywanttotweakthemassoftherobottoimprovethelook&feeloftheragdoll.Youcandothisintheragdollwizard,bychangingthemassproperty. Thisisespeciallyimportantinexplosionforceswheretherobotisthrownintotheair.
SoundThissectionwilladdsoundeffectstoourgame.
MachinegunDragmachineGunSingleShotLoopableontotheMachineGungameobject.
TurnoffPlayonAwake.
7
RocketLauncherWewanttoattachthesoundsourceoftherockettotherocketsothattheaudiolevelsreducesasitfliesaway.
SelecttheRocketprefab.
AddanAudioSourcecomponenttotheprefab.
DragtheRocketLauncherFireaudiosourcetotheAudioClippropertyoftheAudioSource.
AdjusttheRolloffFactorsothatthesoundfadesoutfaster(0.5mightbeok).
GUITheGUI(GraphicalUserInterface)isresponsibleforgivingfeedbacktotheplayeronthecurrentgamestatus. TypicalGUIelementsinclude;numberofbulletsleft,health,missionobjectivesetc.
InthisgamewehavethreemainGUIelements.
OverlayTheoverlaysetsupthedifferentzonesoftheGUI(health,ammoetc).
SelecttheGUIOverlaytextureinGUI/GUIOverlay.
SelectGameObject>CreateOther>GUITexture,thiswillplacethetextureinthecentreoftheGameView.
Wenowneedtopositiontheoverlayinthecorrectplace:
ModifythetransformPositionto0,0,0.
ModifythePixelInsetto0,0,256,128(inorderX,Y,Width,Height).
HealthSelectGUI/healthBarintheProjectView.
SelectGameObject>CreateOther>GUITexture.
SetthetransformPositionto0,0,0.
Thepixelinsetvaluesare37,83,111,29.
ThehealthBartextureisscaledinrealtimetocoverthecorrectamountoftherippledareabesidethehealthicon.
MachineGunSelectGameObject>CreateOther>Text.
SettransformPositionto0,0,0.
8
SetPixelOffsetto188,109.
Youcanchangethetextifwanted(fornow),ascriptwillsettextwhenthegameisrun.
RocketsSelectGameObject>CreateOther>GUITexture.
SetTexturetoNone.
DragMiscScripts/DrawRockets.jsontotheGUITexture.
SetRocketTexturetoGUIRocket21.
SetPosYto68.
Finally,addtheFPSPlayerscripttotheFPScontroller,assigntheGUIstothepropertiesintheFPSPlayerscriptsection.
Finally...We’venearlyfinishedourtutorial,butlet’saddsomeadditionalsoundsfirst.
PlayerDamageSoundsTotheFPSPlayerscriptoftheFPScontrollergameobjectassignthefollowingsounds:
moanOfPainSmall
moanOfPainBig
playerDie
WalksoundsWecanassignanynumberofwalksoundstoourFPScontroller(toavoidrepetition),thesearechosenrandomlyfromavariablesizedlist.
SelectFPSplayer.ExpandthetriangleforWalkSoundsandsetSizeto5. Dragfootstep15fromSounds/intoeachofthefiveelements.
AddanAudioSourcecomponenttotheFPSplayer(noneedtodoanythingelse).
LightsformovingobjectsThesceneinourgameislightmapped,howeverthecharactersandrigidbodiescannotusethislightmapsincetheyaremoving.Thus,weneedtosetupsomelightswhich
9
onlyaffectthoseobjectsandlooksimilartothelightingofthelightmap. Forthispurposeweusethelightscullingmask.
Createadirectionallight.
We’llalterthelight’scullingmask,thisdetermineswhatthedirectionallightislighting.
FirstgotoEdit>ProjectSettings>Tags,clickonUserLayer8andtypeLightmapped.
NowselectthedirectionallightagainandturnoffLightmapped.
SelectmainLevelMesh,changetheLayerpropertytoLightmapped.Applythischangetoallchildobjectswhenprompted.
Theendofthebeginning...ThiscompletesourFPStutorialseries. Manykeylessonsforgamedevelopmenthavebeenpresentedandwillapplytootherstylesofgames:notonlyFPSstylegames. WehopethatyouhavelearnedthefundamentalsofgamecreationandarenowmotivatedtodesignyourownnovelgameswithUnity.
AcknowledgmentsSpecialthanksgotoJoachimAnte(code)andEthanVosburgh(graphics)fortheirhelpinthemakingofthistutorial.
DownloadthecompleteFPSprojectfromtheResourcessectiontoseeapolishedversionofthistutorial.
10