19
Creating a First Person Shooter (FPS) Part 1 Author: Graham McAllister Revised by: Jeff Aydelotte & Amir Ebrahimi Time to complete: 3-4 hours Last Revision: 10-July-2009

FPS Tutorial 1

Embed Size (px)

Citation preview

Page 1: FPS Tutorial 1

CreatingaFirstPersonShooter(FPS)Part1

Author:GrahamMcAllisterRevisedby:JeffAydelotte&

AmirEbrahimi

Timetocomplete:3­4hours

LastRevision:10­July­2009

Page 2: FPS Tutorial 1

Contents

1. Part1:IntroductionPrerequisites 3Startinganewproject 3Settingupthegameenvironment 4AddingtheMainCharacter 4Addingaweapon 5CreatetheMissileobject 6Missileexplosions 10Soundeffects 13AddingaGUI 13Physics 15Acknowledgments 19

Page 3: FPS Tutorial 1

Part1:Introduction

PrerequisitesThistutorialassumesthatyouarefamiliarwiththeUnityinterfaceandbasicscriptingconcepts.

StartinganewprojectDownloadFPS_Tutorial.zip,unzip,andopentheprojectfolderinUnity.

ImporttheStandardAssetsUnityPack­agefromyourStandardPackagesfolderwhereUnityisinstalled.

Afterimporting,youwillseeUnity’sbuiltin"Stan­dardAssets"intheProjectPanel.Whenwecreatenewassets,it’sbesttoputtheminfoldersthatgroupthemaccordingtotheirfunction,e.g.Rocket,Explosion,Audio,etc.

ThistutorialwilldetailhowtomakeasimpleFirstPersonShooter(FPS).Itwillintroducefundamental3Dgameprogrammingconceptsandgivetipsonhowtothinklikeagameprogrammer.

Page 4: FPS Tutorial 1

SettingupthegameenvironmentOncetheassetshavebeenimported,you’llnoticetherearemanyfoldersinthePro­jectpanel.

IntheProjectspanel,SelectthemainLevelMeshfromObjects/mainLevelMesh/mainLevelMesh.

IntheInspectorpanel,insideoftheFBXImporteroptionsyou’llfindthe"Gener­ateColliders"option.Togglethatoptionon.Ifwedon’tdothis,theplayerwillsimplyfallthroughthelevel(nocollision).

DragthemainLevelMeshintothescene.

 

Thereisnoneedtoaddalighttothescene,thelevelisalreadyfullylightmapped.Theimportedleveluseslightmapsforalllightingwhichallowsustousepre­bakedshad­ows.Lightmapsareverygoodforperformance,especiallyifyouwanttocreateacomplexlightingsetup.

You’renowreadytoaddacharacterintotheenvironment.

AddingtheMainCharacterWe’renowgoingtoaddinacharacterfortheplayertocontrol.Unityhasabuiltinprefabspecificallyforafirst­personcontroller.ThiscanbefoundintheProjectpanelunderStandardAssets­>Prefabs.

ToaddtheFirstPersonController,clickonthearrowbesideStandardAssetsintheProjectpanel,aslistofassetswillappear.Findthe foldercalledPrefabsandclickonthearrowinthelefthandside.YoushouldnowseetheFirstpersoncontrollerasset.DragthisintotheSceneview.

4

Page 5: FPS Tutorial 1

Youshouldseeacylinderobjectrepresentingtheplayer,3largearrowsforal­teringthelocationin3Dspacefortheobject(ifyoudonotsee3arrowsthenpressthe‘W’key),andawhitemeshwhichshowstheobject’sviewport(whereitiscurrentlylooking).TheFPSControllerisnowthedefaultcamera,bymovingthisobject,youchangethecurrentviewintheGameView.You’llalsonoticethattheFPSControllerhasacameraiconontopofit.Movethecharactersothatitisabovegroundlevelintheenvironment.

AswenolongerhaveanyneedfortheMainCamera,youcandeleteit.

PressPlay,youshouldnowbeabletomovearoundthelevelbyusingthemouseandkeyboard(cursorkeystomoveorW,A,S,D).

 

You’venowcreatedaverysimpleFPS,let’sgivetheplayeraweapon.

AddingaweaponWe’renowgoingtogivetheplayeragrenadetypeobjecttothrowintheenviron­ment.Todothis,you’llneedtocreatesomeJavascripttotellUnityaboutthebehavioroftheweapon.

Sowhatdowewanttodo?Wewanttoallowtheplayertoshootwhereverthecam­eraispointing.However,let’sfirstthinkaboutourgamecharacterandtheirweapons.Ourgamecharacterisseenthroughthefirstpersonview,withthecamerapositionedateyelevel.Iftheplayerfiresaweapons,theweaponshouldbelaunchedfromwher­evertheirhandsare,notfromeyelevel.Thismeanswehavetoaddinagameobjecttorepresentthegrenadelauncher,andplaceitwheretheplayer’shandwouldbewhentheyholdthisweapons.Thisensuresthattheobjectfiresfromthecorrectlocation. 

5

Page 6: FPS Tutorial 1

CreatetheweaponlauncherFirst,let’saddinagameobjecttorepresentthegrenadelauncher.Agameobjectisanyiteminthe3Dworld(player,level,sounds),componentsarethepropertiesthatthegameobjecthas.Thereforeyouapplycomponentstogameobjects.

FromthemainmenuselectGameObject­>CreateEmpty,andrenametheobjectto"Launcher"intheHierarchypanel.Note,thisobjectisinvisibleasitisandemptyobject,howeveritisjustaplaceholderforourmissilelauncher.

Nowlet’sgetinclosetoourFPScontrollersowecanseewheretopositiontheweaponlauncher.

SelecttheFPScontrollerintheHierarchyPanelandensuringthatyourcursorisovertheSceneView,press‘F’(frameselected).Thisfocusesusontheplayer(thecurrentlyselecteditem).

NowselecttheLauncherfromtheHierarchyPanelandchooseGameObject­>Movetoviewfromthemainmenu.NoticehowtheLauncherobjectisnowplacedneartheFPSController.Wecannowusethehandlestoplacethelauncherapproximatelywherethehandsshouldbe.

NOTE Youcanmakethecharacterleftorright­handedbyalteringthelocationofthisobject,noneedtochangeanycode.

MakesureyourUnitywindowlayoutisin2by3mode(Window­>Layouts­>2by3),andpressthePlaybutton.MakesureLauncherisselectedintheHierarchyViewandwhilstwatchingtheSceneView,movethecharacteraround.You’llnoticethatourlauncherobjectdoesnotmovewithourcharacter(youcanpressPlaytostopthegamerunningnow).

TosolvethisproblemdragtheLauncherobjectontotheMainCameraobjectthatbelongstotheFPSControllerintheHierarchypanel.ItisokaytobreakthePrefabconnection.NowrunthegameagainandwatchtheSceneView,theLaunchershouldnowmovewithourcharacter.WehaveassociatedtheLaunchergameobjectwithanobjectthatmovesinall3axes(thecamera).

CreatetheMissileobjectLet’screatethemissilethatwillbelaunchedwhentheuserclicksthefirebutton.

Fornowwe’llusesomethingsimple,asphere.CreateanewprefabobjectbyclickingonAssets­>Create­>PrefabfromtheUnitymenubar,andrenameittoMissile.

Nowcreateasphere(GameObject­>CreateOther­>Sphere).

NowdragtheSpheregameobjectfromtheHierarchyPanelontotheMissileprefabintheProjectPanel.Theiconfortheprefabwillnowchange.YoucandeletetheSphereobjectfromtheHierarchyView.

6

Page 7: FPS Tutorial 1

TIP Anygameobjectwhichyouknowyou’llneedtoinstantiateatrun­timeshouldgenerallybeaprefab.

 

WritetheMissileLaunchercodeTheFPSControllerisaprefabconsistingofseveralgameobjectandcomponents.TheFPSControlleritselfisacylindricalmeshthatonlyrotatesaroundthey­axis,soifweattachthelaunchercode(script)tothis,thenwewon’tbeabletoshootupanddown.Therefore,we’regoingtoattachourlaunchercodetotheMainCamerainsidetheFPSControllerasthecameracanlookinanydirection.

Let’screateourfirstJavascriptcodewhichwilldescribethebehaviouroftheLauncher.

SelectAssets­>Create­>JavaScript,whichcreatesablankJavascriptdocument.AnewassetappearsintheProjectPanelentitledNewBehaviourScript.RenamethisscripttoMissileLauncher.

TIP YoucanspecifywhichexternalcodeeditoryouwantUnitytousebyclickingonUnity­>PreferencesthenselectingtheExternalScriptEditorbox.

CreateanewdirectoryinsideyourProjectViewcalledWeaponScripts,we’llputallourweaponsscriptsinhere.MoveyourMissileLauncherjavascriptintohere,andmovetheMissileprefabalso.

Let’shavealookatthecompleteJavascriptforMissileLauncher.Youcantypeinthecodesectionsasyoufollow.

Thinkingfromahighlevel,whatdowewanttodo?Well,wewanttodetectwhentheuserhashitthefirebutton,theninstantiateanewmissile,andlaunchitwithacertainvelocitytowardswheretheuserwasaiming.Let’sexaminethecodeindetail:

var projectile : Rigidbody;var speed = 20;

function Update(){

Thisisthebeginningofthescript,whichdefinestopropertiesanddeclaresafunctioncalledUpdate.

if( Input.GetButtonDown( "Fire1" ) )

7

Page 8: FPS Tutorial 1

Firstwewanttocheckwhentheuserhitsthefirebutton."Fire1"ismappedtoboththeleftmousebuttonandthecurrentkeyboardconfiguration(thiscanbeeditedfrommenuEditor­>ProjectSettings­>Input).

{ var instantiatedProjectile : Rigidbody = Instantiate( projectile, transform.position, transform.rotation );

Wedeclareavariabletoholdareferencetotheinstantiatedobject.ThetypeofthisvariableisRigidbody,thisisbecausethemissileshouldhavephysicsbehavior.

ToinstantiateanobjectinUnityweusetheInstantiatefunctionwiththreepa­rameters,theobjecttoinstantiate,the3Dpositionitshouldbecreatedat,andtherotationtheobjectshouldhave.Thereisalsoanotherconstructor,checktheAPIguide,butwe’llusethisonefornow.

Thefirstparameter,projectile,istheobjectwewanttocreate.Sowhatisprojectileanyway?Theprojectileissetbyyouinsidetheeditor.Toallowthistohappen,wede­clarethevariableprojectileoutsideofanyfunction,whichmakesitpublicandexposes ittotheUnityeditor.Theprojectileobjectcouldhavebeencreatedincode,howeverifyouwanttomodify(tweak)avariable,it’sbettertodothisfromwithintheUnityeditor.

Thesecondparameter,transform.position,createstheprojectileatthesamepositionin3Dspaceasthelauncher.Whythelauncher?Well,thescriptwe’recreatingwillbeattachedtothelaunchersoifwewanttogetourcurrent3Dposition,transform.positiongivesthattous(thetransformkeywordaccessestheTransformoftheGameObjectwherethescriptisattached). 

Thethirdparameter,transform.rotation,issimilartothesecondparameter,exceptitcreatesthemissilewiththesamerotationpropertiesasthelauncher.

instantiatedProjectile.velocity = transform.TransformDirection( Vector3( 0, 0, speed ) );

Thenextpartofthecodemakesourmissilemove.Todothis,wegivethemissileavelocity,butinwhichdirection(x,y,orz)?IntheSceneView,clickontheFPSControl­ler,themovearrowsappear(press‘W’ifthearrowsdonotappear),oneisred,oneisgreen,andoneisblue.Reddenotesthex­axis,greendenotesthey­axis,andbluede­notesthez­axis.Asblueispointinginthedirectionthattheplayerisfacing,wewanttogiveourmissileavelocityinthez­axis.

 

8

Page 9: FPS Tutorial 1

VelocityisapropertyofinstantiatedProjectile.Howdidweknowthis?Well,instanti­atedProjectileisoftypeRigidbody,andifwelookattheAPIweseethatvelocityisaproperty.TakealookatsomeoftheotherpropertiesthatRigidbodyhas,too.Tosetthevelocityweneedtospecifythespeedineachaxis.However,thereisoneslightissue. Objectsin3Darespecifiedusingtwocoordinatemodels;localandworld.Inlo­calspace,coordinatesarerelativetotheobjectyouareworkingwith.Inworldspace,coordinatesareabsolute:up,forexample,isalwaysthesamedirectionforallobjects.Rigidbody.velocitymustbespecifiedinworldspace.So,whenassigningthevelocityyouneedtoconvertfromthez­axisinlocalspace(theforwarddirection)toitsrespec­tiveworldspacedirection.Youdothisusingthetransform.TransformDirectionfunctionwhichtakesaVector3asanargu­ment.Thevariablespeedisalsoexposed,sowecantweakitintheeditor.

Physics.IgnoreCollision( instantiatedProjectile. collider, transform.root.collider ); }}

Finally,weturnoffcollisionsbetweenthemissileandtheplayer.Ifwedidn’tdothisthemissilewouldcollidewiththeplayerwhenitwasinstantiated.LookthisupintheAPIunderIgnoreCollision.

HereisthefullcodetoMissileLauncher.js:

var projectile : Rigidbody;var speed = 20;

function Update(){ if( Input.GetButtonDown( "Fire1" ) ) { var instantiatedProjectile : Rigidbody = Instantiate( projectile, transform.position, transform.rotation );

instantiatedProjectile.velocity = transform.TransformDirection( Vector3( 0, 0, speed ) );

Physics.IgnoreCollision( instantiatedProjectile. collider, transform.root.collider ); }}

InsertthedescribedcodeintoMissileLauncherJavascriptandsaveit.

9

Page 10: FPS Tutorial 1

AttachtheMissileLauncherscripttotheLauncherintheFPSController.YoucanconfirmthattheMissileLauncherscriptisnowattachedtotheLauncherbyse­lectingLauncheritintheHierarchyViewandcheckingthattheMissileLauncherscriptisshownintheInspectorpanel.

Themissileprefabwepreviouslycreatedhasnotbeenassociatedwiththeprojectilevariableinourscript,sowemustdothisinsidetheeditor.TheprojectilevariableisoftypeRigidbody,sofirstwemustensurethatourmissilehasaRigidbodyattached.

ClickontheMissileintheProjectpanel,thenfromthemainmenubarselectComponents­>Physics­>Rigidbody.ThisaddsaRigidbodycomponenttothemissilewewanttofire.Wehavetodothisasthetypeofobjectwewanttofiremustmatchthetypeofthevariableweexposedinthescript.

Associatethemissilewiththeprojectilevariableinthescript.First,clickonLauncherintheHierarchypanel,noticethevariableProjectileintheMissile­LauncherscriptsectionintheInspectorpanel.NowdragtheMissileprefabfromtheProjectpanelanddropitontotheProjectilevariable.

Nowifyourunthegameyouwillbeabletoshootoutasmallspherewhichwillbeaffectedbygravity.

MissileexplosionsNowwe’regoingtoaddanexplosionwhenthemissilecollideswithanotherobject.Todothisweneedtoattachbehaviortothemissile,i.e.,createanewscriptandaddittotheMissilegameobject.

CreateanewblankscriptbyselectingAssets­>Create­>JavascriptandrenamethisnewscripttoProjectile.DragthenewscripttotheWeaponScriptsfolderintheProjectpanel.

SowhatdowewanttheProjectiletodo?Wewanttodetectwhenthemissilehashadacollisionandcreateanexplosionatthatpoint.Let’slookatthecode:

var explosion : GameObject;

function OnCollisionEnter( collision : Collision ){

AnycodethatweputinsidetheOnCollisionEnterfunctionisexecutedwhenevertheobjectthatthescriptisattachedisincollisionwithanotherobject.

var contact : ContactPoint = collision.contacts[0];

10

Page 11: FPS Tutorial 1

ThemaintaskwewanttodoinsidetheOnCollisionEnterfunctionistoinstanti­ateanewexplosionatthelocationin3Dspacewhereverthemissilecollided.So,wheredidthecollisionhappen?ThefunctionOnCollisionEnterispassedaColli­

sionclasswhichcontainsthisinformation.ThepointatwhichthecollisionoccurredisstoredintheContactPointvariable.

var rotation = Quaternion.FromToRotation( Vector3.up, contact.normal ); var instantiatedExplosion : GameObject = Instantiate( explosion, contact.point, rotation );

HereweusetheInstantiatefunctiontocreateanexplosion.Weknowthatin­

stantiatetakes3parameters;(1)theobjecttoinstantiate,(2)the3Dposition,and(3)therotationoftheobject.

Wewillassignthistoagameobjectwithaparticlesystemlater.We’llalsowanttoassignthisusingtheeditor,sowe’llexposethisvariablebymakingitpublic(declaringitoutsideofanyfunction).

Thesecondparameter,the3DpointatwhichtoInstantiatetheexplosionwasdeterminedfromthecollisionclassinpoint2. 

Thethirdparameter,therotationtosettheexplosionto,needssomeexplanation.Wewanttherotationoftheexplosionsothatthey­axisoftheexplosionfollowsalongthesurfacenormalofthesurfacethemissilecollidedwith.Thismeansthatforwallstheexplosionshouldfaceoutwards,forfloorsitwillfaceupwards.Sowhatwewanttodoistranslatethey­axisoftheexplosioninlocalspace(they­axisisupwards),tothesurfacenormal(inworldspace)oftheobjectthatwascollidedwith.Essentiallytherotationissaying‘makethey­axisoftheobjectpointinthesamedirectionasthenormalofthesurfacewithwhichitcollided’.

Destroy( gameObject );}

Finally,wewanttomakethemissiledisappearfromthegameasithasnowcollided,whichisdonebycallingtheDestroy()functionwithgameObjectasaparameter

(gameObjectdenotestheobjectthescriptisassociatedwith).

HereisthefullcodetoProjectile.js:

var explosion : GameObject;

11

Page 12: FPS Tutorial 1

function OnCollisionEnter( collision : Collision ){ var contact : ContactPoint = collision.contacts[0];

var rotation = Quaternion.FromToRotation( Vector3.up, contact.normal ); var instantiatedExplosion : GameObject = Instantiate( explosion, contact.point, rotation );

Destroy( gameObject );}

AddthecodeintotheProjectileJavascriptandsaveit.

AttachtheProjectileJavascripttotheMissileprefabbyselectingComponent­>Scripts­>Projectile.

Nowwehavetocreatetheexplosionthatwewanttooccurwheneverthemissilecol­lides.

First,createanewPrefab(callitExplosion)thatwillstoretheexplosionasset.

Thestandardassetscontainaniceexplosionprefabwithaparticlesystemandalightaroundtheexplosion.DragtheexplosionprefabunderStandardAssets/Particles/explosionintotheHierarchyView.

Adjustthesettingsontheexplosionuntilyou’rehappywithhowitlooks,thendragtheExplosionfromtheHierarchyviewontotheExplosionPrefabintheProjectpanel.

Nowwecanassigntheexplosiontothemissile:

EnsuringthatMissileprefabisselected,fillintheExplosionvariablebydraggingtheExplosionobjectintheProjectpanelontotheMissile’sExplosionvariableintheInspectorpanel.

DefiningExplosionBehaviorNowwehavetocreateonemorescriptwhichwilldefinethebehavioroftheexplo­sionitself.

Createanewscript,callitExplosion,andputitintheWeaponsfolder.DoubleclickontheExplosionscripttoeditit.

 

AnothercommonfunctiontypeforscriptsiscalledStart().Codeplacedinsidehere

isexecutedonlyoncewhentheobjectitbelongstoisinstantiated.Allwewanttodofornowistodeletetheexplosionfromthegameafteracertainamountoftime.To

12

Page 13: FPS Tutorial 1

dothisweusetheDestroy()functionwithasecondparameterwhichspecifieshowlongtowaitbeforedeleting.

var explosionTime = 1.0;

function Start(){ Destroy( gameObject, explosionTime );}

TheexplosionTimevariableisexposedtotheUnityeditorsoitcanbeeasilytweaked.

InserttheabovecodeintotheExplosionscript,deletingtheUpdate()functionintheprocess.

AttachtheExplosionscripttotheExplosionprefabbyfirstclickingontheExplo­sionprefabandthenselectingComponents­>Scripts­>Explosion.

Noticehowwe’vetriedtogroupthebehaviorasneatlyaspossibly,codethatrelatestotheexplosioniscontainedwithinthescriptthatisattachedtotheExplosionprefab.

Runthegameandwhereveryourmissilecollideswiththeenvironment,youshouldseetheexplosionparticlesystemforaperiodoftime.

SoundeffectsOurgameworldhasbeenalittlequietsofar,let’saddasoundeffecttoourexplosioneffect.

Firstlet’sassignanaudiocliptotheExplosionprefab.

ToallowtheExplosionobjecttobeabletoacceptanaudioclip,weaddtheAudioSourcecomponenttoitfromthemainmenu(Component­>Audio­>AudioSource).You’llnoticeoneofthepropertiesofthiscomponentistheAudioClip.

Assign"RocketLauncherImpact"totheExplosionprefab’sAudioClipexposedvariable.Unitycanplaymanydifferentaudioformats.

Runthegameagainandourexplosionsoundeffectshouldbeheardwheneachmissileimpact.

AddingaGUINowlet’saddagraphicaluserinterface(GUI),morecommonlyknownasaheadsupdisplay(HUD)tothegame.OursimpleGUIisonlygoingtocontainacrosshair.

13

Page 14: FPS Tutorial 1

AddingacrosshairCreateadirectorycalledGUIinyourprojectview.

Createanewscript,callitCrosshairanddragittotheGUIfolder.

EnterthefollowingcodeintoCrosshair.js:

var crosshairTexture : Texture2D;var position : Rect;

function Start(){ position = Rect( ( Screen.width - crosshairTexture.width ) / 2, ( Screen.height - crosshairTexture.height ) / 2, crosshairTexture.width, crosshairTexture.height );}

function OnGUI(){ GUI.DrawTexture( position, crosshairTexture );}

 

Firstwecreatetwovariables.Thefirstvariableiswherewe’regoingtoputtheimagethatwe’regoingtouseforourtexture.Thesecondvariableistherectanglewhichwillstorewheretopositionthetextureonthescreen. 

InsideoftheStart()functionwecalculatewherethetexturewillbedrawn.Insideoftheconstructorwehave4parameterswhichdeterminewheretherectangleislocatedandhowlargeitis.Thefirstparametertellsuswheretheleftsideoftherectangleis.Thesecondparametersetsthebottomoftherectangle.Thethirdandfourthparame­tersdeterminethewidthandheightoftherectangle.

InsideOnGUI()weusethefunctionalityoftheGUIclasstodrawitemsonscreen.InthiscasewecallDrawTexture()andpassitthepositionandcrosshairTexture.Thisfunctionwillthendrawourcrosshairinthecenterofthescreen.

Savethescript.

Createanewemptygameobjectandrenameit“GUI”.

DragyourCrosshairscriptontotheGUIgameobject.

SelecttheGUIgameobjectandthendragtheaimtexturefoundatTextures/aimfromtheProjectviewtotheCrosshairTexturevariableintheInspector

Pressplayandthereshouldbeacrosshairinthecenterofthegamescreen

14

Page 15: FPS Tutorial 1

PhysicsNowwewantobjectsinourenvironmenttobehaveasnaturallyaspossible,thisisachievedbyaddingphysics.Inthissectionwe’regoingtoaddobjectstotheenviron­mentwhichwillmovewhenhitwithourmissile.Firsttherearesomenewtermstoexplain.

UpdatePreviously,wehaveenteredcodeinsideanUpdatefunction,sothatwecanexecutethatcodeeveryframe.Oneexamplewastodetectiftheuserhadhitthefirebutton.However,framerateisnotaregularvalueasitisdependentonthecomplexityofthesceneetc.Thisirregulartimingbetweenframescanleadtounstablephysics.There­fore,wheneveryouwanttoupdateobjectsinyourgamewhichinvolvephysics(rigid­bodies),codeshouldbeplacedinsideaFixedUpdatefunction.ThedeltaTimevalue

inUnityisusedtodeterminethetimetakenbetweenrenderingtwoconsecutiveframes.

AgeneraldistinctionbetweenUpdateandFixedUpdatefunctionsisasfollows:

• Update()­codeinsidethefunctiontypicallyupdatesplayerbehavior,gamelogic,

etc.ThevalueofdeltaTimeisnotconsistentwhenusedwithinthisfunction.

• FixedUpdate()­codeinsidethisfunctiontypicallyupdatesrigidbodiesovertime(physicsbehavior).ThedeltaTimealwaysreturnsthesamevaluewhencalledwithinaFixedUpdatefunction.

 

ThefrequencywithwhichFixedUpdateiscalledisspecifiedbytheFixedTimestep

propertyinmenuoptionEdit­>ProjectSettings­>Timeandcanalsobealtered.This

15

Page 16: FPS Tutorial 1

propertycontainsthetimeinsecondstogettheframespersecondvalueandtakethereciprocalofthisvalue.

TIP WhenmodifyingthevalueforFixedTimestep(effectivelyframespersecond),becarefultostrikeabalance;asmallertimestepwillgivemorestablephysics(moreaccuracy),howeverthegameperformancewillsuffer.Ensurethatthegamerunsquicklyandthephysicsseemrealistic.

Thefinaltermtoexplaininthissectionisyield.Thiscanbethoughtofasastate­menttopauseexecutionofthecurrentfunction.

Solet’sgetbacktoourgame,whatdowewanttodo:

• Allowtheusertofireamissile(alreadydone).

• Ifthemissilecollideswithanotherrigidbody,determineifthereareanyotherobjectsinthevicinitywhichhaverigidbodiesattached.

• Foreachrigidbodywithintheforceoftheexplosion,givethemaforceintheupwardsdirection,causingthemtoreacttothemissile.

Let’slookatthecodefortheupdatedExplosionJavascript:

var explosionTime = 1.0;var explosionRadius = 5.0;var explosionPower = 2000.0;

function Start(){ //Destroy the explosion in x seconds, //this will give the particle system and audio enough time to finish playing Destroy( gameObject, explosionTime );

//Find all nearby colliders var colliders : Collider[] = Physics.OverlapSphere( transform.position, explosionRadius );

Firstwedetermineifthereareanyobjectswithcollidersclosetowherethemissilelanded.TheclassfunctionPhysics.OverlapSphere()takestwoparameters:a3Dpositionandradiusandreturnsanarrayofcolliderswhicharecontainedwithinthedefinedsphere.

//Apply a force to all surrounding rigid bodies. for( var hit in colliders ) {

16

Page 17: FPS Tutorial 1

Oncethearrayhasbeenobtained,eachoftherigidbodiesattachedtothecolliderscanbegivenaforceinacertaindirection.

if( hit.rigidbody ) { hit.rigidbody.AddExplosionForce( explosionPower, transform.position, explosionRadius ); } }

Wethenaddaforce(explosionPower)intheupwardsdirection(y­axis),attheloca­tionwherethemissilelanded(transform.position).However,astheeffectofexplo­sionsdiminishoverdistance,theforceshouldnotbeconstantovertheentireradius.Rigidbodiesclosertotheedgeofthecircumferenceshouldhavealessereffectap­plied thanobjectsattheepicenteroftheexplosion.Thiseffectistakenintoconsidera­tionbythisfunction.TheexposedvariablesexplosionPowerandexplosionRadiuscanbeeasilytweakedtocreateasuitableeffect.

//If we have a particle emitter attached, emit particles for .5 seconds if( particleEmitter ) { particleEmitter.emit = true; yield WaitForSeconds( 0.5 ); particleEmitter.emit = false; }}

 

IfaparticleemitterisattachedtoourExplosionprefabthenstartemittingparticles,waitfor0.5seconds(yield),andthenstopitemitting.

HereisthefullcodetoExplosion.js:

var explosionTime = 1.0;var explosionRadius = 5.0;var explosionPower = 2000.0;

function Start(){ //Destroy the explosion in x seconds, //this will give the particle system and audio enough time to finish playing Destroy( gameObject, explosionTime );

17

Page 18: FPS Tutorial 1

//Find all nearby colliders var colliders : Collider[] = Physics.OverlapSphere( transform.position, explosionRadius );

//Apply a force to all surrounding rigid bodies. for( var hit in colliders ) { if( hit.rigidbody ) { hit.rigidbody.AddExplosionForce( explosionPower, transform.position, explosionRadius ); } }

//If we have a particle emitter attached, emit particles for .5 seconds if( particleEmitter ) { particleEmitter.emit = true; yield WaitForSeconds( 0.5 ); particleEmitter.emit = false; }}

UpdatetheExplosionJavascriptwiththenewcodeandsavethescript.

Let’screateobjectstoshoot.Createacubeinthesceneandattacharigidbody.Duplicatethecubeseveraltimesandscatterthemaround.

Trythegameagainandshootobjectswhichhaverigidbodiesattached.Theyshouldnowreactwithanupwardsforce.Also,trytonotshoottheobjectsdi­

18

Page 19: FPS Tutorial 1

rectly,butclosetothem.Thiswillclearlydemonstratehowtheupwardsexplo­sionforceisappliedoveraradiusandnotonlytoeachobjetdirectly.

Saveyourscene.

AcknowledgmentsSpecialthanksgotoJoachimAnte(code)andEthanVosburgh(graphics)fortheirhelpinthemakingofthistutorial.

Thenexttutorialintheserieswillshowyouhowtobuilduponthesefunda­mentalsbyintroducingmoreadvancedconceptssuchasAIandmultipleweapons.

19