Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such...
Transcript of Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such...
![Page 1: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/1.jpg)
http://freepdf-books.com
![Page 2: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/2.jpg)
http://freepdf-books.com
![Page 3: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/3.jpg)
Unity5GameOptimization
http://freepdf-books.com
![Page 4: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/4.jpg)
TableofContents
Unity5GameOptimization
Credits
AbouttheAuthor
Acknowledgments
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.DetectingPerformanceIssues
TheUnityProfiler
LaunchingtheProfiler
Editororstandaloneinstances
Editorprofiling
TheUnityWebplayerconnection
RemoteconnectiontoaniOSdevice
RemoteconnectiontoanAndroiddevice
TheProfilerwindow
http://freepdf-books.com
![Page 5: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/5.jpg)
Controls
CPUArea
TheGPUArea
TheRenderingArea
TheMemoryArea
TheAudioArea
ThePhysics3D/2DArea
Bestapproachestoperformanceanalysis
Verifyingscriptpresence
Verifyingscriptcount
Minimizingongoingcodechanges
Minimizinginternaldistractions
Minimizingexternaldistractions
Targetedprofilingofcodesegments
Profilerscriptcontrol
CustomCPUProfiling
SavingandloadingProfilerdata
SavingProfilerdata
LoadingProfilerdata
FinalthoughtsonProfilingandAnalysis
UnderstandingtheProfiler
Reducingnoise
Focusingontheissue
Summary
2.ScriptingStrategies
CacheComponentreferences
ObtainingComponentsusingthefastestmethod
Removingemptycallbackdeclarations
AvoidingtheFind()andSendMessage()methodsatruntime
Staticclasses
SingletonComponents
http://freepdf-books.com
![Page 6: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/6.jpg)
Assigningreferencestopre-existingobjects
Aglobalmessagingsystem
Agloballyaccessibleobject
Registration
Messageprocessing
Implementingthemessagingsystem
Messagequeuingandprocessing
Implementingacustommessage
Messageregistration
Messagesending
Messagecleanup
Wrappingupthemessagingsystem
Disablingunusedscriptsandobjects
Disablingobjectsbyvisibility
Disablingobjectsbydistance
Considerusingdistance-squaredoverdistance
AvoidretrievingstringpropertiesfromGameObjects
Update,Coroutines,andInvokeRepeating
ConsidercachingTransformchanges
FasterGameObjectnullreferencechecks
Summary
3.TheBenefitsofBatching
DrawCalls
MaterialsandShaders
DynamicBatching
Vertexattributes
Uniformscaling
DynamicBatchingsummary
StaticBatching
TheStaticflag
Memoryrequirements
http://freepdf-books.com
![Page 7: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/7.jpg)
Materialreferences
StaticBatchingcaveats
EditModedebuggingofStaticBatching
Avoidinginstantiatingstaticmeshesatruntime
Visibilityandrendering
StaticBatchingsummary
Summary
4.KickstartYourArt
Audio
Loadingaudiofiles
Profilingaudio
Additionalloadingoptions
Encodingformatsandqualitylevels
Audioperformanceenhancements
MinimizeactiveAudioSourcecount
MinimizeAudioClipreferences
EnableForcetoMonofor3Dsounds
Resampletolowerfrequencies
Considerallencodingformats
Bewareofstreaming
ApplyFiltereffectsthroughMixergroupstoreduceduplication
Use“WWW.audioClip”responsibly
ConsiderAudioModulefilesforbackgroundmusic
Texturefiles
Compressionformats
Textureperformanceenhancements
ReduceTexturefilesize
UseMipMapswisely
Manageresolutiondownscalingexternally
AdjustAnisotropicFilteringlevels
ConsiderAtlasing
http://freepdf-books.com
![Page 8: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/8.jpg)
Adjustcompressionratesfornon-squareTextures
SparseTextures
ProceduralMaterials
Meshandanimationfiles
Reducingpolygoncount
TweakingMeshCompression
UseRead-WriteEnabledappropriately
Import/calculateonlywhat’sneeded
Considerbakedanimations
LetUnityoptimizemeshes
Combinemeshes
Summary
5.FasterPhysics
PhysicsEngineinternals
Physicsandtime
TheFixedUpdateloop
MaximumAllowedTimestep
Physicsupdatesandruntimechanges
StaticandDynamicColliders
Collisiondetection
Collidertypes
TheCollisionMatrix
Rigidbodyactiveandsleepingstates
Rayandobjectcasting
Physicsperformanceoptimizations
Scenesetup
Scaling
Positioning
Mass
UseStaticCollidersappropriately
OptimizetheCollisionMatrix
http://freepdf-books.com
![Page 9: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/9.jpg)
Preferdiscretecollisiondetection
ModifytheFixedUpdatefrequency
AdjusttheMaximumAllowedTimestep
Minimizecastandbounding-volumechecks
AvoidcomplexMeshColliders
Usesimplerprimitives
UsesimplerMeshColliders
Avoidcomplexphysicscomponents
Letphysicsobjectssleep
ModifySolverIterationCount
Optimizingragdolls
ReduceJointsandColliders
Avoidinter-ragdollcollisions
Disableorremoveinactiveragdolls
Knowwhentousephysics
ConsiderupgradingtoUnity5
Summary
6.DynamicGraphics
Profilingrenderingissues
GPUprofiling
TheFrameDebugger
Bruteforcetesting
CPU-bound
Multithreadedrendering
GPUSkinning
Frontendbottlenecks
LevelOfDetail
DisableGPUSkinning
Reducetessellation
Backendbottlenecks
Fillrate
http://freepdf-books.com
![Page 10: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/10.jpg)
Overdraw
OcclusionCulling
Shaderoptimization
ConsiderusingShadersintendedformobileplatforms
Usesmalldatatypes
Avoidchangingprecisionwhileswizzling
UseGPU-optimizedhelperfunctions
Disableunnecessaryfeatures
Removeunnecessaryinputdata
Onlyexposenecessaryvariables
Reducemathematicalcomplexity
Reducetexturelookups
Avoidconditionalstatements
Reducedatadependencies
SurfaceShaders
UseShader-basedLOD
Memorybandwidth
Uselesstexturedata
TestdifferentGPUTextureCompressionformats
Minimizetexturesampling
Organizeassetstoreducetextureswaps
VRAMlimits
Texturepreloading
Texturethrashing
LightingandShadowing
ForwardRendering
DeferredShading
VertexLitShading(legacy)
Real-timeShadows
Lightingoptimization
UsetheappropriateShadingMode
http://freepdf-books.com
![Page 11: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/11.jpg)
UseCullingMasks
UseBakedLightmaps
OptimizeShadows
Optimizinggraphicsformobile
MinimizeDrawCalls
MinimizetheMaterialcount
MinimizetexturesizeandMaterialcount
Maketexturessquareandpowerof2
UsethelowestpossibleprecisionformatsinShaders
AvoidAlphaTesting
Summary
7.MasterfulMemoryManagement
TheMonoplatform
Thecompilationprocess
ManualJITcompilation
Memoryusageoptimization
Unitymemorydomains
Nativememory
Managedmemory
Garbagecollection
Memoryfragmentation
Garbagecollectionatruntime
Threadedgarbagecollection
Garbagecollectiontactics
ValuetypesandReferencetypes
Passbyvalueandpassbyreference
StructsareValuetypes
ArraysareReferencetypes
StringsareimmutableReferencetypes
Stringconcatenation
Boxing
http://freepdf-books.com
![Page 12: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/12.jpg)
Theimportanceofdatalayout
TheUnityAPI
Theforeachloops
Coroutines
Closures
.NETlibraryfunctions
Temporaryworkbuffers
Objectpooling
Prefabpooling
PoolableComponents
ThePrefabpoolingsystem
Prefabpools
Objectspawning
Instanceprespawning
Objectdespawning
Prefabpooltesting
PrefabpoolingandSceneloading
Prefabpoolingsummary
ThefutureofMonoandUnity
Summary
8.TacticalTipsandTricks
Editorhotkeytips
GameObjects
SceneView
Arrays
Interface
Other
Editorinterfacetips
General
TheInspectorView
TheProjectView
http://freepdf-books.com
![Page 13: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/13.jpg)
TheHierarchyView
TheSceneandGameViews
PlayMode
Scriptingtips
General
Attributes
Variableattributes
Classattributes
Logging
Usefullinks
Customeditors/menustips
Externaltips
Othertips
Summary
Index
http://freepdf-books.com
![Page 14: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/14.jpg)
http://freepdf-books.com
![Page 15: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/15.jpg)
Unity5GameOptimization
http://freepdf-books.com
![Page 16: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/16.jpg)
http://freepdf-books.com
![Page 17: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/17.jpg)
Unity5GameOptimizationCopyright©2015PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:November2015
Productionreference:1281015
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78588-458-0
www.packtpub.com
http://freepdf-books.com
![Page 18: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/18.jpg)
http://freepdf-books.com
![Page 19: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/19.jpg)
CreditsAuthor
ChrisDickinson
Reviewers
CliffordChampion
Dr.SebastianT.Koenig
AcquisitionEditor
IndrajitDas
ContentDevelopmentEditor
AthiraLaji
TechnicalEditor
PrajaktaMhatre
CopyEditor
CharlotteCarneiro
ProjectCoordinator
BijalPatel
Proofreader
SafisEditing
Indexer
RekhaNair
Graphics
JasonMonteiro
ProductionCoordinator
AparnaBhagat
CoverWork
AparnaBhagat
http://freepdf-books.com
![Page 20: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/20.jpg)
http://freepdf-books.com
![Page 21: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/21.jpg)
AbouttheAuthorChrisDickinsongrewupinEnglandwithastrongpassionforscience,mathematics,andvideogames.Hereceivedhismaster’sdegreeinphysicswithelectronicsfromtheUniversityofLeedsin2005,andimmediatelytraveledtoCaliforniatoworkonscientificresearchintheheartofSiliconValley.Findingthatcareerpathunsuitable,hebeganworkinginthesoftwareindustry.
Overthelastdecade,hehasmadeacareerinsoftwaredevelopment,becomingaseniorsoftwaredeveloper.Chrishasprimarilyworkedinsoftwareautomationandinternaltesttooldevelopment,buthispassionforvideogamesneverfullyfaded.In2010,hetookthepathofdiscoveringthesecretsofgamedevelopmentand3Dgraphicsbycompletingaseconddegree—abachelor’sdegreeingameandsimulationprogramming.Heauthoredatutorialbookongamephysics(LearningGamePhysicswithBulletPhysicsandOpenGLbyPacktPublishing).Hecontinuestoworkinsoftwaredevelopment,creatingindependentgameprojectsinhissparetimewithtoolssuchasUnity3D.
http://freepdf-books.com
![Page 22: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/22.jpg)
http://freepdf-books.com
![Page 23: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/23.jpg)
AcknowledgmentsI’vemanagedtograspanabsolutelyridiculousamountofknowledgeinjust5years.Noneofthiswouldhavebeenpossiblewithouttheconstantmotivationfrommycoworkers,tutors,friends,andfamily.
ThankstomycomradesinsoftwaredevelopmentforbeingsounderstandingofmyerraticschedulewhileIwaslearninggamedevelopmentatschool.
Thanksalsotomycollegetutorsforhelpingacceleratemepastthecorematerialandlearnsomuchaboutgamedevelopmentsoquickly.
ThankstomyfriendsforalwaysbeingaconstantsourceofharassmentandinquisitivenessaboutwhatI’vebeenworkingon.
Thankstomyfamilyforgivingmetheopportunitytolearn,live,andlovesomuchinsuchashorttime.
Andofcourse,thankstomywonderfulwifeandbestfriend,Jamie,forbeingsocaringandsupportiveofallthelatenightsandhelpingmestaycreative.
http://freepdf-books.com
![Page 24: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/24.jpg)
http://freepdf-books.com
![Page 25: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/25.jpg)
AbouttheReviewersCliffordChampionhasabroadbackgroundinsoftwareengineering,withyearsofexperiencespanning3Dgames,Internetapplications,andartificialintelligence.HeholdsdegreesinmathematicsandcomputersciencefromUCLAandUCSD,respectively.Inthepast,CliffordworkedforvideogametechnologycompanyHavok(nowpartofMicrosoft),andinteractivemediaanddesigncompanyPlainJoeStudios.Currently,heleadsasoftwareteamatzSpace(zspace.com),aVRcompanyspecializingin3Dforclassroomsandindustry.
CliffordcanbefoundonTwitterat@duckmaestroandwelcomesdiscussionsonanytopic.
Dr.SebastianT.KoenigreceivedhisPhDinhumaninterfacetechnologyfromtheUniversityofCanterbury,NewZealand,developingaframeworkforindividualizedvirtualrealitycognitiverehabilitation.HeobtainedhisdiplomainpsychologyfromtheUniversityofRegensburg,Germany,intheareasofclinicalneuropsychologyandvirtualrealityrehabilitation.
SebastianisthefounderandCEOofKatanaSimulations,whereheoverseesthedesign,development,andevaluationofcognitiveassessmentandtrainingsimulations.Hisprofessionalexperiencespansover10yearsofclinicalworkincognitiverehabilitationandover8yearsofvirtualrealityresearch,development,andusertesting.Hehasextensiveexperienceasaspeakeratinternationalconferencesandasareviewerofscientificpublicationsintheareasofrehabilitation,cognitivepsychology,neuropsychology,softwareengineering,gamedevelopment,gameuserresearch,andvirtualreality.
Sebastianhasdevelopednumeroussoftwareapplicationsforcognitiveassessmentandtraining.Forhisworkonthevirtualmemorytask,hewasawardedtheprestigiousLavalVirtualAwardin2011,fortheMedicineandHealthcategory.OtherapplicationsofhisincludethevirtualrealityexecutivefunctionassessmentincollaborationwiththeKesslerFoundation,NewJersey,USA,andthepatent-pendingMicrosoftKinect-basedmotorandcognitivetrainingJewelMine/MysticIsleattheUSCInstituteforCreativeTechnologies,California,USA.
Hemaintainsthewebsiteatwww.virtualgamelab.com,whichfeatureshisresearchandhissoftwaredevelopmentprojects.HiswebsitealsocontainsacomprehensivelistoftutorialsfortheUnitygameengine.
http://freepdf-books.com
![Page 26: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/26.jpg)
http://freepdf-books.com
![Page 27: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/27.jpg)
www.PacktPub.com
http://freepdf-books.com
![Page 28: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/28.jpg)
Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
https://www2.packtpub.com/books/subscription/packtlib
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.
http://freepdf-books.com
![Page 29: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/29.jpg)
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser
http://freepdf-books.com
![Page 30: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/30.jpg)
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
http://freepdf-books.com
![Page 31: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/31.jpg)
http://freepdf-books.com
![Page 32: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/32.jpg)
PrefaceUserexperienceisacriticalcomponentofanygame.Userexperienceincludesnotonlyourgame’sstoryanditsgameplay,butalsohowsmoothlythegraphicsrun,howreliablyitconnectstomultiplayerservers,howresponsiveitistouserinput,andevenhowlargethefinalapplicationfilesizeisduetotheprevalenceofappstoresandclouddownloads.Thebarriertoenteringgamedevelopmenthasbeenloweredconsiderablythankstothereleaseofcheap,AAA-industry-levelgamedevelopmenttoolssuchasUnity.However,thefeaturesandqualityofthefinalproductthatourplayersexpectustoprovideisincreasingwitheverypassingday.Weshouldexpectthateveryfacetofourgamecanandwillbescrutinizedbyplayersandcriticsalike.
Thegoalsofperformanceoptimizationaredeeplyentwinedwithuserexperience.Poorlyoptimizedgamescanresultinlowframerates,freezes,crashes,inputlag,longloadingtimes,inconsistentandjitteryruntimebehavior,physicsenginebreakdowns,andevenexcessivelyhighbatterypowerconsumption(particularlyimportantinthiseraofmobiledevices).Havingjustoneoftheseissuescanbeagamedeveloper’sworstnightmareasreviewswilltendtofocusontheonethingthatwedidbadly,inspiteofallthethingsthatwedidwell.
Performanceisallaboutmakingthebestuseoftheavailableresources,whichincludestheCPUresourcessuchasCPUcyclesandmainmemoryspace,GraphicsProcessingUnit(GPU)resourcessuchasmemoryspace(VRAM)andmemorybandwidth,andsoon.Butoptimizationalsomeansmakingsurethatnosingleresourcecausesabottleneckataninappropriatetime,andthatthehighestprioritytasksgettakencareoffirst.Evensmall,intermittenthiccupsandsluggishnessinperformancecanpulltheplayeroutoftheexperience,breakingimmersionandlimitingourpotentialtocreatetheexperienceweintended.
Itisalsoimportanttodecidewhentotakeastepbackandstopmakingperformanceenhancements.Inaworldwithinfinitetimeandresources,therewouldalwaysbeanotherwaytomakeitbetter,faster,oreasiertomaintain.Theremustbeapointduringdevelopmentwherewedecidethattheproducthasreachedacceptablelevelsofquality.Ifnot,weriskdoomingourselvestoimplementingfurtherchangesthatresultinlittleornotangiblebenefit.
Thebestwaytodecideifaperformanceissueisworthfixingistoanswerthequestion“willtheusernoticeit?”.Iftheanswertothisquestionsis“no”,thenperformanceoptimizationwouldbeawastedeffort.Thereisanoldsayinginsoftwaredevelopment:
Prematureoptimizationistherootofallevil
Prematureoptimizationisthecardinalsinofreworkingandrefactoringcodetoenhanceperformancewithoutanyproofthatitisnecessary.Thiscouldmeaneithermakingchangeswithoutshowingthataperformanceproblemevenexists(answeringthequestionofwhetherornotitwouldbenoticeabletotheuser),ormakingchangesbecauseweonly
http://freepdf-books.com
![Page 33: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/33.jpg)
believeaperformanceissuemightstemfromaparticularareabeforeithasbeenproventobetrue.Makingthesemistakeshascostsoftwaredevelopers,asacollectivewhole,adepressingnumberofworkhoursfornothing.
Thisbookintendstogiveusthetools,knowledge,andskillsweneedtobothdetectandfixperformanceissuesinourapplication,nomatterwheretheystemfrom.ThiscouldbehardwarecomponentssuchastheCPU,GPU,orRAM,withinsoftwaresubsystemssuchasPhysics,Rendering,orwithintheUnityEngineitself.Inaddition,themoreresourceswesave,themorewecandowithintheUnityEnginewiththesamehardwaresystem,allowingustogeneratemoreinterestinganddynamicgameplay.
Thiswillgiveourgameabetterchanceofsucceedingandstandingoutfromthecrowdinamarketplacethatisinundatedwithnew,highqualitygameseverysingleday.
http://freepdf-books.com
![Page 34: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/34.jpg)
WhatthisbookcoversChapter1,DetectingPerformanceIssues,providesanexplorationoftheUnityProfilerandaseriesofmethodstoprofileourapplication,detectperformancebottlenecks,andperformrootcauseanalysis.
Chapter2,ScriptingStrategies,dealswiththebestpracticesforourUnityC#Scriptcode,minimizingComponentoverhead,improvinginter-objectcommunication,andmore.
Chapter3,TheBenefitsofBatching,exploresUnity’sDynamicandStaticBatchingsystemstoeasetheburdenontherenderingsystem.
Chapter4,KickstartYourArt,helpsyouunderstandtheunderlyingtechnologybehindourartassetsandlearnhowtoavoidcommonpitfallswithimporting,compression,andencoding.
Chapter5,FasterPhysics,isaboutinvestigatingthenuancesofUnity’sphysicssystemforboth3Dand2Dgames,andhowtoproperlyorganizeourphysicsobjectsforimprovedperformance.
Chapter6,DynamicGraphics,providesanin-depthexplorationoftherenderingsystem,andhowtoimproveapplicationsthatsufferrenderingbottlenecksintheGPU,orCPU,andspecializedtechniquesformobiledevices.
Chapter7,MasterfulMemoryManagement,examinestheinnerworkingsoftheUnityEngine,theMonoFramework,andhowmemoryismanagedwithinthesecomponentstoprotectourapplicationfromheapallocationsandruntimegarbagecollection.
Chapter8,TacticalTipsandTricks,dealswithamultitudeofusefultechniquesusedbyprofessionalstoimproveprojectworkflowandscenemanagement.
http://freepdf-books.com
![Page 35: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/35.jpg)
http://freepdf-books.com
![Page 36: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/36.jpg)
WhatyouneedforthisbookThemajorityofthisbookwillfocusonfeatureswithinthecontextofUnityversion5.x.MostofthetechniquescanbeappliedtoUnity4.xprojects,butmayrequireanupgradetoUnity4ProEditioninordertoaccesssomeofthem(suchasOcclusionCulling,StaticBatching,andeventheProfileritself).
http://freepdf-books.com
![Page 37: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/37.jpg)
http://freepdf-books.com
![Page 38: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/38.jpg)
WhothisbookisforThisbookisintendedforintermediateandadvancedUnitydeveloperswhohaveexperiencewithmostofUnity’sfeatureset,andthosewhowanttomaximizetheperformanceoftheirgameorsolveparticularbottlenecks.WhetherthebottleneckiscausedbyCPUoverload,runtimespiking,slowmemoryaccess,fragmentation,garbagecollection,poorGPUfillrate,ormemorybandwidth,thisbookwillteachyouthetechniquesyouneedtoidentifythesourceoftheproblemandhelpexploremultiplewaysofreducingtheirimpactonyourapplication.
FamiliaritywiththeC#languagewillbeneededforsectionsinvolvingscriptingandmemoryusage,andabasicunderstandingofcgwillbeneededforareasinvolvingShaderoptimization.
http://freepdf-books.com
![Page 39: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/39.jpg)
http://freepdf-books.com
![Page 40: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/40.jpg)
ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“ThemainUnitycallbackforapplicationupdatesistheUpdate()function.”
Ablockofcodeissetasfollows:
publicclassTestComponent:MonoBehaviour{
voidUpdate(){
if(Input.GetKeyDown(KeyCode.Space)){
PerformProfilingTest();
}
}
}
Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:
publicclassTestComponent:MonoBehaviour{
voidUpdate(){
if(Input.GetKeyDown(KeyCode.Space)){
PerformProfilingTest();
}
}
}
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:“ThethresholdvalueforthesleepingstatecanbemodifiedunderEdit|ProjectSettings|Physics|SleepThreshold.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
http://freepdf-books.com
![Page 41: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/41.jpg)
http://freepdf-books.com
![Page 42: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/42.jpg)
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.
Tosendusgeneralfeedback,simplye-mail<[email protected]>,andmentionthebook’stitleinthesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.
http://freepdf-books.com
![Page 43: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/43.jpg)
http://freepdf-books.com
![Page 44: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/44.jpg)
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
http://freepdf-books.com
![Page 45: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/45.jpg)
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
http://freepdf-books.com
![Page 46: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/46.jpg)
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.
Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.
http://freepdf-books.com
![Page 47: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/47.jpg)
PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.
http://freepdf-books.com
![Page 48: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/48.jpg)
QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<[email protected]>,andwewilldoourbesttoaddresstheproblem.
http://freepdf-books.com
![Page 49: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/49.jpg)
http://freepdf-books.com
![Page 50: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/50.jpg)
Chapter1.DetectingPerformanceIssuesPerformanceevaluationformostsoftwareproductsisaveryscientificprocess:determinethemaximumsupportedperformancemetrics(numberofconcurrentusers,maximumallowedmemoryusage,CPUusage,andsoon);performloadtestingagainsttheapplicationinscenariosthattrytosimulatereal-worldbehavior;gatherinstrumentationdatafromtestcases;analyzethedataforperformancebottlenecks;completearoot-causeanalysis;makechangesintheconfigurationorapplicationcodetofixtheissue;andrepeat.
Justbecausegamedevelopmentisaveryartisticprocessdoesnotmeanitshouldnotbetreatedinequallyobjectiveandscientificways.Ourgameshouldhaveatargetaudienceinmind,whocantellusthehardwarelimitationsourgamemightbeunder.Wecanperformruntimetestingofourapplication,gatherdatafrommultiplecomponents(CPU,GPU,memory,physics,rendering,andsoon),andcomparethemagainstthedesiredmetrics.Wecanusethisdatatoidentifybottlenecksinourapplication,performadditionalinstrumentationtodeterminetherootcauseoftheissue,andapproachtheproblemfromavarietyofangles.
Togiveusthetoolsandknowledgetocompletethisprocess,thischapterwillintroduceavarietyofmethodsthatwewillusethroughoutthebooktodeterminewhetherwehaveaperformanceproblem,andwheretherootcauseoftheperformanceissuecanbefound.Theseskillswillgiveusthetechniquesweneedtodetect,analyze,andprovethatperformanceissuesareplaguingourUnityapplication,andwhereweshouldbegintomakechanges.Indoingso,youwillprepareyourselvesfortheremainingchapterswhereyouwilllearnwhatcanbedoneabouttheproblemsyou’refacing.
WewillbeginwithanexplorationoftheUnityProfileranditsmyriadoffeatures.Wewillthenexploreahandfulofscriptingtechniquestonarrow-downoursearchfortheelusivebottleneckandconcludewithsometipsonmakingthemostofbothtechniques.
http://freepdf-books.com
![Page 51: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/51.jpg)
TheUnityProfilerTheUnityProfilerisbuiltintotheUnityEditoritself,andprovidesanexpedientwayofnarrowingoursearchforperformancebottlenecksbygeneratingusageandstatisticsreportsonamultitudeofUnity3Dcomponentsduringruntime:
CPUusagepercomponentoftheUnity3DEngineRenderingstatisticsGPUusageonseveralprogrammablepipelinestepsandstagesMemoryusageandstatisticsAudiousageandstatisticsPhysicsengineusageandstatistics
NoteWiththereleaseofUnity5.0,UnityTechnologieshasmadetheProfileravailabletoalldevelopersrunningthePersonalEdition(thenewnamefortheFreeEdition).
UsersrunningtheFreeEditionofUnity4musteitherupgradetoUnity5,orpurchasealicenseforUnity4ProEdition.
Thisadditionalreportingcomeswithaprice,however.Additionalinstrumentationflagswillbeenabledwithinthecompiler,generatingruntimeloggingeventsandadifferentlevelofautomatedcodeoptimizationwhiletheProfilerisinuse,whichcausessomeadditionalCPUandmemoryoverheadatruntime.Thisprofilingcostisnotcompletelynegligible,andislikelytocauseinconsistentbehaviorwhentheProfileristoggledonandoff.
Inaddition,weshouldalwaysavoidusingEditorModeforanykindofprofilingandbenchmarkingpurposesduetotheoverheadcostsoftheEditor;itsinterface,andadditionalmemoryconsumptionofvariousobjectsandcomponents.Itisalwaysbettertotestourapplicationinastandaloneformat,onthetargetdevice,inordertogetamoreaccurateandrealisticdatasample.
TipUserswhoarealreadyfamiliarwithconnectingtheUnityProfilertotheirapplicationsshouldskiptothesectiontitledTheProfilerwindow
http://freepdf-books.com
![Page 52: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/52.jpg)
LaunchingtheProfilerWewillbeginwithabrieftutorialonhowtoconnectourgametotheUnityProfilerwithinavarietyofcontexts:
Localinstancesoftheapplication,eitherthroughtheEditororstandaloneProfilingtheEditoritselfLocalinstancesoftheapplicationinUnityWebplayerRemoteinstancesoftheapplicationonaniOSdevice(theiPadtabletortheiPhonedevice)RemoteinstancesoftheapplicationonanAndroiddevice(atabletorphonedevicerunningAndroidOS)WewillbrieflycovertherequirementsforsettinguptheProfilerineachofthesecontexts.
EditororstandaloneinstancesTheonlywaytoaccesstheProfileristolaunchitthroughtheUnityEditorandconnectittoarunninginstanceofourapplication.Thisisthecasewhetherwe’rerunningourgamewithintheEditor,runningastandaloneapplicationonthelocalorremotedevice,orwhenwewishtoprofiletheEditoritself.
ToopentheProfiler,navigatetoWindow|ProfilerwithintheEditor.IftheEditorisalreadyrunninginPlayMode,thenwemayseereportingdatagatheringintheProfilerWindow:
TipToprofilestandaloneprojects,ensurethattheUseDevelopmentModeandAutoconnectProfilerflagsareenabledwhentheapplicationisbuilt.
SelectingwhethertoprofileanEditor-basedinstance(throughtheEditor’sPlayMode)orastandaloneinstance(separatelybuiltandrunninginthebackground)canbeachievedthroughtheActiveProfileroptionintheProfilerwindow.
http://freepdf-books.com
![Page 53: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/53.jpg)
TheUnityProfiler
EditorprofilingProfilingtheEditoritself,suchasprofilingcustomEditorScripts,canbeenabledwiththeProfileEditoroptionintheProfilerwindowasshowninthefollowingscreenshot.NotethatthisrequirestheActiveProfileroptiontobeconfiguredtoEditor.
TheUnityWebplayerconnectionTheProfilercanalsoconnecttoaninstanceoftheUnityWebplayerthatiscurrentlyrunninginabrowser.Thisenablesustoprofileourweb-basedapplicationinamorereal-worldscenariothroughthetargetbrowser,andtestmultiplebrowsertypesforinconsistenciesinbehavior.
1. EnsurethattheUseDevelopmentModeflagisenabledwhentheWebplayerapplicationisbuilt.
2. LaunchthecompiledWebplayerapplicationinabrowserand,whileitisactiveinthebrowserwindow,holdtheAltkey(OptionkeyonaMac)andright-clickontheWebplayerobjectwithinthebrowsertoopentheReleaseChannelSelectionmenu.ThenselecttheDevelopmentchannel,asshowninthefollowingscreenshot:
NoteNotethatchangingtheReleaseChanneloptionwillrestarttheWebplayerapplication.
http://freepdf-books.com
![Page 54: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/54.jpg)
3. Asshowninthefollowingscreenshot,opentheProfilerintheUnityEditorwithintheProfilerwindow,andthennavigatetoActiveProfiler|WindowsWebPlayer(COMPUTERNAME)orActiveProfiler|OSXWebPlayer(COMPUTERNAME),dependingontheOperatingSystem:
YoushouldnowseereportingdatacollectingintheProfilerwindow.
RemoteconnectiontoaniOSdeviceTheProfilercanalsobeconnectedtoanactiveinstanceoftheapplicationrunningremotelyonaniOSdevice,suchasaniPadoriPhone.ThiscanbeachievedthroughasharedWiFiconnection.FollowthegivenstepstoconnecttheProfilertoanAppledevice:
NoteNotethatremoteconnectiontoanAppledeviceisonlypossiblewhentheProfilerisrunningonanAppleMacdevice.
1. EnsurethattheUseDevelopmentModeandAutoconnectProfilerflagsareenabledwhentheapplicationisbuilt.
2. ConnectboththeiOSdeviceandMactoalocalorADHOCWiFinetwork.3. AttachtheiOSdevicetotheMacviatheUSBortheLightningcable.4. BeginbuildingtheapplicationwiththeBuild&Runoptionasnormal.
http://freepdf-books.com
![Page 55: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/55.jpg)
5. OpentheProfilerwindowintheUnityEditorandselectthedeviceunderActiveProfiler.
YoushouldnowseetheiOSdevice’sprofilingdatagatheringintheProfilerwindow.
TipTheProfilerusesports54998to55511tobroadcastprofilingdata.Makesuretheseportsareavailableforoutboundtrafficifthereisafirewallonthenetwork.
RemoteconnectiontoanAndroiddeviceTherearetwodifferentmethodsforconnectinganAndroiddevicetotheUnityProfiler:eitherthroughaWiFiconnectionorusingtheAndroidDebugBridge(ADB)tool.ADBisasuiteofdebuggingtoolsthatcomesbundledwiththeAndroidSDK.
FollowthegivenstepsforprofilingoveraWiFiconnection:
1. EnsurethattheUseDevelopmentModeandAutoconnectProfilerflagsareenabledwhentheapplicationisbuilt.
2. ConnectboththeAndroidanddesktopdevicestoalocalWiFinetwork.3. AttachtheAndroiddevicetothedesktopdeviceviatheUSBcable.4. BeginbuildingtheapplicationwiththeBuild&Runoptionasnormal.5. OpentheProfilerwindowintheUnityEditorandselectthedeviceunderActive
Profiler.
YoushouldnowseetheAndroiddevice’sprofilingdatagatheringintheProfilerWindow.
ForADBprofiling,followthegivensteps:
1. FromtheWindowscommandprompt,runtheadbdevicescommand,whichchecksifthedeviceisrecognizedbyADB(ifnot,thenthespecificdevicedriversforthedevicemayneedtobeinstalledand/orUSBdebuggingneedstobeenabledonthetargetdevice).
NoteNotethat,iftheadbdevicescommandisn’tfoundwhenitisrunfromthecommandprompt,thentheAndroidSDKfoldermayneedtobeappendedontotheEnvironment’sPATHvariable.
2. EnsurethattheUseDevelopmentModeandAutoconnectProfilerflagsareenabledwhentheapplicationisbuilt.
3. AttachtheAndroiddevicetothedesktopdeviceviathecable(forexample,USB).4. BeginbuildingtheapplicationwiththeBuild&Runoptionasnormal.5. OpentheProfilerWindowintheUnityEditorandselectthedeviceunderActive
Profiler.
YoushouldnowseetheAndroiddevice’sprofilingdatagatheringintheProfilerwindow.
http://freepdf-books.com
![Page 56: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/56.jpg)
TheProfilerwindowWewillnowcovertheessentialfeaturesoftheProfilerastheycanbefoundwithintheinterface.
NoteNotethatthissectioncoversfeaturesastheyappearintheUnityProfilerwithinUnity5.AdditionalfeatureswereaddedtotheProfilerwiththereleaseofUnity5;thesemaybedifferent,ornotexist,inUnity4’sProfiler.
TheProfilerwindowissplitintothreemainareas:
ControlsTimelineViewBreakdownView
Theseareasareasshowninthefollowingscreenshot:
ControlsThetopbarcontainsmultiplecontrolswecanusetoaffectwhatisbeingprofiledandhowdeeplyinthesystemdataisgatheredfrom.Theyare:
AddProfiler:Bydefault,theProfilershowsseveralofUnity’senginecomponentsintheTimelineView,buttheAddProfileroptioncanbeusedtoaddadditionalitems.
http://freepdf-books.com
![Page 57: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/57.jpg)
SeetheTimelineViewsectionforacompletelistofcomponentswecanprofile.Record:EnablingthisoptionwillmaketheProfilercontinuouslyrecordprofilingdata.NotethatdatacanonlyberecordedifPlayModeisenabled(andnotpaused)orifProfileEditorisenabled.DeepProfile:OrdinaryprofilingwillonlyrecordthetimeandmemoryallocationsmadebyanyUnitycallbackmethods,suchasAwake(),Start(),Update(),FixedUpdate(),andsoon.EnablingDeepProfilerecompilesourscriptstomeasureeachandeveryinvokedmethod.Thiscausesanevengreaterinstrumentationcostduringruntimeandusessignificantlymorememorysincedataisbeingcollectedfortheentirecallstackatruntime.Asaconsequence,DeepProfilingmaynotevenbepossibleinlargeprojectsrunningonweakhardware,asUnitymayrunoutofmemorybeforetestingcanevenbegin!
TipNotethatDeepProfilingrequirestheprojecttoberecompiledbeforeprofilingcanbegin,soitisbesttoavoidtogglingtheoptionduringruntime.
Becausethisoptionmeasuresallmethodsacrossourcodebaseinablindfashion,itshouldnotbeenabledduringmostofourprofilingtests.Thisoptionisbestreservedforwhendefaultprofilingisnotprovidingenoughdetail,orinsmalltestScenes,whichareusedtoprofileasmallsubsetofgamefeatures.
IfDeepProfilingisrequiredforlargerprojectsandScenes,buttheDeepProfileoptionistoomuchofahindranceduringruntime,thentherearealternativesthatcanbefoundintheupcomingsectiontitledTargetedProfilingofcodesegments.
ProfileEditor:ThisoptionenablesEditorprofiling—thatis,gatheringprofilingdatafortheUnityEditoritself.ThisisusefulinordertoprofileanycustomEditorScriptswehavedeveloped.
TipNotethatActiveProfilermustbesettotheEditoroptionforthisfeaturetowork.
ActiveProfiler:Thisdrop-downgloballyofferschoicestoselectthetargetinstanceofUnitywewishtoprofile;this,aswe’velearned,canbethecurrentEditorapplication,alocalstandaloneinstanceofourapplication,oraninstanceofourapplicationrunningonaremotedevice.Clear:ThisclearsallprofilingdatafromtheTimelineView.FrameSelection:TheFramecountershowshowmanyframeshavebeenprofiled,andwhichframeiscurrentlyselectedintheTimelineView.Therearetwobuttonstomovethecurrentlyselectedframeforwardorbackwardbyoneframe,andathirdbutton(theCurrentbutton)thatresetstheselectedframetothemostrecentframeandkeepsthatposition.ThiswillcausetheBreakdownViewtoalwaysshowtheprofilingdataforthecurrentframeduringruntimeprofiling.TimelineView:TheTimelineViewrevealsprofilingdatathathasbeencollectedduringruntime,organizedbyareasdependingonwhichcomponentoftheenginewasinvolved.
http://freepdf-books.com
![Page 58: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/58.jpg)
EachAreahasmultiplecoloredboxesforvarioussubsectionsofthosecomponents.Thesecoloredboxescanbetoggledtoreveal/hidethecorrespondingdatatypeswithintheTimelineView.
EachAreafocusesonprofilingdataforadifferentcomponentoftheUnityengine.WhenanAreaisselectedintheTimelineView,essentialinformationforthatcomponentwillberevealedintheBreakdownViewforthecurrentlyselectedframe.
TheBreakdownViewshowsverydifferentinformation,dependingonwhichAreaiscurrentlyselected.
TipAreascanberemovedfromtheTimelineViewbyclickingonthe‘X‘atthetoprightofanArea.AreascanberestoredtotheTimelineViewthroughtheAddProfileroptionintheControlsbar.
CPUArea
ThisAreashowsCPUUsageformultipleUnitysubsystemsduringruntime,suchasMonoBehaviourcomponents,cameras,somerenderingandphysicsprocesses,userinterfaces(includingtheEditor’sinterface,ifwe’rerunningthroughtheEditor),audioprocessing,theProfileritself,andmore.
TherearethreewaysofdisplayingCPUUsagedataintheBreakdownView:
HierarchyRawHierarchyTimeline
TheHierarchyModegroupssimilardataelementsandglobalUnityfunctioncallstogetherforconvenience—forinstance,renderingdelimiters,suchasBeginGUI()andEndGUI()callsarecombinedtogetherinthisMode.
TheRawHierarchyModewillseparateglobalUnityfunctioncallsintoindividuallines.ThiswilltendtomaketheBreakdownViewmoredifficulttoread,butmaybehelpfulifwe’retryingtocounthowmanytimesaparticularglobalmethodhasbeeninvoked,ordeterminingifoneofthesecallsiscostingmoreCPU/memorythanexpected.Forexample,eachBeginGUI()andEndGUI()callwillbeseparatedintodifferententries,possiblyclutteringtheBreakdownView,makingitdifficulttoread.
Perhaps,themostusefulmodefortheCPUAreaistheTimelineModeoption(nottobeconfusedwiththemainTimelineView).ThisModeorganizesCPUusageduringthecurrentframebyhowthecallstackexpandedandcontractedduringprocessing.BlocksatthetopofthisviewweredirectlycalledbytheUnityEngine(suchastheStart(),Awake(),orUpdate()methods),whileblocksunderneaththemaremethodsthatthosemethodshadcalled,whichcanincludemethodsonotherComponentsorobjects.
Meanwhile,thewidthofagivenCPUTimelineBlockgivesustherelativetimeittooktoprocessthatmethodcomparedtootherblocksaroundit.Inaddition,methodcallsthatconsumerelativelylittleprocessingtime,relativetothemoregreedymethods,areshown
http://freepdf-books.com
![Page 59: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/59.jpg)
asgrayboxestokeepthemoutofsight.
ThedesignoftheCPUTimelineModeoffersaverycleanandorganizedwayofdeterminingwhichparticularmethodinthecallstackisconsumingthemosttime,andhowthatprocessingtimemeasuresupagainstothermethodsbeingcalledduringthesameframe.Thisallowsustogaugewhichmethodisthebiggestculpritwithminimaleffort.
Forexample,let’sassumethatwearelookingataperformanceprobleminthefollowingscreenshot.Wecantell,withaquickglance,thattherearethreemethodsthatarecausingaproblem,andtheyeachconsumesimilaramountsofprocessingtime,duetohavingsimilarwidths.
Inthisexample,thegoodnewsisthatwehavethreepossiblemethodsthroughwhichtofindperformanceimprovements,whichmeanslotsofopportunitiestofindcodethatcanbeimproved.Thebadnewsisthatincreasingtheperformanceofonemethodwillonlyimproveaboutone-thirdofthetotalprocessingforthatframe.Hence,allthreemethodswillneedtobeexaminedandimprovedinordertominimizetheamountofprocessingtimeduringthisframe.
TheCPUAreawillbemostusefulduringChapter2,ScriptingStrategies.
TheGPUArea
TheGPUAreaissimilartotheCPUArea,exceptthatitshowsmethodcallsandprocessingtimeasitoccursontheGPU.RelevantUnitymethodcallsinthisAreawillrelatetocameras,drawing,opaqueandtransparentgeometry,lightingandshadows,andsoon.
TheGPUAreawillbebeneficialduringChapter6,DynamicGraphics.
TheRenderingArea
TheRenderingAreaprovidesrenderingstatistics,suchasthenumberofSetPasscalls,thetotalnumberofBatchesusedtorenderthescene,thenumberofBatchessavedfromDynamicandStaticBatching,memoryconsumedforTextures,andsoon.
TheRenderingAreawillbeusefulinChapter3,TheBenefitsofBatching.
http://freepdf-books.com
![Page 60: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/60.jpg)
TheMemoryArea
TheMemoryAreaallowsustoinspectmemoryusageoftheapplicationintheBreakdownViewintwodifferentways:
SimpleModeDetailedMode
TheSimpleModeprovidesonlyahigh-leveloverviewofmemoryconsumptionofcomponentssuchasUnity’slow-levelEngine,theMonoframework(totalheapsizethatwillbegarbage-collected),Graphics,Audio(FMOD),andevenmemoryusedtostoredatacollectedbytheProfiler.
TheDetailedModeshowsmemoryconsumptionofindividualgameobjectsandcomponents,forboththeirnativeandmanagedrepresentations.Italsohasacolumnexplainingthereasonforthatobjectconsumingmemoryandwhenitmightbede-allocated.
TheMemoryAreawillbethemainfocalpointofChapter7,MasterfulMemoryManagement.
TheAudioArea
TheAudioAreagrantsanoverviewofaudiostatisticsandcanbeusedbothtomeasureCPUusagefromtheaudiosystem,aswellastotalmemoryconsumedbyAudioSources(forbothplayingandpausedsources)andAudioClips.
TheAudioAreawillcomeinhandyasweexploreartassetsinChapter4,KickstartYourArt.
TipAudioisoftenoverlookedwhenitcomestoperformanceenhancements,butaudiocanbecomeofthebiggestsourcesofbottlenecksifitisnotmanagedproperly.It’sworthperformingoccasionalchecksontheAudiosystem’smemoryandCPUconsumptionduringdevelopment.
ThePhysics3D/2DArea
TherearetwodifferentPhysicsAreas,onefor3Dphysics(Nvidia’sPhysX)andanotherforthe2Dphysicssystem(Box2D)thatwasintegratedintotheUnityEngineinversion4.5.ThisAreaprovidesvariousphysicsstatisticssuchasRigidbody,Collider,andContactcounts.
WewillbemakinguseofthisAreainChapter5,FasterPhysics.
NoteAsofthepublicationofthistext,withUnityv5.2.2f1asthemostrecentversion,thePhysics3DAreaonlyprovidesahandfulofitems,whilethePhysics2DAreaprovidessignificantlymoreinformation.
http://freepdf-books.com
![Page 61: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/61.jpg)
http://freepdf-books.com
![Page 62: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/62.jpg)
BestapproachestoperformanceanalysisGoodcodingpracticesandprojectassetmanagementoftenmakefindingtherootcauseofaperformanceissuerelativelysimple,atwhichpointtheonlyrealproblemisfiguringouthowtoimprovethecode.Forinstance,ifthemethodonlyprocessesasinglegiganticforloop,thenitwillbeaprettysafeassumptionthattheproblemiseitherwiththeiterationofthelooporhowmuchworkisprocessedeachiteration.
Ofcourse,alotofourcode,whetherwe’reworkingindividuallyorinagroupsetting,isnotalwayswritteninthecleanestwaypossible,andweshouldexpecttohavetoprofilesomepoorcodingworkfromtimetotime.Sometimes,hack-ysolutionsareinevitable,andwedon’talwayshavethetimetogobackandrefactoreverythingtokeepupwithourbestcodingpractices.
It’seasytooverlooktheobviouswhenproblemsolvingandperformanceoptimizationisjustanotherformofproblemsolving.ThegoalistouseProfilersanddataanalysistosearchourcodebaseforcluesaboutwhereaproblemoriginates,andhowsignificantitis.It’softenveryeasytogetdistractedbyinvaliddataorjumptoconclusionsbecausewe’rebeingtooimpatientormissedasubtleclue.Manyofushaverunintooccasions,duringsoftwaredebugging,wherewecouldhavefoundtherootcauseoftheproblemmuchfasterifwehadsimplychallengedandverifiedourearlierassumptions.Alwaysapproachingdebuggingunderthebeliefthattheproblemishighlycomplexandtechnicalisagoodwaytowastevaluabletimeandeffort.Performanceanalysisisnodifferent.
Achecklistoftaskswouldbehelpfultokeepusfocusedontheissue,andnotwastetimechasing“ghosts”.Everyprojectisdifferentandhasadifferentsetofconcernsanddesignparadigms,butthefollowingchecklistisgeneralenoughthatitshouldbeabletoapplytoanyUnityproject:
VerifyingthetargetScriptispresentintheSceneVerifyingtheScriptappearsintheScenethecorrectnumberoftimesMinimizingongoingcodechangesMinimizinginternaldistractionsMinimizingexternaldistractions
http://freepdf-books.com
![Page 63: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/63.jpg)
VerifyingscriptpresenceSometimestherearethingsweexpecttosee,butdon’t.Theseareusuallyeasytonote,becausethehumanbrainisverygoodatpatternrecognition.Ifsomethingdoesn’tmatchtheexpectedpattern,thenittendstobeveryobvious.Meanwhile,therearetimeswhereweassumesomethinghasbeenhappening,butitdidn’t.Thesearegenerallymoredifficulttonotice,becausewe’reoftenscanningforthefirstkindofproblem.Verificationoftheintendedorderofeventsiscritical,orweriskjumpingtoconclusions,wastingvaluabletime.
InthecontextofUnity,thismeansitisessentialtoverifythatthescriptweexpecttoseetheeventcomingfromisactuallypresentintheScene,andthatthemethodcallshappenintheorderweintended.
ScriptpresencecanbequicklyverifiedbytypingthefollowingintotheHierarchywindowtextbox:
t:<monobehaviourname>
Forexample,typingt:mytestmonobehaviour(note:itisnotcase-sensitive)intotheHierarchytextboxwillshowashortlistofallGameObjectsthatcurrentlyhaveaMyTestMonobehaviourscriptattachedasaComponent.
TipNotethatthisshortlistfeaturealsoincludesanyGameObjectswithComponentsthatderivefromthegivenscriptname.
http://freepdf-books.com
![Page 64: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/64.jpg)
Weshouldalsodouble-checkthattheGameObjectstheyareattachedtoarestillenabled,sincewemayhavedisabledthemduringearliertesting,orsomeone/somethinghasaccidentallydeactivatedtheobject.
http://freepdf-books.com
![Page 65: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/65.jpg)
VerifyingscriptcountIfweassumethataMonoBehaviour,whichiscausingperformanceproblems,onlyappearsonceinourScene,thenwemayignorethepossibilitythatconflictingmethodinvocationsarecausingabottleneck.Thisisdangerous;whatifsomeonecreatedtheobjecttwiceormoreintheScenefile,orweaccidentallyinstantiatedtheobjectmorethanoncefromcode?WhatweseeintheProfilercanbeaconsequenceofthesameexpensivemethodbeinginvokedmorethanonceatthesametime.Thisissomethingwewillwanttodouble-checkusingthesameshortlistmethodasbefore.
IfweexpectedonlyoneoftheComponentstoappearintheScene,buttheshortlistrevealedmorethanone,thenwemaywishtorethinkourearlierassumptionsaboutwhat’scausingthebottlenecks.Wemaywishtowritesomeinitializationcodethatpreventsthisfromeverhappeningagain,and/orwritesomecustomEditorhelperstodisplaywarningstoanyleveldesignerswhomightbemakingthismistake.
Preventingcasualmistakeslikethisisessentialforgoodproductivity,sinceexperiencetellsusthat,ifwedon’texplicitlydisallowsomething,thensomeone,somewhere,atsomepoint,forwhateverreason,willdoitanyway,andcostusagooddealofanalysiswork.
http://freepdf-books.com
![Page 66: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/66.jpg)
MinimizingongoingcodechangesMakingcodechangestotheapplicationinordertohuntdownperformanceissuesisnotrecommended,asthechangesareeasytoforgetastimewearson.Addingdebugloggingstatementstoourcodecanbetempting,butrememberthatitcostsustimetointroducethesecalls,recompileourcode,andremovethesecallsonceouranalysisiscomplete.Inaddition,ifweforgettoremovethem,thentheycancostunnecessaryruntimeoverheadinthefinalbuildsinceUnity’sDebugloggingcanbeprohibitivelyexpensiveinbothCPUandmemory.
Onewaytocombatthisproblemistouseasource-controltooltodifferentiatethecontentsofanymodifiedfiles,and/orrevertthembacktotheiroriginalstate.Thisisanexcellentwaytoensurethatunnecessarychangesdon’tmakeitintothefinalversion.
Makinguseofbreakpointsduringruntimedebuggingisthepreferredapproach,aswecantracethefullcallstack,variabledata,andconditionalcodepaths(forexample,if-elseblocks),withoutriskinganycodechangesorwastingtimeonrecompilation.
http://freepdf-books.com
![Page 67: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/67.jpg)
MinimizinginternaldistractionsTheUnityEditorhasitsownlittlequirksandnuancesthatcanleaveusconfusedbycertainissues.
Firstly,ifasingleframetakesalongtimetoprocess,suchthatourgamenoticeablyfreezes,thentheProfilermaynotbecapableofpickinguptheresultsandrecordingthemintheProfilerwindow.Thiscanbeespeciallyannoyingifwewishtocatchdataduringapplication/Sceneinitialization.Theupcomingsection,CustomCPUProfiling,willoffersomealternativestoexploretosolvethisproblem.
Onecommonmistake(thatIhaveadmittedlyfallenvictimtomultipletimesduringthewritingofthisbook)is:ifwearetryingtoinitiateatestwithakeystrokeandwehavetheProfileropen,weshouldnotforgettoclickbackintotheEditor’sGamewindowbeforetriggeringthekeystroke!IftheProfileristhemostrecentlyclickedwindow,thentheEditorwillsendkeystrokeeventstothat,insteadoftheruntimeapplication,andhencenoGameObjectwillcatchtheeventforthatkeystroke.
VerticalSync(otherwiseknownasVSync)isusedtomatchtheapplication’sframeratetotheframerateofthedeviceitisbeingdisplayedon(forexample,themonitor).ExecutingtheProfilerwiththisfeatureenabledwillgeneratealotofspikesintheCPUusageareaundertheheadingWaitForTargetFPS,astheapplicationintentionallyslowsitselfdowntomatchtheframerateofthedisplay.Thiswillgenerateunnecessaryclutter,makingithardertospottherealissue(s).WeshouldmakesuretodisabletheVSynccoloredboxundertheCPUAreawhenwe’reonthelookoutforCPUspikesduringperformancetests.WecandisabletheVSyncfeatureentirelybynavigatingtoEdit|ProjectSettings|Qualityandthenthesubpageforthecurrentlyselectedbuildplatform.
Weshouldalsoensurethatadropinperformanceisn’tadirectresultofamassivenumberofexceptionsanderrormessagesappearingintheEditorconsole.Unity’sDebug.Log(),andsimilarmethodssuchasDebug.LogError(),Debug.LogWarning(),andsoon,arenotoriouslyexpensiveintermsofCPUusageandheapmemoryconsumption,whichcanthencausegarbagecollectiontooccurandevenmorelostCPUcycles.
ThisoverheadisusuallyunnoticeabletoahumanbeinglookingattheprojectinEditorMode,wheremosterrorscomefromthecompilerormisconfiguredobjects.Buttheycanbeproblematicwhenusedduringanykindofruntimeprocess;especiallyduringprofiling,wherewewishtoobservehowthegamerunsintheabsenceofexternaldisruptions.Forexample,ifwearemissinganobjectreferencethatweweresupposedtoassignthroughtheEditoranditisbeingusedinanUpdate()method,thenasingleMonoBehaviourcouldbethrowingnewexceptionseverysingleupdate.Thisaddslotsofunnecessarynoisetoourprofilingdata.
NotethatwecandisabletheInfoorWarningcheckboxes(showninthefollowingscreenshot)fortheprojectduringPlayModeruntime,butitstillcostsCPUandmemorytoexecutedebugstatements,eventhoughtheyarenotbeingrendered.Itisoftenagoodpracticetokeepalloftheseoptionsenabled,toverifythatwe’renotmissinganythingimportant.
http://freepdf-books.com
![Page 68: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/68.jpg)
http://freepdf-books.com
![Page 69: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/69.jpg)
MinimizingexternaldistractionsThisoneissimplebutabsolutelynecessary.Weshoulddouble-checkthattherearenobackgroundprocesseseatingawayCPUcyclesorconsumingvastswathesofmemory.Beinglowonavailablememorywillgenerallyinterferewithourtesting,asitcancausemorecachemisses,hard-driveaccessforvirtualmemorypage-fileswapping,andgenerallyslowresponsivenessoftheapplication.
http://freepdf-books.com
![Page 70: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/70.jpg)
http://freepdf-books.com
![Page 71: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/71.jpg)
TargetedprofilingofcodesegmentsIfourperformanceproblemisn’tsolvedbytheabovechecklist,thenweprobablyhavearealissueonourhandsthatdemandsfurtheranalysis.Thetaskoffiguringoutexactlywheretheproblemislocatedstillremains.TheProfilerwindowiseffectiveatshowingusabroadoverviewofperformance;itcanhelpusfindspecificframestoinvestigateandcanquicklyinformuswhichMonoBehaviourand/ormethodmaybecausingissues.However,wemuststilldetermineexactlywheretheproblemexists.Weneedtofigureoutiftheproblemisreproducible,underwhatcircumstancesaperformancebottleneckarises,andwhereexactlywithintheproblematiccodeblocktheissueisoriginatingfrom.
Toaccomplishthese,wewillneedtoperformsomeprofilingoftargetedsectionsofourcode,andthereareahandfulofusefultechniqueswecanemployforthistask.ForUnityprojects,theyessentiallyfitintotwocategories:
ControllingtheProfilerfromscriptcodeCustomtimingandloggingmethods
NoteNotethatthefollowingsectionmostlyfocussesonhowtoinvestigateScriptingbottlenecksthroughC#code.Detectingthesourceofbottlenecksinotherenginecomponentswillbediscussedintheirrelatedchapters.
http://freepdf-books.com
![Page 72: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/72.jpg)
ProfilerscriptcontrolTheProfilercanbecontrolledinscriptcodethroughthestaticProfilerclass.ThereareseveralusefulmethodsintheProfilerclassthatwecanexplorewithintheUnitydocumentation,butthemostimportantmethodsarethedelimitermethodsthatactivateanddeactivateprofilingatruntime:Profiler.BeginSample()andProfiler.EndSample().
TipNotethatthedelimitermethods,BeginSample()andEndSample(),areonlycompiledindevelopmentbuilds,andassuchtheycausenooverheadinthefinalbuild.Therefore,itissafetoleavetheminourcodebaseifwewishtousethemforprofilingtestsatalaterdate.
TheBeginSample()methodhasanoverloadthatallowsacustomnameforthesampletoappearintheCPUUsageArea’sHierarchyModeview.Forexample,thefollowingcodewillprofileinvocationsofthismethodandmakethedataappearintheBreakdownViewunderacustomheading:
voidDoSomethingCompletelyStupid(){
Profiler.BeginSample("MyProfilerSample");
List<int>listOfInts=newList<int>();
for(inti=0;i<1000000;++i){
listOfInts.Add(i);
}
Profiler.EndSample();
}
TipDownloadingtheexamplecode
Youcandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
Weshouldexpectthatinvokingthispoorlydesignedmethod(itgeneratesalistcontainingamillionintegers,andthendoesabsolutelynothingwithit)willcauseahugespikeinCPUusage,chewupseveralMegabytesofmemory,andappearintheProfilerBreakdownViewundertheheadingMyProfilerSampleasthefollowingscreenshotshows:
http://freepdf-books.com
![Page 73: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/73.jpg)
NotethatthesecustomsamplenamesdonotappearattherootofthehierarchywhenweperformDeepProfiling.ThefollowingscreenshotshowstheBreakdownViewforthesamecodeunderDeepProfiling:
Notehowthecustomnameforthesampledoesnotappearatthetopofthesample,wherewemayexpectitto.It’sunclearwhatcausesthisphenomenon,butthiscancausesomeconfusionwhenexaminingtheDeepProfilingdatawithinHierarchyMode,soitisgoodtobeawareofit.
http://freepdf-books.com
![Page 74: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/74.jpg)
CustomCPUProfilingTheProfilerisjustonetoolatourdisposal.Sometimes,wemaywanttoperformcustomizedprofilingandloggingofourcode.Maybewe’renotconfidenttheUnityProfilerisgivingustherightanswer,maybeweconsideritsoverheadcosttoogreat,ormaybewejustlikehavingcompletecontrolofeverysingleaspectofourapplication.Whateverourmotivations,knowingsometechniquestoperformanindependentanalysisofourcodeisausefulskilltohave.It’sunlikelywe’llonlybeworkingwithUnityfortheentiretyofourgamedevelopmentcareers,afterall.
Profilingtoolsareverycomplex,soit’sunlikelywewouldbeabletogenerateacomparablesolutiononourownwithinareasonabletimeframe.WhenitcomestotestingCPUusage,allweneedisanaccuratetimingsystem,afast,low-costwayofloggingthatinformation,andsomepieceofcodetotestagainst.Itjustsohappensthatthe.NETlibrary(or,technically,theMonoframework)comeswithaStopwatchclassundertheSystem.Diagnosticsnamespace.WecanstopandstartaStopwatchobjectatanytime,andwecaneasilyacquireameasureofhowmuchtimehaspassedsincetheStopwatchwasstarted.
Unfortunately,thisclassisnotveryaccurate—itisaccurateonlytomilliseconds,ortenthsofamillisecondatbest.Countinghigh-precisionrealtimewithaCPUclockcanbeasurprisinglydifficulttaskwhenwestarttogetintoit;so,inordertoavoidadetaileddiscussionofthetopic,weshouldtrytofindawayfortheStopwatchclasstosatisfyourneeds.
Beforewegetobsessedwiththetopicofhighprecision,weshouldfirstaskourselvesifweevenneedit.Mostgamesexpecttorunat30FPS(frames-per-second)or60FPS,whichmeanstheyonlyhavearound33msor16ms,respectively,tocomputeeverythingfortheentireframe.So,hypothetically,ifweonlyneedtobringtheperformanceofaparticularcodeblockunder10ms,thenrepeatingthetestthousandsoftimestogetmicrosecondprecisionwouldn’treallytellusanythinguseful.
However,ifprecisionisimportant,thenoneeffectivewaytoincreaseitisbyrunningthesametestmultipletimes.Assumingthatthetestcodeblockisbotheasilyrepeatableandnotexceptionallylong,thenweshouldbeabletorunthousands,orevenmillions,oftestswithinareasonabletimeframeandthendividethetotalelapsedtimebythenumberoftestswejustperformedtogetamoreaccuratetimeforasingletest.
ThefollowingisaclassdefinitionforacustomtimerthatusesaStopwatchtocounttimeforagivennumberoftests:
usingUnityEngine;
usingSystem;
usingSystem.Diagnostics;
usingSystem.Collections;
publicclassCustomTimer:IDisposable{
privatestringm_timerName;
privateintm_numTests;
http://freepdf-books.com
![Page 75: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/75.jpg)
privateStopwatchm_watch;
//givethetimeraname,andacountofthenumberoftestswe're
running
publicCustomTimer(stringtimerName,intnumTests){
m_timerName=timerName;
m_numTests=numTests;
if(m_numTests<=0)
m_numTests=1;
m_watch=Stopwatch.StartNew();
}
//calledwhenthe'using'blockends
publicvoidDispose(){
m_watch.Stop();
floatms=m_watch.ElapsedMilliseconds;
UnityEngine.Debug.Log(string.Format("{0}finished:{1:0.00}mstotal,
{2:0.000000}mspertestfor{3}tests",m_timerName,ms,ms/m_numTests,
m_numTests));
}
}
ThefollowingisanexampleoftheCustomTimerclassusage:
intnumTests=1000;
using(newCustomTimer("MyTest",numTests)){
for(inti=0;i<numTests;++i){
TestFunction();
}
}//thetimer'sDispose()methodisautomaticallycalledhere
Therearethreethingstonotewhenusingthisapproach.Firstly,weareonlymakinganaverageofmultiplemethodinvocations.Ifprocessingtimevariesenormouslybetweeninvocations,thenthatwillnotbewell-representedinthefinalaverage.Secondly,ifmemoryaccessiscommon,thenrepeatedlyrequestingthesameblocksofmemorywillresultinanartificiallyhighercachehitrate,whichwillbringtheaveragetimedownwhencomparedtoatypicalinvocation.Thirdly,theeffectsofJITcompilationwillbeeffectivelyhiddenforsimilarlyartificialreasonsasitonlyaffectsthefirstinvocationofthemethod.JITcompilationissomethingthatwillbecoveredinmoredetailinChapter7,MasterfulMemoryManagement.
Theusingblockistypicallyusedtosafelyensurethatunmanagedresourcesareproperlydestroyedwhentheygooutofscope.Whentheusingblockends,itwillautomaticallyinvoketheobject’sDispose()methodtohandleanycleanupoperations.Inordertoachievethis,theobjectmustimplementtheIDisposableinterface,whichforcesittodefinetheDispose()method.
However,thesamelanguagefeaturecanbeusedtocreateadistinctcodeblock,whichcreatesashort-termobject,whichthenautomaticallyprocessessomethingusefulwhenthecodeblockends.
Note
http://freepdf-books.com
![Page 76: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/76.jpg)
Notethattheusingblockshouldnotbeconfusedwiththeusingstatement,whichisusedatthestartofascriptfiletopullinadditionalnamespaces.It’sextremelyironicthatthekeywordformanagingnamespacesinC#hasanamingconflictwithanotherkeyword.
Asaresult,theusingblockandtheCustomTimerclassgiveusacleanwayofwrappingourtargettestcodeinawaywhichmakesitobviouswhenandwhereitisbeingused.
Anotherconcerntoworryaboutisapplicationwarmup.UnityhasasignificantstartupcostwhenaScenebegins,giventhenumberofcallstovariousGameObjects’Awake()andStart()methods,aswellasinitializationofothercomponentssuchasthePhysicsandRenderingsystems.Thisearlyoverheadmightonlylastasecond,butthatcanhaveasignificanteffectontheresultsofourtesting.Thismakesitcrucialthatanyruntimetestingbeginsaftertheapplicationhasreachedasteadystate.
Ifpossible,itwouldbewisetowrapthetargetcodeblockinanInput.GetKeyDown()methodcheckinordertohavecontroloverwhenitisinvoked.Forexample,thefollowingcodewillonlyexecuteourtestmethodwhentheSpaceBarispressed:
if(Input.GetKeyDown(KeyCode.Space)){
intnumTests=1000;
using(newCustomTimer("ControlledTest",numTests)){
for(inti=0;i<numTests;++i){
TestFunction();
}
}
}
TherearethreeimportantdesignfeaturesoftheCustomTimerclass:itonlyprintsasinglelogmessagefortheentiretest,onlyreadsthevaluefromtheStopwatchafterithasbeenstopped,andusesstring.Format()forgeneratingacustomstring.
Asexplainedearlier,Unity’sconsoleloggingmechanismisprohibitivelyexpensive.Asaresult,weshouldneverusetheseloggingmethodsinthemiddleofaprofilingtest(orevengameplay,forthatmatter).Ifwefindourselvesabsolutelyneedingdetailedprofilingdatathatprintsoutlotsofindividualmessages(suchasperformingatimingtestoneachiterationofaloop,tofindwhichiterationiscostingmoretimethantherest),thenitwouldbewisertocachetheloggingdataandprintitallattheend,astheCustomTimerclassdoes.Thiswillreduceruntimeoverhead,atthecostofsomememoryconsumption.ThealternativeisthatmanymillisecondsarelosttoprintingeachDebug.Log()messageinthemiddleofthetest,whichpollutestheresults.
ThesecondfeatureisthattheStopwatchisstoppedbeforethevalueisread.Thisisfairlyobvious;readingthevaluewhileitisstillcountingmightgiveusaslightlydifferentvaluethanstoppingitfirst.UnlesswedivedeepintotheMonoprojectsourcecode(andthespecificversionUnityuses),wemightnotknowtheexactimplementationofhowStopwatchcountstime,atwhatpointsCPUticksarecounted,andatwhatmomentsanyapplicationcontextswitchingistriggeredbytheOS.So,itisoftenbettertoerronthesideofcautionandpreventanymorecountingbeforeweattempttoaccessthevalue.
http://freepdf-books.com
![Page 77: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/77.jpg)
Finally,there’stheusageofstring.Format().ThiswillbecoveredinmoredetailinChapter7,MasterfulMemoryManagement,buttheshortexplanationisthatthismethodisusedbecausegeneratingcustomstringsusingthe+operatorresultsinasurprisinglylargeamountofmemoryconsumption,whichattractstheattentionofthegarbagecollector.Thiswouldconflictwithourgoalofachievingaccuratetimingandanalysis.
http://freepdf-books.com
![Page 78: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/78.jpg)
http://freepdf-books.com
![Page 79: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/79.jpg)
SavingandloadingProfilerdataTheUnityProfilercurrentlyhasafewfairlysignificantpitfallswhenitcomestosavingandloadingProfilerdata:
Only300framesarevisibleintheProfilerwindowatonceThereisnowaytosaveProfilerdatathroughtheuserinterfaceProfilerbinarydatacanbesavedintoafiletheScriptcode,butthereisnobuilt-inwaytoviewthisdata
Theseissuesmakeitverytrickytoperformlarge-scaleorlong-termtestingwiththeUnityProfiler.TheyhavebeenraisedinUnity’sIssueTrackertoolforseveralyears,andtheredoesn’tappeartobeanysalvationinsight.So,wemustrelyonourowningenuitytosolvethisproblem.
Fortunately,theProfilerclassexposesafewmethodsthatwecanusetocontrolhowtheProfilerlogsinformation:
1. TheProfiler.enabledmethodcanbeusedtoenable/disabletheProfiler,whichistheequivalentofclickingontheRecordbuttonintheControlViewoftheProfiler.
NoteNotethatchangingProfiler.enableddoesnotchangethevisiblestateoftheRecordbuttonintheProfiler’sControlsbar.Thiswillcausesomeconfusingconflictsifwe’recontrollingtheProfilerthroughbothcodeandtheuserinterfaceatthesametime.
2. TheProfiler.logFilemethodsetsthecurrentpathofthelogfilethattheProfilerprintsdataoutto.Beawarethatthisfileonlycontainsaprintoutoftheapplication’sframerateovertime,andnoneoftheusefuldatawenormallyfindintheProfiler’sTimelineView.Tosavethatkindofdataasabinaryfile,wemustusetheoptionsthatfollow.
3. TheProfiler.enableBinaryLogmethodwillenable/disableloggingofanadditionalfilefilledwithbinarydata,whichincludesalloftheimportantvalueswewanttosavefromtheTimelineandBreakdownViews.ThefilelocationandnamewillbethesameasthevalueofProfiler.logFile,butwith.dataappendedtotheend.
Withthesemethods,wecangenerateasimpledata-savingtoolthatwillgeneratelargeamountsofProfilerdataseparatedintomultiplefiles.Withthesefiles,wewillbeabletoperusethematalaterdate.
http://freepdf-books.com
![Page 80: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/80.jpg)
SavingProfilerdataInordertocreateatoolthatcansaveourProfilerdata,wecanmakeuseofaCoroutine.Atypicalmethodwillbeexecutedfrombeginningtoendinonesitting.However,Coroutinesareusefulconstructsthatallowuswritemethodsthatcanpauseexecutionuntilalatertime,oraneventtakesplace.Thisisknownasyielding,andisaccomplishedwiththeyieldstatement.Thetypeofyielddetermineswhenexecutionwillresume,whichcouldbeoneofthefollowingtypes(theobjectthatmustbepassedintotheyieldstatementisalsogiven):
Afteraspecificamountoftime(WaitForSeconds)AfterthenextUpdate(WaitForEndOfFrame)AfterthenextFixedUpdate(WaitForFixedUpdate)JustpriortothenextLateUpdate(null)AfteraWWWobjectcompletesitscurrenttask,suchasdownloadingafile(WWW)AfteranotherCoroutinehasfinished(areferencetoanotherCoroutine)
TheUnityDocumentationonCoroutinesandExecutionOrderprovidesmoreinformationonhowtheseusefultoolsfunctionwithintheUnityEngine:
http://docs.unity3d.com/Manual/Coroutines.htmlhttp://docs.unity3d.com/Manual/ExecutionOrder.html
TipCoroutinesshouldnotbeconfusedwiththreads,whichexecuteindependentlyofthemainUnitythread.Coroutinesalwaysrunonthemainthreadwiththerestofourcode,andsimplypauseandresumeatcertainmoments,dependingontheobjectpassedintotheyieldstatement.
Gettingbacktothetaskathand,thefollowingistheclassdefinitionforourProfilerDataSaverComponent,whichmakesuseofaCoroutinetorepeatanactionevery300frames:
usingUnityEngine;
usingSystem.Text;
usingSystem.Collections;
publicclassProfilerDataSaverComponent:MonoBehaviour{
int_count=0;
voidStart(){
Profiler.logFile="";
}
voidUpdate(){
if(Input.GetKey(KeyCode.LeftControl)&&Input.GetKeyDown(KeyCode.H))
{
StopAllCoroutines();
_count=0;
StartCoroutine(SaveProfilerData());
http://freepdf-books.com
![Page 81: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/81.jpg)
}
}
IEnumeratorSaveProfilerData(){
//keepcallingthismethoduntilPlayModestops
while(true){
//generatethefilepath
stringfilepath=Application.persistentDataPath+"/profilerLog"+
_count;
//setthelogfileandenabletheprofiler
Profiler.logFile=filepath;
Profiler.enableBinaryLog=true;
Profiler.enabled=true;
//count300frames
for(inti=0;i<300;++i){
yieldreturnnewWaitForEndOfFrame();
//workaroundtokeeptheProfilerworking
if(!Profiler.enabled)
Profiler.enabled=true;
}
//startagainusingthenextfilename
_count++;
}
}
}
TryattachingthisComponenttoanyGameObjectintheScene,andpressCtrl+H(OSXuserswillwanttoreplacetheKeyCode.LeftControlcodewithsomethingsuchasKeyCode.LeftCommand).TheProfilerwillstartgatheringinformation(whetherornottheProfilerWindowisopen!)and,usingasimpleCoroutine,willpumpthedataoutintoaseriesoffilesunderwhereverApplication.persistantDataPathispointingto.
TipNotethatthelocationofApplication.persistantDataPathvariesdependingontheOperatingSystem.ChecktheUnityDocumentationformoredetailsathttp://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html.
ItwouldbeunwisetosendthefilestoApplication.dataPath,asitwouldputthemwithintheProjectWorkspace.TheProfilerdoesnotreleasethemostrecentlogfilehandleifwestoptheProfilerorevenwhenPlayModeisstopped.Consequently,asfilesaregeneratedandplacedintotheProjectworkspace,therewouldbeaconflictinfileaccessibilitybetweentheUnityEditortryingtoreadandgeneratecomplementarymetadatafiles,andtheProfilerkeepingafilehandletothemostrecentlogfile.Thiswouldresultinsomenastyfileaccesserrors,whichtendtocrashtheUnityEditorandloseanyScenechangeswe’vemade.
http://freepdf-books.com
![Page 82: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/82.jpg)
WhenthisComponentisrecordingdata,therewillbeasmalloverheadinharddiskusageandtheoverheadcostofIEnumeratorcontextswitchingevery300frames,whichwilltendtoappearatthestartofeveryfileandconsumeafewmillisecondsofCPU(dependingonhardware).
Eachfilepairshouldcontain300framesworthofProfilerdata,whichskirtsaroundthe300framelimitintheProfilerwindow.AllweneednowisawayofpresentingthedataintheProfilerwindow.
HereisascreenshotofdatafilesthathavebeengeneratedbyProfilerDataSaverComponent:
NoteNotethatthefirstfilemaycontainlessthan300framesifsomeframeswerelostduringProfilerwarmup.
http://freepdf-books.com
![Page 83: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/83.jpg)
LoadingProfilerdataTheProfiler.AddFramesFromFile()methodwillloadagivenprofilerlogfilepair(thetextandbinaryfiles)andappenditintotheProfilertimeline,pushingexistingdatafurtherbackintime.Sinceeachfilewillcontain300frames,thisisperfectforourneeds,andwejustneedtocreateasimpleEditorWindowclassthatcanprovidealistofbuttonstoloadthefilesintotheProfiler.
TipNotethatAddFramesFromFile()onlyrequiresthenameoftheoriginallogfile.Itwillautomaticallyfindthecomplimentarybinary.datafileonitsown.
ThefollowingistheclassdefinitionforourProfilerDataLoaderWindow:
usingUnityEngine;
usingUnityEditor;
usingSystem.IO;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Text.RegularExpressions;
publicclassProfilerDataLoaderWindow:EditorWindow{
staticList<string>s_cachedFilePaths;
staticints_chosenIndex=-1;
[MenuItem("Window/ProfilerDataLoader")]
staticvoidInit(){
ProfilerDataLoaderWindowwindow=
(ProfilerDataLoaderWindow)EditorWindow.GetWindow
(typeof(ProfilerDataLoaderWindow));
window.Show();
ReadProfilerDataFiles();
}
staticvoidReadProfilerDataFiles(){
//makesuretheprofilerreleasesthefilehandle
//toanyofthefileswe'reabouttoloadin
Profiler.logFile="";
string[]filePaths=Directory.GetFiles
(Application.persistentDataPath,"profilerLog*");
s_cachedFilePaths=newList<string>();
//wewanttoignoreallofthebinary
//filesthatendin.data.TheProfiler
//willfigurethatpartout
Regextest=newRegex(".data$");
for(inti=0;i<filePaths.Length;i++){
stringthisPath=filePaths[i];
http://freepdf-books.com
![Page 84: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/84.jpg)
Matchmatch=test.Match(thisPath);
if(!match.Success){
//notabinaryfile,addittothelist
Debug.Log("Foundfile:"+thisPath);
s_cachedFilePaths.Add(thisPath);
}
}
s_chosenIndex=-1;
}
voidOnGUI(){
if(GUILayout.Button("FindFiles")){
ReadProfilerDataFiles();
}
if(s_cachedFilePaths==null)
return;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Files");
EditorGUILayout.BeginHorizontal();
//createsomestylestoorganizethebuttons,andshow
//themostrecently-selectedbuttonwithredtext
GUIStyledefaultStyle=newGUIStyle(GUI.skin.button);
defaultStyle.fixedWidth=40f;
GUIStylehighlightedStyle=newGUIStyle(defaultStyle);
highlightedStyle.normal.textColor=Color.red;
for(inti=0;i<s_cachedFilePaths.Count;++i){
//list5itemsperrow
if(i%5==0){
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
}
GUIStylethisStyle=null;
if(s_chosenIndex==i){
thisStyle=highlightedStyle;
}else{
thisStyle=defaultStyle;
}
if(GUILayout.Button(""+i,thisStyle)){
Profiler.AddFramesFromFile(s_cachedFilePaths[i]);
s_chosenIndex=i;
}
http://freepdf-books.com
![Page 85: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/85.jpg)
}
EditorGUILayout.EndHorizontal();
}
}
ThefirststepincreatinganycustomEditorWindowiscreatingamenuentrypointwitha[MenuItem]attributeandthencreatinganinstanceofaWindowobjecttocontrol.BothoftheseoccurwithintheInit()method.
We’realsocallingtheReadProfilerDataFiles()methodduringinitialization.ThismethodreadsallfilesfoundwithintheApplication.persistantDataPathfolder(thesamelocationourProfilerDataSaverComponentsavesdatafilesto)andaddsthemtoacacheoffilenamestouselater.
Finally,thereistheOnGUI()method.Thismethoddoesthebulkofthework.Itprovidesabuttontoreloadthefilesifneeded,verifiesthatthecachedfilenameshavebeenread,andprovidesaseriesofbuttonstoloadeachfileintotheProfiler.ItalsohighlightsthemostrecentlyclickedbuttonwithredtextusingacustomGUIStyle,makingiteasytoseewhichfile’scontentsarevisibleintheProfileratthecurrentmoment.
TheProfilerDataLoaderWindowcanbeaccessedbynavigatingtoWindow|ProfilerDataLoaderintheEditorinterface,asshowinthefollowingscreenshot:
Hereisascreenshotofthedisplaywithmultiplefilesavailabletobeloaded.ClickingonanyofthenumberedbuttonswillpushtheProfilerdatacontentsofthatfileintotheProfiler.
http://freepdf-books.com
![Page 86: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/86.jpg)
TheProfilerDataSaverComponentandProfilerDataLoaderWindowdonotpretendtobeexhaustiveorfeature-rich.Theysimplyserveasaspringboardtogetusstartedifwewishtotakethesubjectfurther.Formostteamsandprojects,300framesworthofshort-termdataisenoughfordeveloperstoacquirewhattheyneedtobeginmakingcodechangestofixtheproblem.
http://freepdf-books.com
![Page 87: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/87.jpg)
http://freepdf-books.com
![Page 88: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/88.jpg)
FinalthoughtsonProfilingandAnalysisOnewayofdescribingperformanceoptimizationis“theactofstrippingawayunnecessarytasksthatspendvaluableresources”.Wecandothesameandmaximizeourownproductivitythroughminimizingwastedeffort.Effectiveuseofthetoolswehaveatourdisposalisofparamountimportance.Itwouldserveuswelltooptimizeourownworkflowbykeepingawareofsomebestpracticesandtechniques.
Most,ifnotall,adviceforusinganykindofdata-gatheringtoolproperlycanbesummarizedintothreedifferentstrategies:
UnderstandingthetoolReducingnoiseFocusingontheissue
http://freepdf-books.com
![Page 89: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/89.jpg)
UnderstandingtheProfilerTheProfilerisanarguablywell-designedandintuitivetool,sounderstandingthemajorityofitsfeaturesetcanbegainedbysimplyspendinganhourortwoexploringitsoptionswithatestprojectandreadingitsdocumentation.Themoreweknowaboutourtoolintermsofitsbenefits,pitfalls,features,andlimitations,themoresensewecanmakeoftheinformationitisgivingus,soitisworthspendingthetimetouseitinaplaygroundsetting.Wedon’twanttobetwoweeksawayfromrelease,withahundredperformancedefectstofix,withnoideahowtodoperformanceanalysisefficiently!
Forexample,alwaysremainawareoftherelativenatureoftheTimelineView’sgraphicaldisplay.JustbecauseaspikeorrestingstateintheTimelineseemslargeandthreatening,doesnotnecessarilymeanthereisaperformanceissue.BecausetheTimelineViewdoesnotprovidevaluesonitsverticalaxis,andautomaticallyreadjuststhisaxisbasedonthecontentofthelast300frames,itcanmakesmallspikesappeartobeabiggerproblemthantheyreallyare.SeveralareasintheTimelineprovidehelpfulbenchmarkbars,givingaglimpseofhowtheapplicationwasperformingatthatmoment.Theseshouldbeusedtodeterminethemagnitudeoftheproblem.Don’tlettheProfilertrickusintothinkingthatbigspikesarealwaysbad.Asalways,it’sonlyimportantiftheuserwillnoticeit!
Asanexample,ifalargeCPUusagespikedoesnotexceedthe60FPSor30FPSbenchmarkbars(dependingontheapplication’stargetframerate),thenitwouldbewisetoignoreitandsearchelsewhereforCPUperformanceissues,asnomatterhowmuchweimprovetheoffendingpieceofcodeitwillprobablyneverbenoticedbytheenduser,andisn’tacriticalissuethataffectsproductquality.
http://freepdf-books.com
![Page 90: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/90.jpg)
ReducingnoiseTheclassicaldefinitionofnoiseincomputerscienceismeaninglessdata,andabatchofprofilingdatathatwasblindlycapturedwithnospecifictargetinmindisalwaysfullofdatawhichwon’tinterestus.Moredatatakesmoretimetomentallyprocessandfilter,whichcanbeverydistracting.Oneofthebestmethodstoavoidthisittosimplyreducetheamountofdataweneedtoprocess,bystrippingawayanydatadeemednonvitaltothecurrentsituation.
ReducingclutterintheProfiler’sgraphicalinterfacewillmakeiteasiertodeterminewhichcomponentiscausingaspikeinresourceusage.RemembertousethecoloredboxesineachTimelineareatonarrowthesearch.However,thesesettingsareautosavedintheEditor,sobesuretore-enablethemforthenextprofilingsessionasthismightcauseustomisssomethingimportantnexttime!
Also,GameObjectscanbedeactivatedtopreventthemfromgeneratingprofilingdata,whichwillalsohelpreduceclutterinourprofilingdata.Thiswillnaturallycauseaslightperformanceboostforeachobjectwedeactivate.But,ifwe’regraduallydeactivatingobjectsandperformancesuddenlybecomessignificantlymoreacceptablewhenaspecificobjectisdeactivated,thenclearlythatobjectisrelatedtotherootcauseoftheproblem.
http://freepdf-books.com
![Page 91: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/91.jpg)
FocusingontheissueThiscategorymayseemredundant,giventhatwe’vealreadycoveredreducingnoise.Allweshouldhaveleftistheissueathand,right?Notexactly.Focusistheskillofnotlettingourselvesbecomedistractedbyinconsequentialtasksandwildgoosechases.
RecallthatprofilingwiththeUnityProfilercomeswithaminorperformancecost.ThiscostisevenmoreseverewhenusingtheDeepProfilingoption.Wemightevenintroducemoreminorperformancecostsintoourapplicationwithadditionalloggingandsoon.It’seasytoforgetwhenandwhereweintroducedprofilingcodeifthehuntcontinuesforseveralhours.
Weareeffectivelychangingtheresultbymeasuringit.Anychangesweimplementduringdatasamplingcansometimesleadustochaseafternonexistentbugsintheapplication,whenwecouldhavesavedourselvesalotoftimebyattemptingtoreplicatethescenarioundernon-profilingconditions.Ifthebottleneckisreproducibleandnoticeablewithoutprofiling,thenit’sacandidatetobeginaninvestigation.Butifnewbottleneckskeepappearinginthemiddleofanexistinginvestigation,thenkeepinmindthattheycouldsimplybebottleneckswerecentlyintroducedwithtestcode,andnotsomethingthat’sbeennewlyexposed.
Finally,whenwehavefinishedprofiling,havecompletedourfixes,andarenowreadytomoveontothenextinvestigation,weshouldmakesuretoprofiletheapplicationonelasttimetoverifythatthechangeshavehadtheintendedeffect.
http://freepdf-books.com
![Page 92: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/92.jpg)
http://freepdf-books.com
![Page 93: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/93.jpg)
SummaryYoulearnedagreatdealthroughoutthischapteronhowtodetectperformanceissueswithinyourapplication.YoulearnedaboutmanyoftheProfiler’sfeaturesandsecrets,youexploredavarietyoftacticstoinvestigateperformanceissueswithamorehands-on-approach,andyou’vebeenintroducedtoavarietyofdifferenttipsandstrategiestofollow.Youcanusethesetoimproveyourproductivityimmensely,solongasyouappreciatethewisdombehindthemandremembertoexploitthemwhenthesituationmakesitpossible.
Thischapterhasintroducedustothetips,tactics,andstrategiesweneedfindaperformanceproblemthatneedsimprovement.Duringtheremainingchapters,wewillexploremethodsonhowtofixissues,andimproveperformancewheneverpossible.So,giveyourselfapatonthebackforgettingthroughtheboringpartfirst,andlet’smoveontolearningsomestrategiestoimproveourC#scriptingpractices.
http://freepdf-books.com
![Page 94: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/94.jpg)
http://freepdf-books.com
![Page 95: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/95.jpg)
Chapter2.ScriptingStrategiesSincescriptingwillconsumeagreatdealofourdevelopmenttime,itwillbeenormouslybeneficialtolearnsomebestpractices.Scriptingisaverybroadterm,sowewilltrytolimitourexposureinthischaptertosituationsthatareveryUnityspecific,focusingonproblemsarisingfromwithintheUnityAPIsandenginedesign.WewilldiscussthenuancesandadvancedtopicsoftheC#language,.NETlibrary,andMonoFramework,inChapter7,MasterfulMemoryManagement.
Whetheryouhavesomespecificproblemsinmindthatyouwishtosolveoryoujustwanttolearnsometechniquesforfuturereference,thischapterwillintroduceyoutoanarrayofmethodsthatyoucanusetoimproveyourscriptingeffortsnowandinthefuture.Ineachcase,wewillexplorehowandwhytheperformanceissuearises,anexamplesituationinwhichtheproblemisoccurring,andoneormoresolutionstocombattheissue.
http://freepdf-books.com
![Page 96: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/96.jpg)
CacheComponentreferencesAcommonmistakewhenscriptinginUnityistooverusetheGetComponent()method.Forexample,thefollowingscriptcodeistryingtocheckacreature’shealthvalue,andifitshealthgoesbelow0,disableaseriesofComponentstoprepareitforadeathanimation:
voidTakeDamage(){
if(GetComponent<HealthComponent>().health<0){
GetComponent<Rigidbody>().enabled=false;
GetComponent<Collider>().enabled=false;
GetComponent<AIControllerComponent>().enabled=false;
GetComponent<Animator>().SetTrigger("death");
}
}
Eachtimethismethodexecutes,itwillreacquirefivedifferentComponentreferences.Thisisgoodintermsofheapmemoryconsumption(inthatitdoesn’tcostany),butitisnotveryfriendlyonCPUusage.ThisisparticularlyproblematicifthemainmethodwerecalledduringUpdate().Evenifitisnot,itstillmightcoincidewithotherimportantevents,suchascreatingparticleeffects,replacinganobjectwitharagdoll(thusinvokingvariousactivityinthephysicsengine),andsoon.Thiscodingstylecanseemharmless,butitcancausealotoflong-termproblemsandruntimeworkforverylittlebenefit.
Itcostsusverylittlememoryspace(only32or64bitseachtime;Unityversion,platform,andfragmentationpermitting)tocachethesereferencesforfutureuse.So,unlessyou’reextremelybottleneckedonmemory,abetterapproachwouldbetoacquirethereferencesduringinitializationandkeepthemuntiltheyareneeded:
privateHealthComponent_healthComponent;
privateRigidbody_rigidbody;
privateCollider_collider;
privateAIControllerComponent_aiController;
privateAnimator_animator;
voidAwake(){
_healthComponent=GetComponent<HealthComponent>();
_rigidbody=GetComponent<Rigidbody>();
_collider=GetComponent<Collider>();
_aiController=GetComponent<AIControllerComponent>();
_animator=GetComponent<Animator>();
}
voidTakeDamage(){
if(_healthComponent.health<0){
_rigidbody.detectCollisions=false;
_collider.enabled=false;
_aiController.enabled=false;
_animator.SetTrigger("death");
}
}
CachingtheComponentreferencesinthiswaysparesusfromreacquiringthemeachtime
http://freepdf-books.com
![Page 97: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/97.jpg)
they’reneeded,savingussomeCPUoverheadeachtime,attheexpenseofsomeadditionalmemoryconsumption.
http://freepdf-books.com
![Page 98: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/98.jpg)
http://freepdf-books.com
![Page 99: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/99.jpg)
ObtainingComponentsusingthefastestmethodThereareseveralvariationsoftheGetComponent()method,anditbecomesprudenttocallthefastestpossibleversionofthismethod.ThethreeoverloadsavailableareGetComponent(string),GetComponent<T>(),andGetComponent(typeof(T)).ItturnsoutthatthefastestversiondependsonwhichversionofUnitywearerunning.
InUnity4,theGetComponent(typeof(T))methodisthefastestoftheavailableoptionsbyareasonablemargin.Let’sprovethiswithsomesimpletesting:
intnumTests=1000000;
TestComponenttest;
using(newCustomTimer("GetComponent(string)",numTests)){
for(vari=0;i<numTests;++i){
test=(TestComponent)GetComponent("TestComponent");
}
}
using(newCustomTimer("GetComponent<ComponentName>",numTests)){
for(vari=0;i<numTests;++i){
test=GetComponent<TestComponent>();
}
}
using(newCustomTimer("GetComponent(typeof(ComponentName))",numTests)){
for(vari=0;i<numTests;++i){
test=(TestComponent)GetComponent(typeof(TestComponent));
}
}
ThiscodetestseachoftheGetComponent()overloadsamilliontimes.Thisisfarmoreteststhanwouldbesensibleforatypicalproject,butitisenoughteststoprovethepoint.
Hereistheresultwegetwhenthetestscomplete:
Asyoucansee,GetComponent(typeof(T))issignificantlyfasterthanGetComponent<T>(),whichisaroundfivetimesfasterthanGetComponent(string).ThistestwasperformedagainstUnity4.5.5,butthebehaviorshouldbeequivalentallthewaybacktoUnity3.x.
Note
http://freepdf-books.com
![Page 100: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/100.jpg)
GetComponent(string)shouldnotbeused,sinceitisnotoriouslyslowandisonlyincludedforcompleteness.
TheseresultschangewhenweruntheexactsametestinUnity5.UnityTechnologiesmadesomeperformanceenhancementstohowSystem.TypereferencesarepassedaroundinUnity5.0,and,asaresult,GetComponent<T>()andGetComponent(typeof(T))becomeessentiallyequivalent:
Asyoucansee,theGetComponent<T>()methodisonlyatinyfractionfasterthanGetComponent(typeof(T)),whileGetComponent(string)isnowaround30timesslowerthanthealternatives(interestingly,itbecameevenslowerthanitwasinUnity4).Multipletestswillprobablyyieldsmallvariationsintheseresults,butultimatelywecanfavoreitherofthetype-basedversionsofGetComponent()whenwe’reworkinginUnity5,andtheoutcomewillbeaboutthesame.
Thereisonecaveat,however.Ifwe’rerunningUnity4,thenwestillhaveaccesstoavarietyofquickaccessorpropertiessuchascollider,rigidbody,camera,andsoon.ThesepropertiesbehavelikeprecachedComponentmembervariables,whicharesignificantlyfasterthanallofthetraditionalGetComponent()methods:
intnumTests=1000000;
Rigidbodytest;
using(newCustomTimer("Cachedreference",numTests))
{
for(vari=0;i<numTests;++i){
test=gameObject.rigidbody;
}
}
NoteNotethatthiscodeisintendedforUnity4,andwillnotcompileinUnity5duetotheremovaloftherigidbodyproperty.
RunningthistestinUnity4givesusthefollowingresult:
Inanefforttoreducedependenciesandimprovecodemodularizationintheengine’sbackend,UnityTechnologieshasdeprecatedallofthesequickaccessorvariablesinUnity5.Onlythetransformpropertyremains.
http://freepdf-books.com
![Page 101: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/101.jpg)
TipUnity4usersconsideringanupgradetoUnity5shouldknowthatupgradingwillautomaticallymodifyanyofthesepropertiestousetheGetComponent<T>()method.However,thiswillresultinuncachedGetComponent<T>()callsscatteredthroughoutyourcode,possiblyrequiringyoutorevisitthetechniquesintroducedintheearliersection,entitledCacheComponentReferences.
ThemoralofthestoryisthatifwearerunningUnity4,andtherequiredComponentisoneofGameObject’sbuilt-inaccessorproperties,thenweshouldusethatversion.Ifnot,thenweshouldfavorGetComponent(typeof(T)).Meanwhile,ifwe’rerunningUnity5,thenwecanfavoreitherofthetype-basedversions:GetComponent<T>()orGetComponent(typeof(T)).
http://freepdf-books.com
![Page 102: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/102.jpg)
http://freepdf-books.com
![Page 103: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/103.jpg)
RemovingemptycallbackdeclarationsWhenwecreatenewMonoBehaviourscriptfilesinUnity,whetherwe’reusingUnity4orUnity5,itcreatestwoboilerplatemethodsforus:
//Usethisforinitialization
voidStart(){
}
//Updateiscalledonceperframe
voidUpdate(){
}
TheUnityenginehooksintothesemethodsduringinitializationandaddsthemtoalistofmethodstocallbackatkeymoments.However,ifweleavetheseasemptydeclarationsinourcodebase,thentheywillcostusasmalloverheadwhenevertheengineinvokesthem.
TheStart()methodisonlycalledwhentheGameObjectisinstantiatedforthefirsttime,whichcanbewheneverthesceneisloadedoranewGameObjectisinstantiatedfromaPrefab.Therefore,leavingtheemptyStart()declarationmaynotbeparticularlynoticeableunlessthere’salotofGameObjectsinthesceneinvokingthematstartuptime.However,italsoaddsunnecessaryoverheadtoanyGameObject.Instantiate()call,whichtypicallyhappensduringkeyevents,sotheycanpotentiallycontributeto,andexacerbate,alreadypoorperformancessituationwhenlotsofeventsarehappeningsimultaneously.
Meanwhile,theUpdate()methodiscalledeverytimethesceneisrendered.IfourscenecontainsthousandsofGameObjectsowningcomponentswiththeseemptyUpdate()declarations,thenwecanbewastingalotofCPUcyclesandcausinghavoconourframerate.
Let’sprovethiswithasimpletest.OurtestsceneshouldhaveGameObjectswithtwotypesofComponent,onetypewithanemptyUpdate()declaration,andanotherwithnomethodsdefined:
publicclassCallbackTestComponent:MonoBehaviour{
voidUpdate(){}
}
publicclassEmptyTestComponent:MonoBehaviour{
}
Herearethetestresultsfor32,768Componentsofeachtype.Ifweenableallobjectswithnostubmethodsduringruntime,thennothinginterestinghappenswithCPUusageintheProfiler.WemaynoticesomememoryconsumptionchangesandsomeslightlydifferentVSyncactivity,butnothingveryconcerning.However,assoonasweenablealltheobjectswithemptyUnitycallbackdeclarations,wewillobserveahugeincreaseinCPUusage:
http://freepdf-books.com
![Page 104: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/104.jpg)
Thefixforthisissimple;deletetheemptydeclarations.Unitywillhavenothingtohookinto,andnothingwillbecalled.Sometimes,findingsuchemptydeclarationsinanexpansivecodebasecanbedifficult,butusingsomebasicregularexpressions(regex),weshouldbeabletofindwhatwe’relookingforrelativelyeasily.
TipAllcommoncode-editingtoolsforUnity,suchasMonoDevelop,VisualStudio,andevenNotepad++,provideawaytoperformaregex-basedsearchontheentirecodebase.Checkthetool’sdocumentationformoreinformation,sincethemethodcanvarygreatlydependingonthetoolanditsversion.
ThefollowingregexsearchshouldfindanyemptyUpdate()declarationsinourcode:
void\s*Update\s*?\(\s*?\)\s*?\n*?\{\n*?\s*?\}
ThisregexchecksforastandardmethoddefinitionoftheUpdate()method,whileincludinganysurpluswhitespaceandnewlinecharactersthatcanbedistributedthroughoutthemethoddeclaration.
Naturally,alloftheaboveisalsotrueforthenon-boilerplateUnitycallbacks,suchasOnGUI(),OnEnable(),OnDestroy(),FixedUpdate(),andsoon.ChecktheMonoBehaviourUnityDocumentationpageforacompletelistofthesecallbacksathttp://docs.unity3d.com/ScriptReference/MonoBehaviour.html.
Itmightseemunlikelythatsomeonegeneratedemptyversionsofthesecallbacksinourcodebase,butneversaynever.Forexample,ifweuseacommonbaseclassMonoBehaviourthroughoutallofourcustomcomponents,thenasingleemptycallbackdeclarationinthatbaseclasswillpermeatetheentiregame,whichcancostusdearly.BeparticularlycarefuloftheOnGUI()method,asitcanbeinvokedmultipletimeswithinthesameframeoruserinterface(UI)event.
http://freepdf-books.com
![Page 105: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/105.jpg)
http://freepdf-books.com
![Page 106: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/106.jpg)
AvoidingtheFind()andSendMessage()methodsatruntimeTheSendMessage()methodandfamilyofGameObject.Find()methodsarenotoriouslyexpensive,andshouldbeavoidedatallcosts.TheSendMessage()methodisabout2,000timesslowerthanasimplefunctioncall,andthecostoftheFind()methodscalesverypoorlywithScenecomplexitysinceitmustiteratethrougheveryGameObjectintheScene.ItissometimesreasonabletocallFind()duringinitializationofaScene,suchasAwake()andStart(),onlyforobjectsthatalreadyexistsintheScene.However,usingeithermethodforinter-objectcommunicationatruntimeislikelytogenerateaverynoticeableoverhead.
RelyingonFind()andSendMessage()typemethodsistypicallysymptomaticofpoordesign,inexperienceinprogrammingwithC#andUnity,orjustplainlazinessduringprototyping.Theirusagehasbecomesomethingofanepidemicamongbeginner-andintermediate-levelprojects,suchthatUnityTechnologiesfeelstheneedtokeepremindinguserstoavoidusingtheminarealgame,overandoveragainintheirdocumentationandattheirconferences.Theyonlyexistasalessprogrammer-ywaytointroducenewuserstointer-objectcommunication,andforsomespecialcaseswheretheycanbeusedinalazy,butresponsible,way.
Tobefair,Unitytargetsawidedemographicofusers,fromindividualhobbyists,students,andthosewithdelusionsofgrandeur,tosmall,mid-sized,andlargedevelopmentteams.Thisresultsinanincrediblywiderangeofsoftwaredevelopmentability.Whenyou’restartingoutwithUnity,itcanbedifficulttofigureoutonyourownwhatyoushouldbedoingdifferently,especiallygivenhowtheUnityenginedoesnotadheretothedesignparadigmsofmanyothergameengines.Ithassomeforeignandquirkyconceptssurroundingscenesandprefabs,aswellasnogodclassentrypoints,noranyobviousraw-datastoragesystemstoworkwith.
Sincewe’retalkingaboutscriptingoptimizationinthissection,let’sexplorethesubjectinsomedetail,discussingsomealternativemethodsforinter-objectcommunication.
Let’sstartbyexaminingaworst-caseexample,whichusesbothFind()andSendMessage()methods,anddiscoversomewaystoimproveuponit.Thefollowingexamplemethodattemptstoinstantiateagivennumberofenemiesfromaprefab,andthennotifiesanEnemyManagerobjectoftheirexistence:
publicvoidSpawnEnemies(intnumEnemies){
for(inti=0;i<numEnemies;++i){
GameObjectenemy=(GameObject)GameObject.Instantiate(_enemyPrefab,
Vector3.zero,Quaternion.identity);
GameObjectenemyManagerObj=GameObject.Find("EnemyManager");
enemyManagerObj.SendMessage("AddEnemy",enemy,
SendMessageOptions.DontRequireReceiver);
}
}
http://freepdf-books.com
![Page 107: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/107.jpg)
Puttingmethodcallsinsidealoop,whichalwaysoutputtothesameresult,isabigredflagforpoorperformance,andwhenwe’redealingwithexpensivemethodssuchasFind(),weshouldalwayslookforwaystocallthemasfewtimesaspossible.Ergo,oneimprovementwecanmakeistomovetheFind()calloutsideoftheforloopandcachetheresultinalocalvariabletobeusedwithintheloop.
WecanalsooptimizeourusageoftheSendMessage()methodbyreplacingitwithaGetComponent()call.Thisreplacesaverycostlymethodwithamuchgentlervariation,achievingeffectivelythesameresult.
Thisgivesusthefollowing:
publicvoidSpawnEnemies(intnumEnemies){
GameObjectenemyManagerObj=GameObject.Find("EnemyManager");
EnemyManagerComponentenemyMgr=
enemyManagerObj.GetComponent<EnemyManagerComponent>();
for(inti=0;i<numEnemies;++i){
GameObjectenemyIcon=(GameObject)GameObject.Instantiate(_enemyPrefab,
Vector3.zero,Quaternion.identity);
enemyMgr.AddEnemy(enemy);
}
}
IfthismethodiscalledduringtheinitializationoftheScene,andwe’renotoverlyconcernedwithloadingtime,thenwecanprobablyconsiderourselvesfinishedwithouroptimizationwork.
However,weoftenneednewobjectsthatareinstantiatedatruntimetofindanexistingobjecttocommunicatewith.Inthisexample,wewantnewenemyobjectstoregisterwithourEnemyManagerComponentsothatitcandowhateveritneedstodotocontroltheenemyobjectsinourScene.WewouldlikeareliableandfastwayfornewobjectstofindexistingobjectswithoutunnecessaryusageoftheFind()method,duetotheoverheadinvolved.
Therearemultipleapproacheswecantaketosolvingthisproblem,eachwiththeirownbenefitsandpitfalls:
StaticclassesSingletonComponentsAssignreferencestopre-existingobjectsAglobalmessagingsystem
http://freepdf-books.com
![Page 108: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/108.jpg)
StaticclassesThisapproachinvolvescreatingaclassthatisgloballyaccessibletotheentirecodebaseatanytime.Theobjectstaysalivefromthemomenttheapplicationstarts,tothemomentitisclosed.Globalmanagerclassesareoftenfrownedupon,sincethenamedoesn’tsaymuchaboutwhatit’smeanttodo,andtheycanbedifficulttodebugsincechangescanoccurfromanywhere,atanypointduringruntime.Inaddition,itisprobablytheleastrobustapproachwhenitcomestochangingorreplacingitatafuturedate.Despiteallofthesedrawbacks,itisbyfartheeasiestsolutiontoimplement,andsowewillcoveritfirst.
TheSingletondesignpatternisacommonwayofensuringthatwehaveaglobally-accessibleobject,andthatonlyoneinstanceeverexistsinmemory.However,thewaythatSingletonsareprimarilyused(notethequalifier)inUnityprojects,canbeeasilyreplacedwithasimpleC#Staticclasswithouttheneedtoimplementprivateconstructors,andtheunnecessarypropertyaccessofanInstancevariable.Essentially,implementingatypicalSingletondesignpatterninC#justtakesmorecode,andtime,toachievethesameresultasastaticclass.
AstaticclassthatfunctionsinmuchthesamewayasourEnemyManagerComponentisusedinthepreviousexamplecanbedefinedasfollows:
usingSystem.Collections.Generic;
publicstaticclassEnemyManager{
staticList<GameObject>_enemies;
publicstaticvoidAddEnemy(GameObjectenemy){
_enemies.Add(enemy);
}
publicstaticvoidRollCall(){
for(inti=0;i<_enemies.Count;++i){
Debug.Log(string.Format("Enemy\"{0}\"reportingin…",
_enemies[i].name));
}
}
}
Notethateverymemberandmethodhasthestatickeywordattached,whichimpliesthatonlyoneinstanceofthisobjectwilleverresideinmemory.Staticclasses,bydefinition,donotallowanynonstaticinstancememberstobedefined,asthatwouldimplythatwecouldsomehowduplicatetheobject.
Staticclassescanbegivenastaticconstructor,whichcanbeusedtoinitializememberdata.Astaticconstructorcanbedefinedlikeso,anditiscalledthemomenttheclassisfirstaccessed(eitherthroughamembervariableoramemberfunction):
staticEnemyManager(){
_enemies=newList<GameObject>();
}
Thistypeofglobalclassisgenerallyconsideredtobeacleanerandeasier-to-useversion
http://freepdf-books.com
![Page 109: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/109.jpg)
ofthetypicalSingletondesignpatternintheworldofC#development.
http://freepdf-books.com
![Page 110: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/110.jpg)
SingletonComponentsThedisadvantageofthestaticclassapproachisthattheymustinheritfromthelowestformofclass—Object.ThismeansthatstaticclassescannotinheritfromMonoBehaviourandthereforewecannotmakeuseofanyofitsUnity-relatedfunctionality,includingtheall-importanteventcallbacks,aswellasCoroutines.Also,sincethere’snoobjecttoselect,welosetheabilitytoinspecttheobject’sdataatruntimethroughtheInspector.ThesearefeaturesthatwemaywishtomakeuseofinourglobalSingletonclasses.
Acommonsolutiontothisproblemistoimplementa“SingletonasaComponent”classthatspawnsaGameObjectcontainingitself,andprovidingstaticmethodstograntglobalaccess.Notethat,inthiscase,wemustessentiallyimplementthetypicalSingletondesignpattern,withprivatestaticinstancevariables,andaglobalInstancemethodforglobalaccess.
HereisthedefinitionforaSingletonAsComponentclass:
publicclassSingletonAsComponent<T>:MonoBehaviourwhereT:
SingletonAsComponent<T>{
privatestaticT__Instance;
protectedstaticSingletonAsComponent<T>_Instance{
get{
if(!__Instance){
T[]managers=
GameObject.FindObjectsOfType(typeof(T))asT[];
if(managers!=null){
if(managers.Length==1){
__Instance=managers[0];
return__Instance;
}elseif(managers.Length>1){
Debug.LogError("Youhavemorethanone"+
typeof(T).Name+"inthescene.Youonly
need1,it'sasingleton!");
for(inti=0;i<managers.Length;++i){
Tmanager=managers[i];
Destroy(manager.gameObject);
}
}
}
GameObjectgo=newGameObject(typeof(T).Name,
typeof(T));
__Instance=go.GetComponent<T>();
DontDestroyOnLoad(__Instance.gameObject);
}
return__Instance;
}
set{
__Instance=valueasT;
}
}
http://freepdf-books.com
![Page 111: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/111.jpg)
}
Sincewewishthistobeaglobalandpersistentobject,weneedtocallDontDestroyOnLoad()shortlyaftertheGameObjectiscreated.ThisisaspecialfunctionthattellsUnitythatwewishtheobjecttopersistbetweenScenesforaslongastheapplicationisrunning.Fromthatpointonward,whenanewsceneisloaded,theobjectwillnotbedestroyedandwillretainallofitsdata.
Thisclassdefinitionassumestwothings.Firstly,becauseitisusinggenericstodefineitsbehavior,itmustbederivedfrominordertocreateaconcreteclass.Secondly,amethodwillbedefinedtoassignthe_Instancevariableandcastitto/fromthecorrectType.
Forexample,thefollowingisallthatisneededtosuccessfullygenerateanewSingletonAsComponentderivedclasscalledMySingletonComponent:
publicclassMySingletonComponent:
SingletonAsComponent<MySingletonComponent>{
publicstaticMySingletonComponentInstance{
get{return((MySingletonComponent)_Instance);}
set{_Instance=value;}
}
}
ThisclasscanbeusedatruntimebyhavinganyotherobjectaccesstheInstancepropertyatanytime.IftheComponentdoesnotalreadyexistinourScene,thentheSingletonAsComponentbaseclasswillinstantiateitsownGameObjectandattachaninstanceofthederivedclasstoitasaComponent.Fromthatpointforward,accessthroughtheInstancepropertywillreferencetheComponentthatwascreated.
TipWhileitispossible,weshouldnotplaceourSingletonAsComponentderivedclassinaSceneHierarchy.ThisisbecausetheDontDestroyOnLoad()methodwillneverbecalled!ThiswouldpreventtheSingletonComponent’sGameObjectfrompersistingwhenthenextSceneisloaded.
PropercleanupofaSingletonComponentcanbealittleconvolutedbecauseofhowUnitytearsdownScenes.Anobject’sOnDestroy()methodiscalledwheneveritisdestroyedduringruntime.Thesamemethodiscalledduringapplicationshutdown,wherebyeveryComponentoneveryGameObjecthasitsOnDestroy()methodcalledbyUnity.ApplicationshutdownalsotakesplacewhenweendPlayModeintheEditorandreturntoEditMode.However,destructionofobjectsoccursinarandomorder,andwecannotassumethattheSingletonComponentwillbethelastobjectdestroyed.
Consequently,ifanyobjectattemptstodoanythingwiththeSingletoninthemiddleoftheirOnDestroy()method,thentheywillbecallingtheInstanceproperty.IftheSingletonhasalreadybeendestroyedpriortothismoment,thencallingInstanceduringanotherobject’sdestructionwouldcreateanewinstanceoftheSingletonComponentinthemiddleofapplicationshutdown!ThiscancorruptourScenefiles,asinstancesofourSingletonComponentswillbeleftbehindintheScene.Ifthishappens,thenUnitywillthrowthefollowingerrormessageatus:
http://freepdf-books.com
![Page 112: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/112.jpg)
ThereasonsomeobjectsmaywishtocallintoourSingletonduringdestructionisthatSingletonsoftenmakeuseoftheObserverpattern.Thisdesignpatternallowsotherobjectstoregister/deregisterwiththemforcertaintasks,similartohowUnitylatchesontocallbackmethods,butinalessautomatedfashion.WewillseeanexampleofthisintheupcomingsectionAglobalmessagingsystem.Objectsthatareregisteredwiththesystemduringconstructionwillwanttoderegisterwiththesystemduringtheirownshutdown,andthemostconvenientplacetodothisiswithinitsOnDestroy()method.Consequently,suchobjectsarelikelytorunintotheaforementionedproblem,whereSingletonsareaccidentallycreatedduringapplicationshutdown.
Tosolvethisproblem,weneedtomakethreechanges.Firstly,weneedtoaddanadditionalflagtotheSingletonComponent,whichkeepstrackofitsactivestate,anddisableitattheappropriatetimes.ThisincludestheSingleton’sowndestruction,aswellasapplicationshutdown(OnApplicationQuit()isanotherusefulUnitycallbackforMonoBehaviours,whichiscalledduringthistime):
privatebool_alive=true;
voidOnDestroy(){_alive=false;}
voidOnApplicationQuit(){_alive=false;}
Secondly,weshouldimplementawayforexternalobjectstoverifytheSingleton’scurrentstate:
publicstaticboolIsAlive{
get{
if(__Instance==null)
returnfalse;
return__Instance._alive;
}
}
Finally,anyobjectthatattemptstocallintotheSingletonduringitsownOnDestroy()method,mustfirstverifythestateusingtheIsAlivepropertybeforecallingInstance.Forexample:
publicclassSomeComponent:MonoBehaviour{
voidOnDestroy(){
if(MySingletonComponent.IsAlive){
MySingletonComponent.Instance.SomeMethod();
}
}
}
ThiswillensurethatnobodyattemptstoaccessInstanceduringdestruction.Ifwedon’tfollowthisrule,thenwewillrunintoproblemswhereinstancesofourSingletonobjectwillbeleftbehindintheSceneafterreturningtoEditMode.
TheironyoftheSingletonComponentapproachisthatweareusingoneofUnity’s
http://freepdf-books.com
![Page 113: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/113.jpg)
Find()methodstodeterminewhetherornotoneoftheseSingletonComponentsalreadyexistsintheScenebeforeweattempttoassignthe__Instancereferencevariable.Fortunately,thiswillonlyhappenwhentheSingletonComponentisfirstaccessed,butit’spossiblethattheinitializationoftheSingletonwouldnotnecessarilyoccurduringSceneinitializationandcanthereforecostusaperformancespikeatabadmomentduringgameplay,whenthisobjectisfirstinstantiatedandFind()getscalled.TheworkaroundforthisistohavesomegodclassconfirmthattheimportantSingletonsareinstantiatedduringSceneinitializationbysimplycallingInstanceoneachone.
Thedownsidetothisapproachisthatifwelaterdecidethatwewantmorethanoneofthesemanagerclassesexecutingatonce,orwewishtoseparateitsbehaviortobemoremodular,thentherewouldbealotofcodethatneedstochange.
Therearefurtheralternativesthatwecanexplore,suchasmakinguseofUnity’sbuilt-inbridgebetweenscriptcodeandtheInspectorinterface.
http://freepdf-books.com
![Page 114: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/114.jpg)
Assigningreferencestopre-existingobjectsAnotherapproachtotheproblemofinter-objectcommunicationistouseUnity’sbuilt-inserializationsystems.Softwaredesignpuriststendtogetalittlecombativeaboutthisfeature,sinceitbreaksencapsulation;itmakesvariablesmarkedprivateactinawaythattreatsthemaspublic.EventhoughthevalueonlybecomespublicwithrespecttotheUnityInspectorandnothingelse,thisisstillenoughtowavesomeredflags.
However,itisaveryeffectivetoolforimprovingdevelopmentworkflow.Thisisparticularlytruewhenartists,designers,andprogrammersarealltinkeringwiththesameproduct,whereeachhaswildlyvaryinglevelsofcomputerscienceandsoftwareprogrammingknowledge.Sometimesit’sworthbendingafewrulesinthenameofproductivity.
Wheneverwecreateapublicvariable,UnityautomaticallyserializesandexposesthevalueintheInspectorinterfacewhentheComponentisselected.However,publicvariablesaredangerousfromasoftwaredesignperspective—thesevariablescanbechangedthroughcodeatanytime,whichcanmakeithardtokeeptrackofthevariable,andintroducealotofunexpectedbugs.
Asanalternative,wecantakeanyprivateorprotectedmembervariableofaclassandexposeittotheUnityEditorInspectorinterfacewiththe[SerializeField]attribute.Thisapproachispreferredoverpublicvariables,asitgivesusmorecontrolofthesituation.Thisway,atleastweknowthevariablescannotbechangedatruntimeviacodeoutsidetheclass(orderivedclass),andthereforemaintainencapsulationfromtheperspectiveofscriptcode.
Forexample,thefollowingclassexposesthreeprivatevariablestotheInspector:
publicclassEnemySpawnerComponent:MonoBehaviour{
[SerializeField]privateint_numEnemies;
[SerializeField]privateGameObject_enemyPrefab;
[SerializeField]privateEnemyManagerComponent_enemyManager;
voidStart(){
SpawnEnemies(_numEnemies);
}
voidSpawnEnemies(int_numEnemies){
for(inti=0;i<_numEnemies;++i){
GameObjectenemy=(GameObject)GameObject.Instantiate(_enemyPrefab,
Vector3.zero,Quaternion.identity);
_enemyManager.AddEnemy(enemy);
}
}
}
TipNotethattheprivateaccessspecifiersshownintheprecedingcodeareredundantkeywordsinC#,asmembervariablesarealwaysprivateunlessspecifiedotherwise,but
http://freepdf-books.com
![Page 115: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/115.jpg)
theseaccessspecifiersareincludedforcompleteness.
LookingatthisComponentintheInspectorviewrevealsthreevalues,initiallygivendefaultvaluesof0,ornull,whichcanbemodifiedthroughtheInspectorinterface:
WecandraganddropaPrefabreferencefromtheProjectswindowintotheEnemyPrefabfield,or,ifwefeltsoinclined,evenareferencetoanotherGameObjectthatispresentintheScene.Although,giventhatit’sbeingusedlikeaPrefabinthecode,itwouldbeunwisetodothis,sincewewouldbecloningaGameObjectthatmighthavealreadyundergonechangesintheScene.PrefabsservethepurposeofablueprintfromwhichtoinstantiatenewGameObjectsandshouldbeusedassuch.
TheEnemyManagerfieldisinterestingbecauseitisaComponentreferenceandnotaGameObjectreference.IfaGameObjectisdroppedintothisfield,thenitwillrefertotheComponentonthegivenobject,asopposedtotheGameObjectthatwedraggedanddroppedintothefield.IfthegivenobjectdoesnothavetheexpectedComponent,thennothingwillbeassigned.
TipAcommonusageoftheComponentreferencetechniqueistoobtainreferencestoComponentsattachedtothesameGameObjectitisattachedto.ThisisanalternativeapproachtothetopicdiscussedinthesectionentitledCacheComponentReferences,earlierinthischapter.
ThedangerhereisthatsincePrefabsareessentiallyGameObjects,PrefabswiththerequiredComponentcanbeassignedtothesefields,eventhoughwemightnotwishthemtobe.UnityloadsPrefabsintomemorymuchlikeGameObjects,andassumesthey’llbeusedinPrefab-likeways;thatis,treatedasnothingmorethanblueprintstobeinstantiatedfromonanas-neededbasis.However,theystillcountasdatastoredinmemoryandcanthereforebeeditedonawhim,makingthemsusceptibletochangesthatdirectlyaffectallfutureGameObjectsinstantiatedfromthem.
Tomakemattersworse,thesechangesbecomepermanenteveniftheyaremadeduringPlayMode,sincePrefabsoccupythesamememoryspacewhetherPlayModeisactiveornot.ThismeansthatwecanaccidentallycorruptourPrefabs,ifweassignthemtothewrongfields.Consequently,thisapproachisamoreteam-friendlywayofsolvingtheoriginalproblemofinter-objectcommunication,butitisnotidealduetoalloftherisksinvolvedwithteammembersaccidentallybreakingthingsorleavingnullreferencesinplace.
ItisalsoimportanttonotethatnotallobjectscanbeserializedbytheInspectorview.
http://freepdf-books.com
![Page 116: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/116.jpg)
Unitycanserializeallprimitivedatatypes(ints,floats,strings,andbools),variousbuilt-intypessuchas(Vector3,Quaternion,andsoon)enums,classes,andstructs,aswellasarraysandlistsofotherserializabletypes.However,itisunabletoserializestaticfields,read-onlyvalues,properties,anddictionaries.
TipSomeUnitydevelopersliketoimplementpseudo-serializationofdictionariesviatwoseparatelistsforkeysandvalues,alongwithaCustomEditorscript,orviaasinglelistofobjects,whichcontainbothkeysandvalues.Bothofthesesolutionsarealittleclumsy,butperfectlyvalid.
Thelastsolutionwewilllookatwillprovideawaytohopefullygetthebestofbothworldsbycombiningeaseofimplementation,easeofextension,andstrictusagethatavoidstoomuchhumanerror.
http://freepdf-books.com
![Page 117: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/117.jpg)
AglobalmessagingsystemThefinalsuggestedapproachtotheproblemofinter-objectcommunicationistoimplementaglobalmessagingsystemthatanyobjectcanaccessandsendmessagesthroughtoanyobjectthatmaybeinterestedinlisteningtothatspecifictypeofmessage.Objectseithersendmessagesorlistenforthem,andtheresponsibilityisonthelistenertodecidewhatmessagesitisinterestedin.Themessagesendercanbroadcastthemessagewithoutcaringatallwhoislistening.Thisapproachisexcellentforkeepingourcodemodularanddecoupled.
Thekindsofmessagewewishtosendcantakemanyforms,suchasincludingdatavalues,references,instructionsforlisteners,andmore,buttheyshouldallhaveacommon,basicdeclarationthatourmessagingsystemcanusetodeterminewhatthemessageis,andwhoitisintendedfor.
ThefollowingisasimpleclassdefinitionforaMessageobject:
publicclassBaseMessage{
publicstringname;
publicBaseMessage(){name=this.GetType().Name;}
}
TheBaseMessageclass’sconstructorcachestheTypeinalocalstringpropertytobeusedlaterforcataloguinganddistributionpurposes.CachingthisvalueisimportantaseachcalltoGetType().Namewillresultinanewstringbeingallocatedontheheap,andwewanttominimizethisasmuchaspossible.Ourcustommessagesmustderivefromthisclass,whichallowsthemtoaddwhateversuperfluousdatatheywish,whilestillmaintainingtheabilitytobesentthroughourmessagingsystem.Takenotethat,despiteacquiringtheTypenameduringthebaseclassconstructor,thenamepropertywillstillcontainthenameofthederivedclass,notthebaseclass.
MovingontoourMessagingSystemclass,weshoulddefineitsfeaturesbywhatkindofrequirementsweneedittofulfill:
ItshouldbegloballyaccessibleAnyobject(MonoBehaviourornot)shouldbeabletoregister/deregisteraslisteners,toreceivespecificmessagetypes(thatis,theObserverpattern)RegisteringobjectsshouldprovideamethodtocallwhenthegivenmessageisbroadcastThesystemshouldsendthemessagetoalllistenerswithinareasonabletimeframe,butnotchokeontoomanyrequestsatonce
AgloballyaccessibleobjectThefirstrequirementmakesthemessagingsystemanexcellentcandidateforaSingletonobject,sinceweshouldonlyeverneedoneinstanceofthesystem.Although,itiswisetothinklongandhardifthisistrulythecasebeforecommittingtoimplementingaSingleton.Ifwelaterdecidethatwewantmultipleinstancesofthisobjecttoexist,thenitcanbedifficulttorefactorduetoallofthedependencieswewillgraduallyintroduceto
http://freepdf-books.com
![Page 118: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/118.jpg)
ourcodebaseasweusethesystemmoreandmore.
Forthisexample,wewillassumethatweareabsolutelypositivethatwewillonlyneedoneofthesesystems,anddesignitaccordingly.
RegistrationMeetingthesecondandthirdrequirementscanbeachievedbyofferingsomepublicmethodsthatallowregistrationwiththemessagingsystem.Ifweforcethelisteningobjecttoprovideusadelegatefunctiontocallwhenthemessageisbroadcast,thenthisallowslistenerstocustomizewhichmethodiscalledforwhichmessage.Thiscanmakeourcodebasemucheasiertounderstand,ifwenamethedelegateafterthemessageitisintendedtoprocess.
TipDelegatefunctionsareincrediblyusefulconstructsinC#thatallowsustopasslocalmethodsaroundasargumentstoothermethods,andaretypicallyusedforcallbacks.ChecktheMSDNC#ProgrammingGuideformoreinformationondelegatesathttps://msdn.microsoft.com/en-us/library/ms173171.aspx.
Insomecases,wemightwishtobroadcastageneralnotificationmessageandhavealllistenersdosomethinginresponse,suchasan“EnemySpawned”message.Othertimes,wemightbesendingamessagethatspecificallytargetsasinglelisteneramongstagroup.Forexample,wemightwishtosendan“EnemyHealthValueChanged”messagethatisintendedforaspecifichealthbarobjectthatisattachedtotheenemythatwasdamaged.Ifweimplementawayforlistenerstostopmessageprocessingearly,thenwecansaveasignificantnumberofCPUcycles,iftherearemanylistenerswaitingforthesamemessagetype.
Thedelegatewedefineshouldthereforeprovideawayofretrievingthemessageviaanargument,andreturnaresponsethatdetermineswhetherornotprocessingforthemessageshouldstopwhenthelistenerisdonewithit.ThedecisiononwhethertostopprocessingornotcanbeachievedbyreturningasimpleBoolean,wheretrueimpliesthatthislistenerhashandledthemessage,andprocessingforthemessagemuststop.
Hereisthedefinitionforthedelegate:
publicdelegateboolMessageHandlerDelegate(BaseMessagemessage);
ListenersmustdefineamethodofthisformandpassareferencetoitwhenitregisterswiththeMessagingSystem,thusprovidinganentrypointforthemessagingsystemtocallwhenthemessageisbroadcast.
MessageprocessingThefinalrequirementforourmessagingsystemisthatthisobjecthassomekindoftiming-basedmechanismbuiltintopreventitfromchokingontoomanymessagesatonce.Thismeansthat,somewhereintheprocess,wewillneedtomakeuseofMonoBehavioureventcallbacksinordertoworkduringUnity’sUpdate()andbeabletocounttime.
http://freepdf-books.com
![Page 119: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/119.jpg)
Thiscanbeachievedwiththestaticclass-basedSingleton(whichwedefinedearlier),whichwouldrequiresomeotherMonoBehaviour-basedgodclasstocallintoit,informingitthattheScenehasupdated.Alternatively,wecanusetheSingletonAsComponenttoachievethesamething,butdosoindependentlyofanygodclass.Theonlydifferencebetweenthetwoiswhetherornotthesystemisdependentonthecontrolofotherobjects.
TheSingletonAsComponentapproachisprobablythebest,sincetherearen’ttoomanyoccasionswherewewouldn’twantthissystemactingindependently,evenifmuchofourgamelogicdependsuponit.Forexample,evenifthegamewaspaused,wewouldn’twantthegamelogictopauseourmessagingsystem.Westillwantthemessagingsystemtocontinuereceivingandprocessingmessagessothatwecan,forexample,keepUI-relatedComponentscommunicatingwithoneanotherwhilethegameplayisinapausedstate.
ImplementingthemessagingsystemLet’sdefineourmessagingsystembyderivingfromtheSingletonAsComponentclass,andprovideamethodforobjectstoregisterwithit:
usingSystem.Collections.Generic;
publicclassMessagingSystem:SingletonAsComponent<MessagingSystem>{
publicstaticMessagingSystemInstance{
get{return((MessagingSystem)_Instance);}
set{_Instance=value;}
}
privateDictionary<string,List<MessageHandlerDelegate>>_listenerDict=
newDictionary<string,List<MessageHandlerDelegate>>();
publicboolAttachListener(System.Typetype,MessageHandlerDelegate
handler){
if(type==null){
Debug.Log("MessagingSystem:AttachListenerfailedduetonomessage
typespecified");
returnfalse;
}
stringmsgName=type.Name;
if(!_listenerDict.ContainsKey(msgName)){
_listenerDict.Add(msgName,newList<MessageHandlerDelegate>());
}
List<MessageHandlerDelegate>listenerList=_listenerDict[msgName];
if(listenerList.Contains(handler)){
returnfalse;//listeneralreadyinlist
}
listenerList.Add(handler);
returntrue;
}
}
http://freepdf-books.com
![Page 120: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/120.jpg)
The_listenerDictvariableisadictionaryofstringsmappedtolistsofMessageHandlerDelegates.Thisdictionaryorganizesourlistenerdelegatesintolistsbywhichmessagetypetheywishtolistento.Thus,ifweknowwhatmessagetypeisbeingsent,thenwecanquicklyretrievealistofalldelegatesthathavebeenregisteredforthatmessagetype.Wecantheniteratethroughthelist,queryingeachlistenertoseeifoneofthemwantstohandleit.
TheAttachListener()methodrequirestwoparameters;amessagetypeintheformofaSystem.Type,andaMessageHandlerDelegatetosendthemessagetowhenitcomesthroughthesystem.
MessagequeuingandprocessingInordertoprocessmessages,ourMessagingSystemshouldmaintainaqueueofincomingmessageobjectssothatwecanprocessthemintheordertheyarebroadcasted:
privateQueue<BaseMessage>_messageQueue=newQueue<BaseMessage>();
publicboolQueueMessage(BaseMessagemsg){
if(!_listenerDict.ContainsKey(msg.name)){
returnfalse;
}
_messageQueue.Enqueue(msg);
returntrue;
}
Themethodsimplychecksifthegivenmessagetypeispresentinourdictionarybeforeaddingittothequeue.Thiseffectivelytestswhetherornotanobjectactuallycarestolistentothemessagebeforewequeueittobeprocessedlater.Wehaveintroducedanewprivatemembervariable,_messageQueue,forthispurpose.
Next,we’lladdadefinitionforUpdate().ThismethodwillbecalledregularlybytheUnityEngine.Itspurposeistoiteratethroughthecurrentcontentsofthemessagequeue,onemessageatime,verifywhetherornottoomuchtimehaspassedsincewebeganprocessing,andifnot,passthemalongtothenextstageintheprocess:
privatefloatmaxQueueProcessingTime=0.16667f;
voidUpdate(){
floattimer=0.0f;
while(_messageQueue.Count>0){
if(maxQueueProcessingTime>0.0f){
if(timer>maxQueueProcessingTime)
return;
}
BaseMessagemsg=_messageQueue.Dequeue();
if(!TriggerMessage(msg))
Debug.Log("Errorwhenprocessingmessage:"+msg.name);
if(maxQueueProcessingTime>0.0f)
timer+=Time.deltaTime;
}
http://freepdf-books.com
![Page 121: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/121.jpg)
}
Thetime-basedsafeguardisinplacetomakesurethatitdoesnotexceedaprocessingtimelimitthreshold.Thispreventsthemessagingsystemfromfreezingourgameiftoomanymessagesgetpushedthroughthesystemtooquickly.Ifthetotaltimelimitisexceeded,thenallmessageprocessingwillstop,leavinganyremainingmessagestobeprocessedduringthenextframe.
Lastly,weneedtodefinetheTriggerMessage()method,whichdistributesmessagestolisteners:
publicboolTriggerMessage(BaseMessagemsg){
stringmsgName=msg.name;
if(!_listenerDict.ContainsKey(msgName)){
Debug.Log("MessagingSystem:Message\""+msgName+"\"hasno
listeners!");
returnfalse;//nolistenersformessagesoignoreit
}
List<MessageHandlerDelegate>listenerList=_listenerDict[msgName];
for(inti=0;i<listenerList.Count;++i){
if(listenerList[i](msg))
returntrue;//messageconsumedbythedelegate
}
returntrue;
}
Thismethodisthemainworkhorseofthemessagingsystem.TheTriggerEvent()‘spurposeistoobtainthelistoflistenersforthegivenmessagetypeandgiveeachofthemanopportunitytoprocessit.Ifoneofthedelegatesreturnstrue,thenprocessingofthecurrentmessageceasesandthemethodexits,allowingtheUpdate()methodtoprocessthenextmessage.
Normally,wewouldwanttouseQueueEvent()tobroadcastmessages,butTriggerEvent()canbecalledinstead.ThismethodallowsmessagesenderstoforcetheirmessagestobeprocessedimmediatelywithoutwaitingforthenextUpdate()event.Thisbypassesthethrottlingmechanism,butthismightbenecessaryformessagesthatneedtobesentduringcriticalmomentsingameplay,wherewaitingoneadditionalframemightresultinstrange-lookingbehavior.
ImplementingacustommessageWe’vecreatedthemessagingsystem,butanexampleofhowtouseitwouldhelpuswrapourheadsaroundtheconcept.Let’sstartbydefiningasimplemessageclass,whichwecanusetotransmitsomedata:
publicclassMyCustomMessage:BaseMessage{
publicreadonlyint_intValue;
publicreadonlyfloat_floatValue;
publicMyCustomMessage(intintVal,floatfloatVal{
_intValue=intVal;
_floatValue=floatVal;
http://freepdf-books.com
![Page 122: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/122.jpg)
}
}
Goodpracticeformessageobjectsistomaketheirmembervariablesreadonly.Thisensuresthatthedatacannotbechangedaftertheobject’sconstruction.Thissafeguardsthecontentofourmessagesagainstbeingaltered,asthey’repassedbetweenonelistenerandanother.
MessageregistrationHere’sasimpleclassthatregisterswiththemessagingsystem,requestingtohaveitsHandleMyCustomMessage()methodcalledwheneveraMyCustomMessageobjectisbroadcastfromanywhereinourcodebase:
publicclassTestMessageListener:MonoBehaviour{
voidStart(){
MessagingSystem.Instance.AttachListener(typeof(MyCustomMessage),
this.HandleMyCustomMessage);
}
boolHandleMyCustomMessage(BaseMessagemsg){
MyCustomMessagecastMsg=msgasMyCustomMessage;
Debug.Log(string.Format("Gotthemessage!{0},{1}",
castMsg._intValue,castMsg._floatValue));
returntrue;
}
}
WheneveraMyCustomMessageobjectisbroadcast(fromanywhere!),thislistenerwillretrievethemessagethroughitsHandleMyCustomMessage()method.Itcanthentypecastitintotheappropriatederivedmessagetypeandhandlethemessageinitsownuniqueway.Otherclassescanregisterforthesamemessage,andhandleitdifferentlythroughitsowncustomdelegatemethod(assuminganearlierobjectdidn’treturntruefromitsowndelegate).
WeknowwhattypeofmessagewillbeprovidedbythemsgargumentoftheHandleMyCustomMessage()method,becausewedefineditduringregistrationthroughtheAttachListener()call.Duetothis,wecanbecertainthatourtypecastingissafe,andwecansavetimebynothavingtodoanullreferencecheck,although,technically,thereisnothingstoppingususingthesamedelegatetohandlemultiplemessagetypes!Inthesecases,thoughwewouldneedtoimplementawayofdeterminingwhichmessageobjectisbeingpassed,andtreatitaccordingly.Thebestapproachistodefineauniquemethodforeachmessagetypeinordertokeepthingsappropriatelydecoupled.
NotehowtheHandleMyCustomMessagemethoddefinitionmatchesthefunctionsignatureofMessageHandlerDelegate,andthatitisbeingreferencedintheAttachListener()call.Thisishowwetellthemessagingsystemwhatmethodtocallwhenthegivenmessagetypeisbroadcast,andhowdelegatesensuretypesafety.Ifthefunctionsignaturehadadifferentreturnvalueoradifferentlistofarguments,thenitwouldbeaninvaliddelegatefortheAttachListener()method,andwewouldgetcompilererrors.
http://freepdf-books.com
![Page 123: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/123.jpg)
Thebeautifulpartisthatwe’refreetogivethedelegatemethodwhatevernamewewant.Themostsensibleapproachistonamethemethodafterthemessagewhichithandles.Thismakesitcleartoanyonereadingourcodewhatthemethodisusedforandwhatmessageobjecttypeisrequiredtocallit.
MessagesendingFinally,let’simplementanexampleofsendingamessagesothatwecantestthissystemout!Here’sacomponentthatwillbroadcastaninstanceofourMyCustomMessageclassthroughthemessagingsystemwhentheSpaceBarispressed:
publicclassTestMessageSender:MonoBehaviour{
publicvoidUpdate(){
if(Input.GetKeyDown(KeyCode.Space)){
MessagingSystem.Instance.QueueMessage(newMyCustomMessage(5,
13.355f));
}
}
}
IfweaddboththeTestMessageSenderandTestMessageListenerobjectstoourSceneandpresstheSpacebar,weshouldseealogmessageappearintheconsole,informingusofasuccessfultest:
OurMessagingSystemSingletonobjectwillbecreatedimmediatelyuponSceneinitialization,whentheTestMessageListener‘sStart()methodiscalledanditregisterstheHandleMyCustomMessagedelegate.NoadditionaleffortisrequiredonourparttocreatetheSingletonweneed.
MessagecleanupSincemessageobjectsareclasses,theywillbecreateddynamicallyinheapmemoryandwillbedisposedofshortlyafterwardswhenthemessagehasbeenprocessedanddistributedamongstalllisteners.However,asyouwilllearninChapter7,MasterfulMemoryManagement,thiswilleventuallyresultinagarbagecollectionasheapmemoryaccumulatesovertime.Ifourapplicationrunsforlongenough,itwilleventuallyresultintheoccasionalgarbagecollection.Therefore,itiswisetousethemessagingsystemsparinglyandavoidspammingmessagestoofrequentlyoneveryupdate.
Themoreimportantclean-upoperationtoconsiderisderegistrationofdelegatesifanobjectneedstobedestroyedorde-spawned.Ifwedon’thandlethisproperly,thenthemessagingsystemwillhangontodelegatereferencesthatpreventobjectsfrombeingfullydestroyedandfreedfrommemory.
Essentially,weneedtopaireveryAttachListener()callwithanappropriateDetachListener()methodwhentheobjectisdestroyed,disabled,orweotherwisedecide
http://freepdf-books.com
![Page 124: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/124.jpg)
thatwenolongerneedittobequeriedwhenmessagesarebeingsent.
ThefollowingmethoddefinitionintheMessagingSystemclasswilldetachalistenerforaspecificevent:
publicboolDetachListener(System.Typetype,MessageHandlerDelegate
handler)
{
if(type==null){
Debug.Log("MessagingSystem:DetachListenerfailedduetonomessage
typespecified");
returnfalse;
}
stringmsgName=type.Name;
if(!_listenerDict.ContainsKey(type.Name)){
returnfalse;
}
List<MessageHandlerDelegate>listenerList=_listenerDict[msgName];
if(!listenerList.Contains(handler)){
returnfalse;
}
listenerList.Remove(handler);
returntrue;
}
HereisanexampleusageoftheDetachListener()method,addedtoourTestMessageListenerclass:
voidOnDestroy(){
if(MessagingSystem.IsAlive){
MessagingSystem.Instance.DetachListener(typeof(MyCustomMessage),
this.HandleMyCustomMessage);
}
}
NotehowthisdefinitionmakesuseoftheIsAlivepropertydeclaredintheSingletonAsComponentclass.Thissafeguardsusagainsttheaforementionedproblemsduringapplicationshutdown,wherewecannotguaranteethattheSingletonwasdestroyedlast.
WrappingupthemessagingsystemCongratulationsareinorder,aswehavefinallybuiltafullyfunctionalglobalmessagingsystemthatanyandallobjectscaninterfacewith,tosendmessagesbetweenoneanother!AusefulfeatureofthisapproachisthatitisMonoBehaviour-agnostic,meaningthatthemessagesendersandlistenersdonotevenneedtoderivefromMonoBehaviourtointerfacewiththemessagingsystem;itjustneedstobeaclassthatprovidesamessagetypeandadelegatefunctionofthematchingfunctionsignature.
AsfarasbenchmarkingtheMessagingSystemclassgoes,weshouldfindthatifitis
http://freepdf-books.com
![Page 125: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/125.jpg)
capableofprocessinghundreds,ifnotthousandsofmessagesinasingleframewithminimalCPUoverhead(dependingontheCPU,ofcourse).TheCPUusageisessentiallythesamewhetheronemessageisbeingdistributedto100differentlisteners,100messagesaredistributedtojustonelistener.Itcostsaboutthesameeitherway.
Evenifwe’repredominantlysendingmessagesduringUIorgameplayevents,thisisprobablyfarmorepowerthanweneed.So,ifitdoesseemtobecausingperformanceproblems,thenit’sfarmorelikelytobecausedbywhatthelistenerdelegatesaredoingwiththemessagethanthemessagingsystem’sabilitytoprocessthosemessages.
Therearemanywaystoenhancethemessagingsystemtoprovidemoreusefulfeatureswemayneedinthefuture,suchas:
Allowmessagesenderstosuggestadelay(intimeorframecount)beforeamessageisprocessedanddistributedAllowmessagelistenerstodefineapriorityforhowurgentlyitshouldreceivemessagescomparedtootherlistenerswaitingforthesamemessagetype—awayofskippingtothefrontofthequeueifitregisteredlaterthanotherlistenersImplementsomesafetycheckstohandlesituationswherealistenergetsaddedtothelistofmessagelistenersforaparticularmessage,whileamessageofthattypeisstillbeingprocessed—C#willthrowanenumerationexceptionatussincethedelegatelistwillbechangedbyAttachListener(),whileitisstillbeingiteratedthroughinTriggerEvent()
Atthispoint,wehaveprobablyexploredmessagingsystemsenough,sothesetaskswillbeleftasanacademicexerciseforyoutoundertake,ifyoubecomecomfortableusingthissolutioninyourgames.
Let’sexploresomefurthertechniquesthatwecanusetoimproveperformancethroughscripting.
http://freepdf-books.com
![Page 126: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/126.jpg)
http://freepdf-books.com
![Page 127: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/127.jpg)
DisablingunusedscriptsandobjectsScenescangetprettybusysometimes,especiallywhenwe’rebuildinglarge,openworlds.ThemoreobjectsinvokingcodeinanUpdate()method,theworsethingswillscaleandthesloweryourgamebecomes.However,muchofwhatisbeingprocessedmaybecompletelyunnecessaryifitisoutsideoftheplayer’svieworsimplytoofarawaytomatter.Thismaynotbeapossibilityinlargecity-buildingsimulationgameswheretheentiresimulationmustbeprocessedatalltimes,butitisoftenpossibleinfirstpersonandracinggames,wheretheplayeriswanderingaroundalargeexpansivearea,wherenon-visibleobjectscanbetemporarilydisabledwithouthavinganynoticeableeffectongameplay.
http://freepdf-books.com
![Page 128: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/128.jpg)
DisablingobjectsbyvisibilitySometimes,wewantComponentsorGameObjectstobedisabledwhenthey’renotvisible.Unitycomeswithbuilt-inrenderingfeaturestoavoidrenderingobjectsthatarenotvisiblebyCameras(FrustumCulling,whichisautomaticinallversions),andtoavoidrenderingobjectsthatarehiddenbehindotherobjects(OcclusionCulling,tobediscussedinChapter6,DynamicGraphics),butthisdoesnotaffectComponentsthatarenon-renderable,suchasAIscripts.Wemustcontrolthatbehaviorourselves.
ThisproblemcanbesolvedeasilybyusingtheOnBecameVisible()andOnBecameInvisible()MonoBehaviourcallbacks.Asthenamesimply,thesecallbackmethodsareinvokedwhenarenderableobjecthasbecomevisibleorinvisiblewithrespecttothegameviewandanyCamerasinourScene.Inaddition,whentherearemultipleCamerasinaScene(forexample,alocalmultiplayergame),thecallbacksareonlyinvokediftheobjectbecomesvisibletoanyoneCamera,andbecomesinvisibletoallCameras.Thismeanstheaforementionedcallbackswillbecalledatexactlytherighttimestoimplementthisfeature.
Sincethevisibilitycallbacksrelatetoandcommunicatewiththerenderingsystem,theGameObjectmusthavearenderableobjectattached,suchasaMeshorSkinnedMesh.WemustensurethattheComponentswewanttoreceivethevisibilitycallbacksfromareattachedtothesameGameObjectastherenderableobjectandnotsomeparentorsub-object,otherwisetheywon’tbeinvoked.
TipNotethatUnityalsocountsthehiddencameraoftheSceneViewtowardstheOnBecameVisible()andOnBecameInvisible()callbacks.IfwefindthatthesemethodsarenotbeinginvokedproperlyduringPlayModetesting,makesuretoturntheSceneViewCameraawayfromeverything.
Toenable/disableindividualcomponentswiththevisibilitycallbacks,wecanaddthefollowingmethods:
voidOnBecameVisible(){enabled=true;}
voidOnBecameInvisible(){enabled=false;}
And,toenable/disabletheentireGameObjecttheComponentisattachedto,wecanimplementthemethodsthiswayinstead:
voidOnBecameVisible(){gameObject.SetActive(true);}
voidOnBecameInvisible(){gameObject.SetActive(false);}
http://freepdf-books.com
![Page 129: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/129.jpg)
DisablingobjectsbydistanceInothersituations,wewantComponentsorGameObjectstobedisabledaftertheyarefarenoughawayfromtheplayer,suchthattheymaybebarelyvisible,buttoofarawaytomatter.AgoodcandidateforthistypeofactivityisroamingAIcreaturesthatwewanttoseeatadistance,butwherewedon’tneedittoprocessanything.
ThefollowingcodeisasimpleCoroutinethatperiodicallychecksthetotaldistancefromthetargetobjectanddisablesitselfifitstraystoofarawayfromit:
[SerializeField]GameObject_target;
[SerializeField]float_maxDistance;
[SerializeField]int_coroutineFrequency;
voidStart(){
StartCoroutine(DisableAtADistance());
}
IEnumeratorDisableAtADistance(){
while(true){
floatdistSqrd=(Transform.position-
_target.transform.position).sqrMagnitude;
if(distSqrd<_maxDistance*_maxDistance){
enabled=true;
}else{
enabled=false;
}
for(inti=0;i<_coroutineFrequency;++i){
yieldreturnnewWaitForEndOfFrame();
}
}
}
WeshouldassignthePlayerobject(orwhateverobjectwewantittocomparewith)tothe_targetfieldintheInspector,definethemaximumdistancein_maxDistance,andmodifythefrequencywithwhichtheCoroutineisinvokedbyusingthe_coroutineFrequencyproperty.Anytimetheobjectgoesfurtherthan_maxDistancedistanceawayfromtheobjectassignedto_target,itwillbedisabled.Itwillbere-enabledifitreturnswithinthatdistance.
Asubtleperformance-enhancingfeatureofthisimplementationiscomparingagainstdistance-squaredinsteadoftherawdistance.Thisleadsusconvenientlytoournexttip.
http://freepdf-books.com
![Page 130: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/130.jpg)
http://freepdf-books.com
![Page 131: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/131.jpg)
Considerusingdistance-squaredoverdistanceItissafetosaythatCPUsarerelativelygoodatmultiplyingfloating-pointnumberstogether,butrelativelydreadfulatcalculatingsquarerootsfromthem.EverytimeweaskaVector3tocalculateadistancewiththemagnitudepropertyorwiththeDistance()method,we’reaskingittoperformasquarerootcalculation(asperthePythagoreantheorem),whichcancostalotofCPUoverheadcomparedtomanyothertypesofvectormathcalculations.
However,theVector3classalsooffersasqrMagnitudeproperty,whichisthesameasdistance,onlysquared.Thisletsusperformessentiallythesamecomparisoncheckwithouttheexpensivesquarerootincluded,solongaswealsosquarethevaluewe’retryingtocompareitagainst;or,todescribethismathematically,ifthemagnitudeofAislessthanthemagnitudeofB,thenA2willbelessthanB2.
Forexample,considercodelikethefollowing:
floatdistance=(transform.position–
other.transform.position).Distance();
if(distance<targetDistance){
//dostuff
}
Thiscanbereplacedwiththefollowingandachieveanearlyidenticalresult:
floatdistanceSqrd=(transform.position–
other.transform.position).sqrMagnitude;
if(distanceSqrd<targetDistance*targetDistance){
//dostuff
}
Thereasontheresultisnearlyidenticalisbecauseoffloating-pointprecision.We’relikelytolosesomeoftheprecisionthatwewouldhavehadfromusingthesquare-rootvalues,sincethevaluewillbeadjustedtoanareawithadifferentdensityofrepresentablenumbers;itcanlandexactlyon,orcloserto,amoreaccuraterepresentablenumber,or,morelikely,itwilllandonanumberwithlessaccuracy.Asaresult,thecomparisonisnotexactlythesame,butinmostcases,itiscloseenoughtobeunnoticeable,andtheperformancegaincanbequitesignificantforeachinstructionwereplaceinthismanner.
Ifthisminorprecisionlossisnotimportanttoyou,thenthisperformancetrickshouldbeconsidered.However,ifprecisionisveryimportanttoyou(suchasrunninganaccuratelarge-scalegalacticspacesimulation),thenyoumightwanttolookelsewhereforperformanceimprovements.
Notethatthistechniquecanbeusedforanysquare-rootcalculations;notjustfordistance.Thisissimplythemostcommonexampleyoumightrunacross,andbringtolighttheimportantsqrMagnitudepropertyoftheVector3class—apropertywhichUnityTechnologiesintentionallyexposedforustomakeuseofinthismanner.
http://freepdf-books.com
![Page 132: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/132.jpg)
http://freepdf-books.com
![Page 133: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/133.jpg)
http://freepdf-books.com
![Page 134: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/134.jpg)
AvoidretrievingstringpropertiesfromGameObjectsOrdinarily,retrievingastringpropertyfromanobjectisthesameasretrievinganyotherreferencetypepropertyinC#;itisacquiredwithnoadditionalmemorycost.However,forwhateverarcanereasonhiddenwithintheUnitysourcecode,retrievingstringpropertiesfromGameObjectsduplicatesthestringinmemoryandresultsinaheapallocation.ThisdrawstheattentionoftheGarbageCollector,which,ifwearenotcareful,cancauseCPUspikesthatwillaffectperformanceduringruntime.
ThetwopropertiesofGameObjectaffectedbythisstrangebehavioraretagandname.Retrievingeitherofthesepropertiesforanyreasonwillcauseunnecessaryheapallocations.Therefore,itisunwisetouseeitherpropertyduringgameplay,andyoushouldonlyusetheminperformance-inconsequentialareassuchasEditorScripts.However,theTagsystemiscommonlyusedforruntimeidentificationpurposes,whichcanmakethisasignificantproblemforsometeams.
Forexample,thefollowingcodewouldcauseanadditionalheapmemoryallocationduringeveryiterationoftheloop:
for(inti=0;i<listOfObjects.Count;++i){
if(listOfObjects[i].tag=="Player"){
//dosomethingwiththisobject
}
}
ItisoftenbetterpracticetoidentifyobjectsbytheirComponents,classtypes,andidentifyingvaluesthatdonotinvolvestrings,butsometimeswe’reforcedintoacorner.Maybewedidn’tknowanybetterwhenwestarted,weinheritedsomeoneelse’scodebase,orwe’reusingitasaworkaroundforsomething.Let’sassumethat,forwhateverreason,we’restuckwiththeTagsystem,andwewanttoavoidtheseheapallocations.
Fortunately,thetagpropertyismostoftenusedincomparisonsituations,andGameObjectprovidesanalternativewaytocomparetagproperties,whichdoesnotcauseaheapallocation—theCompareTag()method.
Let’sperformasimpletesttoprovehowthissimplechangecanmakeallthedifferenceintheworld:
voidUpdate(){
intnumTests=10000000;
if(Input.GetKeyDown(KeyCode.Alpha1)){
for(inti=0;i<numTests;++i){
if(gameObject.tag=="Player"){
//dostuff
}
}
}
if(Input.GetKeyDown(KeyCode.Alpha2)){
http://freepdf-books.com
![Page 135: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/135.jpg)
for(inti=0;i<numTests;++i){
if(gameObject.CompareTag("Player")){
//dostuff
}
}
}
}
Wecanexecutethesetestsbypressingthe1and2keystotriggertherespectiveforloop.Herearetheresults:
LookingattheBreakdownviewforeachspike,wecanseetwocompletelydifferentsituations:
Retrievingthetagproperty10milliontimesresultsinabout363MBofmemorybeingallocatedjustforstringsalone.Thistakes2435millisecondstoprocess,where488millisecondsarespentongarbagecollection.Meanwhile,usingCompareTag()10milliontimescosts1788millisecondstoprocess,andcausesnoheapmemoryallocations,andhencenoGarbageCollection.Thisshouldmakeitabundantlyclearthatwemustavoidusingthenameandtagproperties.So,ifTagcomparisonbecomesnecessary,thenweshouldmakeuseofCompareTag().
Notethatpassinginastringliterallike"Player"doesnotresultinaruntimeheapallocation,sincetheapplicationtechnicallyallocatesthisvalueduringinitializationandmerelyreferencesitatruntime.However,ifwedynamicallygeneratethecomparisonstring,thenwewillrunintothesameheapmemoryallocationproblems,becausewe’reessentiallycreatinganewstringobjecteachtime.
http://freepdf-books.com
![Page 136: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/136.jpg)
YouwilllearnmorenuancesabouttheGarbageCollectorandstringusageinChapter7,MasterfulMemoryManagement.
http://freepdf-books.com
![Page 137: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/137.jpg)
http://freepdf-books.com
![Page 138: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/138.jpg)
Update,Coroutines,andInvokeRepeatingUpdateiscalledeveryframe,butsometimeswehackinwaysfortheUpdatetobecalledlessfrequentlythannormal,andperhaps,withoutrealizingit,wecreateasituationwhereanemptymethodiscalledmoreoftenthannot:
voidUpdate(){
_timer+=Time.deltaTime;
if(_timer>_aiUpdateFrequency){
ProcessAI();
_timer-=_aiUpdateFrequency;
}
}
Withthisfunctiondefinition,weareessentiallycallinganemptyfunctionalmosteveryframe.Infact,itisworsethanthat;we’realsoperformingaBooleancheckthatalmostalwaysreturnsfalse.Thisisfineifwedon’tabusetheconcept,butasyou’velearned,havingtoomanyoftheseunnecessaryfunctioncallshidinginourScenecanbeasneakyhitonourperformance.
ThisfunctionisaperfectexampleofafunctionwecanconvertintoaCoroutinetomakeuseoftheirdelayed-invocationproperties:
voidStart(){
StartCoroutine(UpdateAI());
}
IEnumeratorUpdateAI(){
while(true){
yieldreturnnewWaitForSeconds(_aiUpdateFrequency);
ProcessAI();
}
}
However,thisapproachhasitsdrawbacks.Forone,aCoroutinecomeswithanadditionaloverheadcostrelativetoastandardfunctioncall(aroundtwiceasslow),aswellassomeheapmemoryallocationstostorethecurrentstateinmemoryuntilthenexttimeitisinvoked.Secondly,onceinitialized,Coroutinesrunindependent,oftheGameObject’sUpdate()processandwillbeinvokedregardlessofwhethertheGameObjecthasbeendisabledornot.Caremustbetakenbeforedecidingtoadoptthisapproach.
However,ifthesituationisappropriate,thebenefitsofcallingnothingduringmostframes,oftenoutweighstheadditionalcostduringtheframeswhereitisinvoked.Indeed,ifwearen’tperformingtoomanycomplexthingswithyieldstatements,thenwecanoftencreateanevensimplerversionofthemethodusingInvokeRepeating(),whichhasaslightlysmalleroverheadcost(about1.5timesslowerthanastandardfunctioncall):
voidStart(){
InvokeRepeating("ProcessAI",0f,_aiUpdateFrequency);
}
NotethatInvokeRepeatingisalsoindependentoftheGameObject’sUpdate()method,
http://freepdf-books.com
![Page 139: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/139.jpg)
andwillcontinuetobeinvokedeveniftheobjectisdisabled.
Regardlessofwhichapproachwepick,thereisanadditionalrisk—havingtoomanymethodstriggeringinthesameframesimultaneously.ImaginethousandsoftheseobjectsthatinitializedtogetherduringSceneinitialization.Everytime_aiUpdateFrequencysecondsgoby,theywillallinvoketheProcessAI()methodwithinthesameframe,andcauseahugespikeinCPUusage.
Possiblesolutionstothisprobleminclude:
GeneratinganewrandomtimetowaiteachtimethetimerexpiresorCoroutinetriggersSpreadoutCoroutineinitializationsothatonlyahandfulofthemarestartedeachframeDelegatetheresponsibilityofcallingupdatestosomemasterclassthatplacesalimitonthenumberofinvocationsthatoccureachframe
ReducingexcessiveUpdatedefinitionstoasimpleCoroutinecanpotentiallysaveusalotofunnecessaryoverhead,soweshouldconsiderconvertingthemwheneverwefeelitisappropriate.However,wemightalsoconsiderre-evaluatingoursolutiontotheoriginalprobleminordertopreventlotsoftimedeventsalltriggeringatthesamemoment.
AnotherapproachtooptimizingupdatesistonotuseUpdate()atall,ormoreaccurately,toonlyuseitonce.WhenUnitycallsUpdate(),itinvolvesbridgingthegapbetweenaGameObject’snativeandmanagedrepresentationoftheGameObject,whichcanbeacostlytask.Youwilllearnmoreaboutthisnative-managedbridgeinChapter7,MasterfulMemoryManagement,butfornow,justconsiderthateverycallbackwerelyonUnitytoinvokeforuscomeswithahiddenprocessingcostattachedrelativetoastandardfunctioncall.
Wecanthereforeminimizethisoverheadbylimitinghowoftenitneedstocrossthebridge.Wecandothisbyhavingagodclasstakecareofcallingourowncustomupdate-stylemethodacrossallofourcustomComponents,initsowndefinitionofUpdate().Infact,manyUnitydeveloperspreferthisapproachrightfromthestartoftheirprojects,asitgivesthemfinercontroloverwhenandhowupdatespropagatethroughoutthesystem,forthingssuchasmenupausingandcooltimemanipulationeffects.
Allobjectswantingtointegratewithsuchasystemmusthaveacommonentrypoint.Wecanachievethisthroughaninterfaceclass.Interfacesessentiallysetupacontractwherebyanyclassthatimplementstheinterfacemustprovideaspecificseriesofmethods.Inotherwords,ifweknowtheobjectimplementsaninterface,thenwecanbecertainaboutwhatmethodsareavailable.InC#,classescanonlyderivefromasinglebaseclass,buttheycanimplementanynumberofinterfaces(thisavoidsthe“deadlydiamondofdeath”problemthatC++programmersmaybefamiliarwith).
Thefollowinginterfacedefinitionwillsuffice,whichonlyrequirestheimplementingclasstodefineasinglemethod:
publicinterfaceIUpdateable{
voidOnUpdate(floatdt);
http://freepdf-books.com
![Page 140: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/140.jpg)
}
Next,we’lldefineaMonoBehaviourclass,whichimplementsthisinterface:
publicclassUpdateableMonoBehaviour:MonoBehaviour,IUpdateable
{
publicvirtualvoidOnUpdate(floatdt){}
}
Notethatwe’renamingthemethodOnUpdate()ratherthanUpdate().We’redefiningacustomversionofthesameconcept,butwewanttoavoidnamecollisionswiththestandardUpdate()callback.
TheOnUpdate()methodoftheUpdateableMonoBehaviourclassretrievesthecurrentdeltatime(dt),tospareusfromabunchofunnecessaryTime.deltaTimecalls.We’vealsomadethefunctionvirtual,toallowderivedclassestocustomizeit.However,asyouknow,UnityautomaticallygrabsandinvokesmethodsdefinedwiththenameUpdate(),butsincewe’redefiningourowncustomupdatewithadifferentname,thenweneedtoimplementsomethingthatwillcallthismethodwhenthetimeisappropriate;somekindof“GameLogic”godclass.
DuringtheinitializationofthisComponent,weshoulddosomethingtonotifyourGameLogicobjectofbothitsexistenceanditsdestruction,sothatitknowswhentostartandstopcallingitsOnUpdate()function.
Inthefollowingexample,wewillassumethatourGameLogicclassisaSingletonComponent,asdefinedearlierinthesectionentitledSingletonComponents,andhasappropriatestaticfunctionsdefinedforregistrationandderegistration(althoughbearinmindthatitcanjustaseasilyuseourmessagingsystem!).
ForMonoBehaviourstohookintothissystem,themostappropriateplaceiswithinStart()andOnDestroy():
voidStart(){
GameLogic.Instance.RegisterUpdateableObject(this);
}
voidOnDestroy(){
GameLogic.Instance.DeregisterUpdateableObject(this);
}
ItisbesttousetheStart()methodforthistask,sinceusingStart()meansthatwecanbecertainallotherpre-existingComponentswillhaveatleasthadtheirAwake()methodscalledpriortothismoment.Thisway,anycriticalinitializationworkwillhavealreadybeendoneontheobjectbeforewestartinvokingupdatesonit.
Notethat,becausewe’reusingStart()inaMonoBehaviourbaseclass,ifwedefineaStart()methodinaderivedclass,thenitwilleffectivelyoverridethebase-classdefinitionandUnitywillgrabthederivedStart()methodasacallbackinstead.Itwould,therefore,bewisetoimplementavirtualInitialize()methodsothatderivedclassescanoverrideittocustomizeinitializationbehaviorwithoutinterferingwiththebaseclass’staskofnotifyingtheGameLogicobjectofourcomponent’sexistence.
http://freepdf-books.com
![Page 141: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/141.jpg)
Forexample:
voidStart(){
GameLogic.Instance.RegisterUpdateableObject(this);
Initialize();
}
protectedvirtualvoidInitialize(){
//derivedclassesshouldoverridethismethodforinitializationcode
}
Weshouldtrytomaketheprocessasautomaticaspossibletospareourselveshavingtore-implementthesetasksforeachnewComponentwedefine.AssoonasaclassinheritsfromourUpdateableMonoBehaviourclass,thenshouldbesecureintheknowledgethatitsOnUpdate()methodwillbecalledwheneveritisappropriate.
Finally,weneedtoimplementtheGameLogicclass.TheimplementationisprettymuchthesamewhetheritisaSingletonComponentorastandaloneComponent,andwhetherornotitusestheMessagingSystem.Eitherway,ourUpdateableMonoBehaviourclassmustregisterandderegisterasIUpdateableObjectobjects,andtheGameLogicclassmustuseitsownUpdate()callbacktoiteratethrougheveryregisteredobjectandcalltheirOnUpdate()function.
HereistheclassdefinitionfortheGameLogicsystem:
publicclassGameLogic:SingletonAsComponent<GameLogic>{
publicstaticGameLogicInstance{
get{return((GameLogic)_Instance);}
set{_Instance=value;}
}
List<IUpdateableObject>_updateableObjects=newList<IUpdateableObject>();
publicvoidRegisterUpdateableObject(IUpdateableObjectobj){
if(!_Instance._updateableObjects.Contains(obj)){
_Instance._updateableObjects.Add(obj);
}
}
publicvoidDeregisterUpdateableObject(IUpdateableObjectobj){
if(_Instance._updateableObjects.Contains(obj)){
_Instance._updateableObjects.Remove(obj);
}
}
voidUpdate(){
floatdt=Time.deltaTime;
for(inti=0;i<_Instance._updateableObjects.Count;++i){
_Instance._updateableObjects[i].OnUpdate(dt);
}
}
}
IfwemakesureallofourcustomMonoBehavioursinheritfromthe
http://freepdf-books.com
![Page 142: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/142.jpg)
UpdateableMonoBehaviourclass,thenwe’veeffectivelyreplacedNinvocationsoftheUpdate()callbackwithjustoneUpdate()callback,plusNvirtualfunctioncalls.Thiscansaveusalargeamountofperformanceoverhead,becauseeventhoughwe’recallingvirtualfunctions,we’restillkeepingtheoverwhelmingmajorityofupdatebehaviorinsidemanagedcode,andavoidingthenative-managedbridgeasmuchaspossible.
Dependingonhowdeepyoualreadyareintoyourcurrentproject,suchchangescanbeincrediblydaunting,time-consuming,andlikelytointroducealotofbugsassubsystemsareupdatedtomakeuseofacompletelydifferentsetofdependencies.However,thebenefitscanoutweightherisksiftimeisonyourside.ItwouldbewisetodosometestingonagroupofobjectsinaScenethatissimilarlydesignedtoyourcurrentScenefilestoverifyifthebenefitsoutweighthecosts.
http://freepdf-books.com
![Page 143: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/143.jpg)
http://freepdf-books.com
![Page 144: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/144.jpg)
ConsidercachingTransformchangesTheTransformComponentonlystoresdatarelativetoitsownparent.ThismeansthataccessingandmodifyingaTransformComponent’sposition,rotation,andscalepropertiescanresultinalotofunanticipatedmatrixmultiplicationcalculationstogeneratethecorrectTransformrepresentationfortheobjectthroughitsparents’Transforms.ThedeepertheobjectisintheHierarchy,themorecalculationsareneededtodeterminethefinalresult.Tomakemattersworse,changestoaTransformComponentalsosendinternalnotificationstocolliders,rigidbodies,lights,andcameras,whichmustbeprocessed.
However,thisalsomeansthatusinglocalPosition,localRotation,andlocalScalehavearelativelytrivialcostassociatedwiththem,becausethevaluescanberetrievedandwrittenastheyarepassedin.Therefore,theselocalpropertyvaluesshouldbeusedwheneverpossible.However,changingourmathematicalcalculationsfromworldspacetolocalspacecanovercomplicatewhatwereoriginallysimple(andsolved!)problems,somakingsuchchangesrisksbreakingourimplementationandintroducingalotofunexpectedbugs.Sometimesit’sworthabsorbingaminorperformancehitinordertosolveacomplex3Dmathematicalproblemmoreeasily!
Inaddition,itisnotuncommon,duringsomecomplexevent,wereplaceaTransform’spropertiesmultipletimesinthesameframe(althoughthisisprobablyawarningsignofover-engineereddesign).WecanconsiderminimizingthenumberoftimeswemodifytheTransformvaluesbycachingtheminamembervariableandcommittingthemonlyattheendoftheframe,asfollows:
privatebool_positionChanged;
privateVector3_newPosition;
publicvoidSetPosition(Vector3position){
_newPosition=position;
_positionChanged=true;
}
voidFixedUpdate(){
if(_positionChanged){
transform.position=_newPosition;
_positionChanged=false;
}
}
ThiscodewillonlycommitchangestothepositioninthenextFixedUpdate()method.
Notethatthiswillnotresultinsluggish-lookingbehaviorduringgameplay,sinceallphysicscalculationsareperformedimmediatelyafterFixedUpdate().TherewouldnotbeanyframesrenderedbeforethephysicsenginegetsachancetorespondtotheTransformchange.
http://freepdf-books.com
![Page 145: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/145.jpg)
http://freepdf-books.com
![Page 146: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/146.jpg)
FasterGameObjectnullreferencechecksItturnsoutthatperforminganullreferencecheckagainstaUnityobjectinvokesamethodontheothersideofthenative-managedbridge(mentionedearlierandexploredinmoredetailinChapter7,MasterfulMemoryManagement),which,asexpected,resultsinsomeunnecessaryperformanceoverhead:
if(gameObject!=null){
//dostuffwithgameObject
}
Thereisasimplealternativethatgeneratesafunctionallyequivalentoutput,butoperatesaroundtwiceasquickly(althoughitdoesobfuscatethepurposeofthecodealittle):
if(!System.Object.ReferenceEquals(gameObject,null)){
//dostuffwithgameObject
}
ThisappliestobothGameObjectsandComponents,aswellasotherUnityobjects,whichhavebothnativeandmanagedrepresentations.However,somerudimentarytestingrevealsthateitherapproachstillconsumesmerenanosecondsonanIntelCorei53570Kprocessor.So,unlessyouareperformingmassiveamountsofnullreferencechecks,thenthegainsmightbemarginalatbest.
However,itisnoteworthyinthesensethattherecanbemanyothersimplealternativesthathaveyettobediscovered,whichcanhelpimproveperformancebycircumventingthenative-managedbridge.
http://freepdf-books.com
![Page 147: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/147.jpg)
http://freepdf-books.com
![Page 148: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/148.jpg)
SummaryThischapterintroducedyoutomanymethodsofimprovingyourscriptingpracticesintheUnityEngine,withtheaimofimprovingperformanceif(andonlyif)youhavealreadyproventhemtobethecauseofaperformanceproblem.Someofthesetechniquesdemandsomeforethoughtandprofilinginvestigationbeforebeingimplemented,sincetheyoftencomewithintroducingadditionalrisksorobfuscatingourcodebasefornewdevelopers.Workflowisoftenjustasimportantasperformanceanddesign,sobeforeyoumakeanyperformancechangestothecode,youshouldconsiderwhetherornotyou’resacrificingtoomuchonthealtarofperformanceoptimization.
Wewillinvestigatemoreadvancedscriptingimprovementtechniqueslater,inChapter7,MasterfulMemoryManagement,butlet’stakeabreakfromstaringatcodeandexploresomewaystoimproveapplicationperformanceusingbuilt-inUnityfeaturessuchasStaticandDynamicBatching.
http://freepdf-books.com
![Page 149: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/149.jpg)
http://freepdf-books.com
![Page 150: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/150.jpg)
Chapter3.TheBenefitsofBatchingIn3Dgraphicsandgames,batchingisaverygeneraltermdescribingtheprocessofgroupingalargenumberofwaywardpiecesofdataandprocessingthemtogetherasasingle,largeblockofdata.Thegoalofthisprocessistoreducecomputationtime,oftenbyexploitingparallelprocessingorreducingoverheadcosts,iftheentirebatchistreatedasindividualelements.Insomecases,theactofbatchingcentersaroundmeshes,largesetsofvertices,edges,UVcoordinates,andsoon,whichareusedtorepresenta3Dobject.However,thetermcouldjustaseasilyrefertotheactofbatchingaudiofiles,sprites,andtexturefiles(alsoknownasAtlasing),andotherlargedatasets.
So,justtoclearupanyconfusion,whenthetopicofbatchingismentionedinUnity,itisusuallyreferringtothetwoprimarymechanismsitoffersforbatchingmeshfiles:StaticandDynamicBatching.Thesemethodsareessentiallyaformofgeometryinstancing,whereweusethesamemeshdatainmemorytorepeatedlyrenderthesameobjectmultipletimeswithoutneedingtopreparethedatamorethanonce.
Thesebatchingfeaturesofferusopportunitiestoimprovetheperformanceofourapplication,butonlyaslongastheyareusedwisely.Theyarefairlynuancedsystems,andtherehasbeenalotofconfusionsurroundingtheconditionsthattheyaretriggeredunder,andjustasimportantly,underwhatconditionswewouldevenseeaperformanceimprovement.Insomecases,batchingcanactuallydegradeperformanceifbatchesareaskedtoprocessdatasetsunderconditionsthatdon’tfitaveryparticularmold.
ThebatchingsystemsinUnityaremostlyablackbox,inwhichUnitytechnologieshavenotrevealedmuchdetailed,technicalinformationabouttheirinnerworkings.But,basedontheirbehavior,profilerdata,andthelistofrequirementsneededtomakethemwork,wecanstillinferagreatdeal.Thischapterintendstodispelmuchofthemisinformationfloatingaroundaboutbatchingsystems.Wewillobserve,viaexplanation,exploration,andexamples,justhowthesetwobatchingmethodsoperate.Thiswillenableustomakeinformeddecisions,makingthemostofthemtoimproveourapplication’sperformance.
http://freepdf-books.com
![Page 151: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/151.jpg)
DrawCallsBeforewediscussStaticandDynamicBatchingindependently,let’sfirstunderstandtheproblemsthattheyarebothtryingtosolvewithinthegraphicspipeline.Wewilltrytokeepfairlylightonthetechnicalities.WewillexplorethistopicingreaterdetailinChapter6,DynamicGraphics.
TheprimarygoalofthesebatchingmethodsistoreducethenumberofDrawCallsrequiredtorenderallobjectsinthecurrentview.Atitsmostbasicform,aDrawCallisarequestsentfromtheCPUtotheGPU,askingittodrawanobject.But,beforeaDrawCallcanberequested,severalimportantcriterianeedtobemet.Firstly,meshandtexturedatamustbepushedfromtheCPUmemory(RAM)intoGPUmemory(VRAM),whichtypicallytakesplaceduringinitializationoftheScene.Next,theCPUmustpreparetheGPUbyconfiguringtheoptionsandrenderingfeaturesthatareneededtoprocesstheobjectthatisthetargetoftheDrawCall.
ThesecommunicationtasksbetweentheCPUandGPUtakeplacethroughtheunderlyinggraphicsAPI,whichcouldbeeitherDirectXorOpenGLdependingontheplatformwe’retargetingandcertaingraphicssettings.TheseAPIsfeaturemanycomplexandinterrelatedsettings,statevariables,anddatasetsthatcanbeconfigured,andtheavailablefeatureschangeenormouslybasedonthehardwaredevicewe’reoperatingon.ThemassivearrayofsettingsthatcanbeconfiguredbeforerenderingasingleobjectisoftencondensedintoasingletermknownastheRenderState.UntiltheseRenderStateoptionsarechanged,theGPUwillmaintainthesameRenderStateforallincomingobjectsandrendertheminasimilarfashion.
ChangingtheRenderStatecanbeatime-consumingprocess.Wewon’tgotoodeeplyintotheparticularsofthis,butessentiallytheRenderStateisacollectionofglobalvariablesthataffecttheentiregraphicspipeline.Changingaglobalvariablewithinaparallelsystemismucheasiersaidthandone.AlotofworkmusthappenontheGPUtosynchronizetheoutcomeofthesestatechanges,whichofteninvolveswaitingforthecurrentbatchtofinish.InamassivelyparallelsystemsuchasaGPU,alotofvaluabletimecanbelostwaitingforonebatchtofinishbeforebeginningthenext.ThingsthatcantriggerthissynchronizationmayincludepushinganewtextureintotheGPU,changingaShader,changinglightinginformation,shadows,transparency,andchangingalmostanysettingwecanthinkof.
OncetheRenderStatehasbeenconfigured,theCPUmustdecidewhatmeshtodraw,whatMaterialitshoulduse,andwheretodrawtheobjectbasedonitsposition,rotation,andscale(allrepresentedwithinasingletransformmatrix).InordertokeepthecommunicationbetweenCPUandGPUverydynamic,newrequestsarepushedintoaCommandBuffer.Thisisabufferedlist,whichtheCPUsendsinstructionsto,andwhichtheGPUpullsfromwheneveritfinishesthepreviouscommand.TheCommandBufferbehaveslikeaFirstInFirstOut(FIFO)queue,andeachtimetheGPUfinishesonecommand,itpopstheoldestcommandfromthefrontofthequeue,processesit,andrepeatsuntiltheCommandBufferisempty.
http://freepdf-books.com
![Page 152: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/152.jpg)
NotethatanewDrawCalldoesnotnecessarilymeanthatanewRenderStatemustbeconfigured.IftwoobjectssharetheexactsameRenderStateinformation,thentheGPUcanimmediatelybeginrenderingthenewobjectsincethesameRenderStateismaintainedafterthelastobjectwasfinished.
Becausetherenderingprocessrequirestwohardwarecomponentstoworkintandem,itisverysensitivetobottlenecks,whichcouldoriginateinoneorbothcomponents.GPUscanrenderindividualobjectsincrediblyquickly,soiftheCPUisspendingtoomuchtimegeneratingDrawCallcommands(orsimplygeneratingtoomanyofthem),thentheGPUwillwaitforinstructionsmoreoftenthanitisworking.Inthiscase,ourapplication’sgraphicswouldbeCPU-bound.We’respendingmoretimewaitingontheCPUtodecidewhattodraw,thantheGPUspendsdrawingit.Conversely,beingGPU-boundmeanstheCommandBufferfillsupwithrequestsastheGPUcannotprocessrequestsfromtheCPUquicklyenough.
NoteYouwilllearnmoreaboutwhatitmeanstohaverenderingbottlenecksineithertheCPUorGPU,andhowtosolvebothcases,inChapter6,DynamicGraphics.
Anothercomponentwhichcanimpedethespeedofgraphicsactivityinthischainofeventsiswithinthehardwaredriver.ThiscomponentmediatescommandscomingthroughthegraphicsAPI,whichcancomefrommultiplesourcessuchasourapplication,otherapplications,andeventheOperatingSystemitself(suchasrenderingthedesktop).Becauseofthis,usingupdateddriverscansometimesresultinafairlysignificantincreaseinperformance!
Next-generationgraphicsAPIs,suchasMicrosoft’sDirectX12,Apple’sMetal,andtheKronosGroup’sVulcan,allaimtoreducetheoverheadonthedriverbysimplifyingandparallelizingcertaintasks;particularly,howinstructionsarepassedintotheCommandBuffer.OncetheseAPIsbecomecommonplace,wemaybeabletogetawaywithusingsignificantlymoreDrawCallscomfortablywithinourapplication.ButuntiltheseAPIsmature,wemusttreatourDrawCallconsumptionwithagooddealofconcern,inordertoavoidbecomingCPU-bound.
http://freepdf-books.com
![Page 153: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/153.jpg)
http://freepdf-books.com
![Page 154: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/154.jpg)
MaterialsandShadersShadersareshortprogramswhichdefinehowtheGPUshouldrenderincomingvertexandpixeldata.AShaderonitsowndoesnothavethenecessaryknowledgeofstatetoaccomplishanythingofvalue.Itrequiresinputssuchasdiffusetextures,normalmaps,colors,andsoon,andmustdecidewhatRenderStatevariablesarerequiredinordertocompleteitsintendedtask.
Unity’sMaterialsystemisessentialtoprovidingthisinformationtoourShaders.Ultimately,thisjustmeansaShaderisdependentuponaMaterialinordertobeusedtorenderanobject.EveryShaderneedsaMaterial,andeveryMaterialmusthaveaShader.EvennewlyimportedmeshesthatareintroducedintotheScenewithoutanyassignedMaterialsareautomaticallyassignedadefault(hidden)Material,whichgivesthemabasicdiffuseShaderandawhitecoloration.So,thereisnowayofgettingaroundthisrelationship.
NoteAsingleMaterialcanonlysupportasingleShader.TheuseofmultipleShadersonthesamemeshrequiresseparateMaterialstobeassignedtodifferentpartsofthesamemesh.
ThesetwosystemscapturethemajorityoftheRenderStatevariableswediscussedintheprevioussection.Asaresult,ifwecanminimizethenumberofMaterialsbeingusedtorendertheScene,thenweminimizetheamountofRenderStatechangesrequired,andhencereducetheamountoftimetheCPUspendspreparingtheGPUeachframe.
Let’sbeginwithasimpleSceneinordertovisualizethebehaviorofMaterialsandbatching.But,beforewestart,weshoulddisableseveralglobaloptionsforrenderingfeaturestoavoiddistractingourselveswithadvancedrenderingfeatures:
NavigatetoEdit|ProjectSettings|QualityandsetShadowstoDisableShadows(orselectthedefaultFastestqualitylevel)NavigatetoEdit|ProjectSettings|Player,opentheOtherSettingstab,anddisableStaticBatching,DynamicBatching,andGPUSkinningiftheyareenabled
TipTheStaticBatchingandGPUSkinningoptionsarenotavailableinUnity4FreeEdition,andrequireanupgradetoUnity4ProEdition.
Next,we’llcreateaScenethatcontainsasingleDirectionalLightandeightmeshes;fourcubes,andfourspheres,whereeachobjecthasitsownuniqueMaterial,position,rotation,andscale:
http://freepdf-books.com
![Page 155: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/155.jpg)
IfweobservetheBatchingvalueintheGameView’sStatspopup,weseeninetotalbatches(notethatthisvaluewillbelabeledDrawCallsintheUnity4Statspopup).UnlesstheCamera’sClearFlagssettingissettoDon’tClear,thenonebatchwillbeconsumeddrawingtheCamerabackground.ThiscouldbetheScene’sSkyboxorasinglequadthatfillsthescreenwithallpixelscoloredaspertheCamera’sBackgroundcolorproperty.
Thenexteightbatchesareusedtodrawoureightobjects.Ineachcase,theDrawCallinvolvespreparingtherenderingsystemusingtheMaterial’spropertiesandaskingtheGPUtorenderthegivenmeshatitscurrentposition,rotation,andscale.TheMaterialalsodefineswhichShaderisused,whichcontrolstheprogrammablepartsofthegraphicspipeline(vertexandfragmentsteps).
NotethatiftheRenderingPathsettingunderthePlayerSettingsissettoForward,thenwecanenableanddisabletheDirectionalLightinourSceneandthenumberofbatchesremainsatnine.ThefirstDirectionalLightinForwardrenderingiseffectivelyfreeatleastintermsofDrawCalls.AssoonasweaddmoreLightstoourScene,whethertheyareDirectional,Point,Spot,orAreaLights,wecauseallobjectstoberenderedwithanadditional“pass”throughtheShaderforeachLight,uptothevalueofthePixelLightCountvalueundertheQualitySettings(lightswithhighbrightnessvaluesareprioritizedfirst).
NoteLightingoptionscanbecomeasignificantsourceofDrawCalls,andyouwilllearnmoreaboutthissysteminChapter6,DynamicGraphics.
Aspreviouslymentioned,wecantheoreticallyminimizethenumberofDrawCallsby
http://freepdf-books.com
![Page 156: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/156.jpg)
reducinghowoftenwecausethesystemtochangeRenderStateinformation.So,partofthegoalthereforeistoreducetheamountofMaterialsweuse.But,ifwesetallobjectstousethesameMaterial,wedon’tseeanybenefitandthenumberofbatchesremainsatnine:
Thisisbecausewe’renotactuallyreducingthenumberofRenderStatechangesnorefficientlygroupingmeshinformation.Withoutanyformofbatching,therenderingsystemisnotsmartenoughtorealizewe’reoverwritingtheexactsameRenderStatevalues,andthenaskingittorenderthesamemeshes,overandoveragain.Thispresentsanopportunitytohavetherenderingprocessrecognizethesesituations,renderallofthesemeshestogetherasoneobject,andavoidunnecessaryDrawCalls.ThisisbasicallyhowDynamicBatchingworkstoreduceourDrawCalls.
http://freepdf-books.com
![Page 157: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/157.jpg)
http://freepdf-books.com
![Page 158: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/158.jpg)
DynamicBatchingThepurposeofDynamicBatchingistobundletogetherlargegroupsofsimplemeshesandpushthemthroughtherenderingsystemasifitwasasinglemesh.OnlymeshesthatarecurrentlyvisibleintheCameraviewarecandidatesforDynamicBatching,whichmeansthatmostofthebatchingworkisaccomplishedatruntime,ratherthanpre-calculated.Thismeansthattheobjectsthatarebatchedtogetherwillvaryfromframetoframe.Hence,thename“Dynamic”Batching.
IfwereturntothePlayerSettingspageandenableDynamicBatching,weshouldseethatthenumberofbatchesdropsfromninedowntosix.DynamicBatchingisautomaticallyrecognizingthatourobjectsshareMaterialandmeshinformationandcancombinethemintoasinglebatchforprocessing.ThisisadecentCPUcost-savingstechniqueandreducesthelikelihoodthatourgamewithbeCPU-bound,sinceitfreesupmoretimeforothertasks,suchasAIandPhysicsprocessing.
Attheriskofsoundingungrateful,weshouldaskourselveswhyweonlysavethreeDrawCalls,andnotsix.Wewouldhopethatthesystemissmartenoughtogroupallofthecubestogetherinonebatchandallofthespheresinanother,takingonlytwoDrawCallstorenderthemall(plusoneDrawCallforthebackground).
ThecompletelistoftherequirementsneededtosuccessfullydynamicallybatchameshcanbefoundintheUnitydocumentationathttp://docs.unity3d.com/Manual/DrawCallBatching.html.
AllmeshinstancesmustusethesameMaterialreferenceOnlyparticlesystemsandmeshrenderersaredynamicallybatched.Skinnedmeshrenderers(foranimatedcharacters)andallotherrenderablecomponenttypescannotbebatchedThetotalnumberofvertexattributesusedbytheShadermustbenogreaterthan900Eitherallmeshinstancesshoulduseauniformscaleorallmeshesshoulduseanonuniformscale,butnotamixtureofthetwoMeshinstancesshouldrefertothesameLightmapfileTheMaterial’sShadershouldnotdependonmultiplepassesMeshinstancesmustnotreceivereal-timeShadows
TherearealsoacoupleofundocumentedrequirementsthathavebeenrevealedduringsomeUniteConferencepanels:
Thereisalimitof300meshesperbatchTheremustbenomorethan32,000meshindicesintheentirebatch
However,acoupleoftheserequirementsarenotcompletelyintuitiveorclearfromthedescription,whichmeritssomeadditionalexplanation.
http://freepdf-books.com
![Page 159: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/159.jpg)
VertexattributesAvertexattributeisapropertycontainedwithinameshfileonapervertexbasis.Thisincludes,butisnotlimitedto,avertex’sposition,anormalvector(mostoftenusedinlightingcalculations),andUVcoordinates(usedtodefinehowatexturewrapsaroundthemesh).Onlymesheswithlessthan900totalvertexattributesusedbytheShadercanbeincludedinDynamicBatching.
TipNotethatlookingintoamesh’srawdatafilemaycontainlessvertexattributeinformationthanUnityloadsintomemorybecauseofhowtheengineconvertsmeshdatafromoneofseveralrawdataformatsintoaninternalformat.
UsingmoreattributedatapervertexwithintheaccompanyingShaderwillconsumemorefromour900-attributebudgetandhencereducethenumberofverticesthemeshisallowedtohavebeforeitcannolongerbeusedinDynamicBatching.Forexample,asimpleShaderwhichonlyusesthreeattributespervertex,suchassomeofthelegacydiffuseShaders,cansupportDynamicBatchingusingmesheswithupto300vertices.ButamorecomplexShader,requiringfiveattributespervertex,canonlysupportDynamicBatchingwithmeshesupto180vertices.
ThisrestrictioniswhyourSceneonlysavesthreeDrawCallswithDynamicBatchingenabled,despitehavingallobjectssharethesameMaterialreference.ThecubethatisautogeneratedbyUnitycontains8verticeseachwithposition,normal,andUVdata,for24attributesintotal.Thisisfarlessthanthe900-vertexattributelimitwhenallofthisdataisusedbytheShader.However,anautogeneratedspherecontains515vertices,whichclearlycannotbedynamicallybatchedifwecountaposition,normal,andUVcoordinateforeachvertex.ThisexplainsoursixDrawCalls:oneforthebackground,oneforabatchedgroupofcubes,andfourforthespheresthatarenotbeingdynamicallybatched,whichmustberenderedwithseparateDrawCalls.
http://freepdf-books.com
![Page 160: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/160.jpg)
UniformscalingThedocumentationsuggeststhat,generally,objectsshouldeithershareauniformscaleoreachhaveauniquenonuniformscaleinordertobeincludedindynamicbatching.But,inreality,thebehaviorofthisrestrictionchangesslightlydependingonwhichversionofUnitywearerunningduetosomechangestotheDynamicBatchingsysteminUnity5.
TipAuniformscalemeansthatallthreecomponentsofthescalevector(x,y,andz)areidentical.
InbothversionsofUnity,ifallinstancesofameshhaveauniformscale,thentheycanbegroupedtogetherinthesamedynamicbatch.InUnity5,itwilldynamicallybatchallnonuniformlyscaledinstancesofthemeshwiththeoriginalbatch,nomattertheirscale.However,inUnity4,nonuniformlyscaledobjects,usingthesamemeshandMaterial,willbegroupedtogetherintoseparatebatches.
Thisassumeswe’reworkingwithpositivescales.Thescalerestrictiongetsalittleunintuitivewhenwe’redealingwithnegativescales.InUnity4,negativescalesdonotaffectDynamicBatchingandallofthesamerulesapplyasbefore.But,inUnity5,ifthemeshhasoneorthreenegativevaluesinitsscalevector,thenitwillnotbeincludedinthebatch.Ifitcontainstwonegativevalues,thenitcanbebatchedalongwithalloftheotherinstances.Itdoesnotevenmatterwhichofthethreevaluesarenegative,onlythattherearezeroortwoofthem.
Presumably,thisisabi-productofthealgorithmusedtodetectvalidbatchablegroups,sincemirroringameshintwodimensionsismathematicallyequivalenttorotatingthemeshaboutbothofthesameaxes180degrees.Thus,thebehaviorweobserveisjusttheDynamicBatchingsystemautomaticallytransformingtheobjectforus.
So,itisworthkeepinginmindthatDynamicBatchingisalittlemoreefficientinUnity5,butithassometrade-offs.Ifwewishtousenegativescalesasashortcuttomirroramesh,thenitwillbeincapableofbeingDynamicallyBatched.
http://freepdf-books.com
![Page 161: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/161.jpg)
DynamicBatchingsummaryTherewereclearlysomesignificantimprovementsmadetotheDynamicBatchingsysteminUnity5,allowingittobemoreversatiletoavarietyofsituations.However,nomatterwhichversionofUnityweareusing,DynamicBatchingisveryusefulwhenwewishtorenderverylargegroupsofsimplemeshes.
Thedesignofthesystemmakesitidealtousewhenallofthemesheswe’reDynamicallyBatchingaresimpleandnearlyidenticalinappearance.PossiblesituationstoapplyDynamicBatchingcouldbeasfollows:
Alargeforestfilledwithrocks,trees,andbushesAbuilding,factory,orspacestationwithmanycommonelements(computers,pipes,andsoon)throughouttheSceneAgamefeaturingmanydynamic,nonanimatedobjectswithsimplegeometryandparticleeffects(agamesuchasGeometryWarsspringstomind)
ThepotentialbenefitsofDynamicBatchingaresignificantenoughtosetasidesometimetoinvestigateifandwherewecanmakeuseofitinourScene.TherearenottoomanyoccasionswhereDynamicBatchingwouldactuallydegradeperformance.
ThemostcommonmistakewithDynamicBatchingistosetupaScenethatgenerateslotsofbatches,whicheachcontainonlyahandfulofmeshes.Inthesecases,theoverheadcostofdetectingandgeneratingthebatchesmightcostmorethanthetimeitsavesjustmakingaseparateDrawCallforeachmesh.
Inaddition,we’refarmorelikelytoinflictperformancelossesonourapplicationbysimplyassumingDynamicBatchingistakingplace,whenwe’veactuallyforgottenoneoftheessentialrequirements.Everysituationisunique,soitisworthexperimentingwithourMaterials,meshes,andShaderstodeterminewhatcanandcannotbedynamicallybatched.
http://freepdf-books.com
![Page 162: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/162.jpg)
http://freepdf-books.com
![Page 163: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/163.jpg)
StaticBatchingUnityoffersasecondbatchingmechanismthroughStaticBatching.ThepurposeofthisfeatureistograntusawaytobatchnonidenticalmeshesofanysizeintoasinglebatchwithasimilargoalandmethodologytoDynamicBatching,butsolvingtheproblemforadifferentsetofconditions.TheessentialdifferencebetweenthetwobatchingmethodsisthatStaticBatchingoccursduringapplicationinitialization,whereasDynamicBatchingtakesplaceatruntime.WethereforehavealotmorecontroloverwhenandwhereStaticBatchingtakesplace.
NoteStaticBatchingisavailableinalleditionsofUnity5,butonlyintheProEditionofUnity4.Unity4FreeuserswillneedtoupgradetotheProEditiontomakeuseofthisfeature.
TheStaticBatchingsystemhasitsownsetofrequirements:
Asthenameimplies,themeshesmustbeflaggedasStaticAdditionalmemorymustbesetasideforeachmeshbeingstaticallybatchedThemeshinstancescancomefromanysourcemesh,buttheymustsharethesameMaterial
Let’scovereachoftheserequirementsinmoredetail.
http://freepdf-books.com
![Page 164: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/164.jpg)
TheStaticflagStaticBatchingcanonlybeappliedtoobjectswiththeStaticflagenabledor,morespecifically,theBatchingStaticsubflag(alsoknownasStaticEditorFlags).ClickingonthedownarrownexttotheStaticoptionforaGameObjectwillrevealadropdownoftheseStaticEditorFlags,whichcanaltertheobject’sbehaviorforvariousStaticprocesses.
http://freepdf-books.com
![Page 165: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/165.jpg)
MemoryrequirementsTheadditionalmemoryrequirementforStaticBatchingwillvarydependingontheamountofreplicationoccurringwithinthebatchedmeshes.StaticBatchingworksbycombiningallflaggedmeshesintoasingle,largemesh,andpassingitintotherenderingsystemthroughasingleDrawCall.Ifallofthemeshesbeingstaticallybatchedareunique,thenthiswouldcostusnoadditionalmemoryusagecomparedtorenderingtheobjectsnormally,asthesameamountofmemoryspaceisrequiredtostorethemeshes.
However,staticallybatchedduplicatescostusadditionalmemoryequaltothenumberofmeshesmultipliedbythesizeoftheoriginalmesh.Ordinarily,renderingone,ten,oramillionclonesofthesameobjectcostsusthesameamountofmemory,becausethey’reallreferencingthesamemeshdata.Theonlydifferenceisthetransformofeachobject.But,becauseStaticBatchingneedstocopythedataintoalargebuffer,completewithitstransformdata,thisreferencingislost,andanewduplicateoftheoriginalmeshiscopiedintothebufferwithahard-codedtransformposition,regardlessofwhetherthesamemeshhasalreadybeencopiedin.
Therefore,usingStaticBatchingtorender1,000identicaltreeobjectswillcostus1,000timesmorememorythanrenderingthesameobjectsnormally,becauseeachtreemustbecopiedintotheStaticBatchingbufferasauniquesetofvertexdata.ThiscausessomesignificantmemoryconsumptionandperformanceissuesifStaticBatchingisnotusedwisely.
http://freepdf-books.com
![Page 166: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/166.jpg)
MaterialreferencesFinally,wealreadyknowaboutsharingmaterialreferencesasameansofreducingRenderStatechanges,sothisrequirementisfairlyobvious.However,sometimeswe’restaticallybatchingmeshesthatrequiremultiplematerials.Inwhichcase,allmeshesusingadifferentmaterialwillbegroupedtogetherintheirownstaticbatch,andagainforeachuniquematerialbeingused.
Thedownsidetothisdesignfeatureisthat,atbest,StaticBatchingcanonlyrenderallofthestaticmeshesusinganumberofDrawCallsequaltothenumberofmaterialstheyneed.But,thebenefitisthatwecancontrolwhichmeshesgetbatchedtogetherusingdifferentmaterials,effectivelyforcingittostartanewstaticbatchthroughsomecunningmaterialduplication.ThiswillbecomeclearafterwecoversomeoftheStaticBatchingsystem’scaveats.
http://freepdf-books.com
![Page 167: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/167.jpg)
StaticBatchingcaveatsTheStaticBatchingsystemisnotwithoutitsdrawbacks.Becauseofhowitapproachesthebatchingsolution,bycombiningmeshesintoasinglegreatermesh,theStaticBatchingsystemhasafewcaveatsthatweneedtobeawareof.TheseconcernsrangefromminorinconveniencestomajordrawbacksdependingontheScene:
DrawCallsavingsarenotimmediatelyvisiblefromtheStatswindowuntilruntimeStaticobjectsshouldnotbeintroducedtotheSceneatruntimeStaticallybatchedmeshescannotbemovedfromtheiroriginalstartingtransformIfanyoneofthestaticallybatchedmeshesisvisible,thentheentiregroupwillberendered
EditModedebuggingofStaticBatchingTryingtodeterminetheoveralleffectthatStaticBatchingishavingonourScenecanbealittletrickysincenothingisbeingStaticallyBatchedwhileinEditMode.AllofthemagichappensduringSceneinitialization,whichcanmakeitdifficulttodeterminewhatbenefitsStaticBatchingisactuallyproviding.Thisisespeciallytrueifweleaveimplementingthisfeatureuntillateintheprojectlifecycle,wherewecanspendalotoftimelaunching,tweaking,andrelaunchingourScenetoensurewe’regettingtheDrawCallsavingswe’reexpecting.Consequently,itisbesttostartworkingonStaticBatchingoptimizationearlyintheprocessofbuildinganewScene.
AvoidinginstantiatingstaticmeshesatruntimeNewstaticobjectsintroducedintotheScenewillnotbeautomaticallycombinedintoanyexistingbatchbytheStaticBatchingsystem.Todosowouldcauseanenormousruntimeoverheadbetweenrecalculatingthemeshandsynchronizingwiththerenderingsystem,soUnitydoesnotevenattempttodoit.Thisrestrictionmeansweshouldnotattempttodynamicallyinstantiatethestaticallybatchedcontent.AllmesheswewishtostaticallybatchshouldbepresentintheoriginalScenefile.
NoteDynamicinstantiationofobjectscanbeacostlyactioninitsownright.WewillcoversolutionstothatprobleminChapter7,MasterfulMemoryManagement.
Aswiththepreviouscaveat,staticallybatchedmeshesshouldnotbemovedaftertheyhavebeenbatched,sincedoingsowouldgenerateatremendousCPUoverhead.TheStaticBatchingsystemhasalreadytakentheoriginaldataandcombineditintoanewmeshobject.MovingtheoriginalmeshesisbothimpossiblewhiletheStaticflagisenabled,andnotevenrecognizedbytheUnitysystemiftheflagisdisabledandtheobject’stransformischanged.
VisibilityandrenderingThefinalcaveatisperhapsthemostimportant.IfevenasinglevertexofaStaticallyBatchedmeshisvisibletotheCamera,thenthewholemeshwillbepushedintothe
http://freepdf-books.com
![Page 168: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/168.jpg)
renderingsystemandprocessedinitsentirely.WeneedtobesmartabouthowweuseStaticBatchingandoptimizeitsusagetopreventusrenderingagiganticmesheachandeveryframe!
Forexample,ifwehaveaScenewithmanyroomsconnectedtogetherwhichallsharethesameMaterial,thenenablingStaticBatchingforeveryroomobjectwillcauseeverysingleroomtoberenderedevenifonlyasingleroomisvisible,andeveniftheplayerisstaringstraightintoawall.SuchSceneswouldfarebetterusingOcclusionCulling(exploredinChapter6,DynamicGraphics)topreventnonvisibleroomsfrombeingrendered.
Meanwhile,largeoutdoorsceneswillfinditusefultoduplicateMaterials.Thisisausefultricktoforcesimilarobjectstobestaticallybatchedintodifferentgroups.Assigningidentical,butduplicateMaterialstodifferentsectionsoftheworldwillrenderthemthesame;however,theywillbegroupedseparately.ThiswouldincreasethenumberofDrawCalls,butallowustoreusethesameTexture,Material,andShaderfilesfortheentireScene.
DuplicatingMaterialscanbecomeabitofachorefromthemaintenanceperspective,sinceanychangesmadetooneMaterialmustalsobemadetotheothers.Hypothetically,wemightthinkwecanaccomplishthisthroughScriptbyattachingaComponentthatautomaticallyduplicatesaMaterialandassignsittothemeshduringSceneinitialization.Unfortunately,StaticBatchinghappenstooearlyintheinitializationprocessforustointerceptthroughacustomComponentsuchasthis,sothetaskmustbedonethroughtheEditor(agoodopportunitytomakeuseofEditorscripts).
http://freepdf-books.com
![Page 169: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/169.jpg)
StaticBatchingsummaryStaticBatchingisapowerful,butdangeroustool.Ifwedon’tuseitwisely,wecanveryeasilyinflictperformancelossesviamemoryconsumptionandrenderingcostsonourapplication.Italsotakesagoodamountofmanualtweakingandconfiguration.However,itdoeshaveasignificantadvantage:itcanbeusedonobjectsetsofanysize.ThereisessentiallynolimitasfarasStaticBatchingisconcerned.
http://freepdf-books.com
![Page 170: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/170.jpg)
http://freepdf-books.com
![Page 171: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/171.jpg)
SummaryItisclearthattheStaticandDynamicBatchingfeaturesarenosilverbullet.WecannotblindlyapplythemtoanygivenSceneandexpectimprovements.IfourapplicationandScenehappentofitaparticularsetofparameters,thenthesemethodsareveryeffectiveatreducingCPUloadandrenderingbottlenecks.But,ifnot,thensomeadditionalworkisrequiredtoprepareourScenetomatchitsfeaturerequirements.Ultimately,onlyagoodunderstandingofthebatchingsystemsandhowtheyfunctioncanhelpusdeterminewhereandwhenthisfeaturecanbeapplied.
WewillcovermoregraphicsimprovementtechniquesinChapter6,DynamicGraphics.Untilthen,let’smoveontoadifferenttopic,andlookintosomeofthemoresubtleperformanceimprovementsthatwecanachievethroughmanagingourartassetsinintelligentways.
http://freepdf-books.com
![Page 172: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/172.jpg)
http://freepdf-books.com
![Page 173: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/173.jpg)
Chapter4.KickstartYourArtArtisaverysubjectivearea,dominatedbypersonalopinionandpreference.Itcanbedifficulttosaywhetheronepieceofartis“better”thantheother,andit’slikelythatwewon’tbeabletofindcompleteconsensusonouropinions.Thetechnicalaspectsbehindartassetsthatsupportagame’sartistrycanalsobeverysubjective.Therearemultipleworkaroundsthatcanbeimplementedtoimproveperformance,butthesetendtoresultinalossofqualityforthesakeofspeed.Ifwe’retryingtoreachpeakperformance,thenit’simportantthatweconsultwithourteammemberswheneverwedecidetomakeanychangestoourartassetsasitisprimarilyabalancingact,whichcanbeanartforminitself.
Whetherwe’retryingtominimizeourruntimememoryfootprint,keepingthesmallestpossibleexecutablesize,maximizingloadingspeed,ormaintainingconsistencyinframerate,thereareplentyofoptionstoexplore.Therearesomemethodsthatareclearlyalwaysideal,andotherswhichmayrequirealittlemorecareandforethoughtbeforebeingadopted,astheymightresultinreducedqualityorincreasethechancesofdevelopingbottlenecksinothercomponents.
Wewillbeginexaminingaudiofiles,followedbyTexturefiles,andfinishupwithmeshesandanimations.Ineachcase,wewillinvestigatehowUnityloads,stores,andmanipulatestheseassetsduringruntime,whatouroptionsare,andwhatwecandotoavoidbehaviorthatmightgenerateperformancebottlenecks.
http://freepdf-books.com
![Page 174: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/174.jpg)
AudioDependingonthescopeoftheproject,audiofilescanrangeanywherefromthelargestdiskspaceconsumer,tothesmallest.Unity,asaframework,canbeusedtobuildsmallapplicationsthatrequireonlyahandfulofsoundeffectsandasinglebackgroundtrack,ortobuildlargeexpansiveroleplayinggamesthatneedmillionsoflinesofspokendialog,musictracks,andambientsounds.ItwillbeusefultomakesenseofhowaudiofilesaremanagedinUnitytobetterunderstandwhatweshoulddoforthesakeofoptimizationinbothcases.
ManydevelopersaresurprisedtofindthatruntimeaudioprocessingcanturnintoasignificantsourceofCPUandmemoryconsumption.Audioisoftenneglectedonbothsidesofthegamingindustry;developerstendnottocommitmanyresourcestoituntilthelastminute,whileuserswillrarelydrawattentiontoit.Nobodynoticeswhentheaudioisgoodorpassable,butweallknowwhatbadaudiosoundslike;it’sinstantlyrecognizable,jarring,andguaranteedtocatchunwantedattention.Thismakesitcrucialnottosacrificetoomuchaudioclarityinthenameofperformance.
Audiobottleneckscancomefromavarietyofsources.Excessivecompression,toomuchaudiomanipulation,toomanyactiveaudioclips,inefficientmemorystoragemethods,andaccessspeedsareallwaystoinvitepoormemoryandCPUperformance.But,withalittleeffortandunderstanding,allittakesisafewtweakshereandtheretosaveusfromauser-experiencedisaster.
NoteSeveralaudiooptionsarenamedslightlydifferentlybetweenUnity4andUnity5,butthefeaturesareidenticalforallintentsandpurposes.WewillproceedusingtheUnity5nameforeachfeature.
http://freepdf-books.com
![Page 175: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/175.jpg)
LoadingaudiofilesWhenweselectanimportedAudioClipintheUnityEditor,weseethatthefirstoptionisthefile’sLoadType.Therearethreepossiblesettingsavailable:
DecompressOnLoadCompressedInMemoryStreaming
TheactualmomentwhenthefileisfirstloadedwilldependonotherAudioClipsettingsandhowtheyareusedduringruntime,whichwewillexplorelater.Thisoptionmerelydefinesthemethodofloadingwhenitoccurs.
DecompressOnLoadcompressesthefileondisktosavespace,anddecompressesitintomemorywhenitisfirstloaded.Thisisthestandardmethodofloadinganaudiofile,andshouldbeusedinmostcases.
CompressedInMemoryloadsthecompressedfilestraightintomemorywhenitisloaded,anddecompressesitduringruntimewhenitisbeingplayed.ThiswillsacrificeruntimeCPUwhentheclipisplayed,butimprovesloadingspeedandreducesruntimememoryconsumption.Hence,thisoptionisbestusedforverylargeaudiofilesthatareusedfairlyfrequently,orifwe’reincrediblybottleneckedonmemoryconsumptionandarewillingtosacrificesomeCPUcyclestoplaytheAudioClip.
Finally,theStreamingoptionwillload,decode,andplayfileson-the-flyatruntimebygraduallypushingthefilethroughasmallbuffer.ThismethodusestheleastamountofmemoryforaparticularAudioClipandthelargestamountofruntimeCPU.Thiscomeswiththeunfortunatedrawbackthattheycannotbereferencedmorethanonce.AttemptingtostreammultiplecopiesofthesameAudioClipwillgenerateanewbufferforeachinstance,resultinginasignificantamountofRAMandruntimeCPUcostifusedrecklessly.Consequently,thisoptionisbestreservedforsingle-instanceAudioClipsthatplayregularlyandneverneedtooverlapwithotherinstances.Ergo,thissettingisbestusedwithbackgroundmusicandambientsoundeffectsthatneedtoplayduringthemajorityofaScene’slifetime.
ProfilingaudioWecanconfirmmuchofthisbehaviorbyplayingmultipleinstancesofanygivenAudioClipviamultipleAudioSourcesinaScene,andbenchmarkingusingtheAudioViewoftheProfilertoseehowmuchmemoryandCPUisconsumedusingthevariousLoadTypeoptions.However,beawarethattheProfileroutputforaudiomemoryandCPUconsumptioninEditorModecanbeverymisleading,sinceitperformsaudioloadingdifferentlytohowitwouldoccurinaruntimeapplication.
ThefirsttimeweloadtheEditorandenterPlayMode,theEditorwilldecompressaudiofiles,costingacertainamountofmemoryandCPUcyclesduringinitializationinordertoaccomplishthis.WecanobservethememorycostsofthisprocessintheProfilerundertheAudioArea.However,ifwerestarttheScene,thenwemaynoticethatthememoryspentondecompressingaudiofilessuddenlydropstonearly0KB,sincefileshavealreadybeen
http://freepdf-books.com
![Page 176: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/176.jpg)
decompressedandtheEditorhasflushedawaydataitnolongerneeds.Thisisnotrepresentativeofarealsituation,asapplicationswouldneedtoperformthisdecompression.
So,ifwewantaccurateaudioprofilinginUnity,weshouldruntheProfileragainstastandalone,orremote,versionofourapplicationontheintendedplatform/device.
AdditionalloadingoptionsThereisanadditionalpairofoptionsthataffectaudiofileloadingbehavior:
LoadInBackgroundPreloadAudioData
Inthetypicalusecase,whereanAudioClipisassignedtoanAudioSourceComponentinaScene,theaudiofilewillbeloadedintomemoryduringSceneinitialization.But,iftheLoadInBackgroundoptionisenabled,thenloadingtheAudioClipwillbedeferredtoabackgroundtaskthatbeginsoncetheScenehasfinishedinitializingandgameplayhasessentiallybegun.So,itstandstoreasonthatwecanimprovetheSceneloadingspeedbyenablingthisoptionforAudioClipsthatwewon’tneeduntillaterintheScene’slifetime,suchassoundeffectsusedinmid-levelcutScenes.
WecanuseanAudioClipobject’sloadStatepropertytoverifyiftheassetisloadedbeforeattemptingtouseit.But,usingtheLoadInBackgroundoptionrisksintroducingjarringbehaviorifwetrytoaccessasoundfilebeforeitisfullyloaded.Inthesecases,thesoundfilewon’tplayuntilthebackgroundloadingtaskhascompleted,inwhichcasethesoundwillprobablyplayataninappropriatemoment.
Thesecondoption,PreloadAudioData,isenabledbydefault,whichtellstheUnityEnginetoautomaticallybeginloadingthefileduringSceneinitialization.DisablingthisoptiondefersloadingtothefirstinstantthattheAudioSourceobject’sPlay()orPlayOneShot()methodsareinvokedatruntime.ThiswillcauseaspikeintheCPU,astheaudiodataisloadedfromthedisk,decompressed(ornot,dependingontheLoadTypesetting),pushedintomemory,andeventuallyplayedonceloaded.
Duetotheamountofplaybackdelay,andtheperformancecost,itisnotrecommendedtorelyonloadingoccurringatthemomentthataudioplaybackisneeded.WeshouldinsteadcontrolloadingourselvesbycallingtheAudioClipobject’sLoadAudioData()atsomeconvenientmomentbeforethefileisneeded.Moderngamestypicallyimplementconvenientstoppingpointsinlevelstoperformtaskssuchasthis,suchasanelevatorbetweenfloorsorlongcorridors,whereverylittleactionistakingplace.NotethatwecanalsomanuallycontrolthefreeingofaudiofilememoryusingtheAudioClipobject’sUnloadAudioData()method.
Solutionsinvolvingcustomloadingandunloadingofaudiodataviathesemethodswouldneedtobetailor-madetotheparticulargame,dependingonwhenAudioClipsareneeded,howlongthey’reneededfor,howScenesareputtogether,andhowplayer(s)traversethem.Thiscanrequireasignificantnumberofspecial-casechanges,testing,andassetmanagementtweakstoachieve.So,itisrecommendedtosavethisapproachasa“Nuclear
http://freepdf-books.com
![Page 177: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/177.jpg)
Option”tobeusedlateinproduction,intheeventthatallothertechniqueshavenotsucceededaswellaswehoped.
http://freepdf-books.com
![Page 178: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/178.jpg)
EncodingformatsandqualitylevelsUnitysupportsthreegeneral-caseencodingformatsforaudiofiles,withafewspecificcasesthatareplatform-dependent(suchasHEVAGforthePSVitaandXMAforXBoxOne).Wewillfocusonthethreeoptionalencodingformats:
CompressedPCMADPCM
ThecompressionalgorithmusedwiththeCompressedformatwilldependontheplatformbeingtargeted.Standaloneapplications,WebGL,andothernon-mobileplatformsuseOgg-Vorbisforcompression,whilemobileplatformsuseMPEG-3(MP3).
TheaudiofilesweimportintotheUnityEnginecanbeoneofmanypopularaudiofileformats,buttheactualencodingthatisbundledintotheexecutablewillendupinoneofthepreviouslymentionedformats.StatisticsareprovidedforthecurrentlyselectedformatintheareafollowingtheCompressionFormatoption,providinganideaofhowmuchdiskspaceisbeingsavedbythecompression,andhowmuchmemorytheAudioClipwillconsumeatruntime(notethatthisalsodependsonthecurrentlyselectedLoadType).
Theencoding/compressionformatusedcanhaveadramaticeffectonthequality,filesize,andmemoryconsumptionoftheaudiofileduringruntime,andonlytheCompressedoptiongivesustheabilitytoalterthequalitywithoutaffectingthesamplingrateofthefile.ThePCMandADPCMformatsdonotprovidethisluxury,andwe’restuckwithwhateverfilesizethosecompressionformatsdecidetogiveus,unlesswe’rewillingtoreduceaudioqualityforthesakeoffilesizebyreducingthesamplingrate.
Eachencodingandcompressionformatprovidesdifferentbenefitsandpitfalls,andeachaudiofilemaybeabletosacrificeonemetricforanotherbasedonitspurposeandcontents.Ifwewishtoproperlyoptimizeourapplication’saudiofiles,thenweneedtobewillingtousealloftheavailableformatsinasingleapplicationtomakethemostofouraudiofiles.
ThePCMformatisalosslessanduncompressedaudioformat,providingacloseapproximationofanalogaudio.Ittradeslargefilesizesforhigheraudioquality,andisbestusedforveryshortsoundeffectsthatrequirealotofclaritywhereanycompressionwouldotherwisedistorttheexperience.
Meanwhile,theADPCMformatisfarmoreefficientinbothsizeandCPUconsumptionthanPCM,butcompressionresultsinafairamountofnoise.Thisnoisecanbehiddenifitisreservedforshortsoundeffectswithalotofchaos,suchasexplosions,collisions,andimpactsoundswherewemightnotbeawareofanygeneratedartefacts.
Finally,theCompressedformatwillresultinsmallfilesthathavelowerqualitythanPCM,butsignificantlybetterqualitythanADPCM,attheexpenseofadditionalruntimeCPUusage.Thisformatshouldbeusedinmostcases.Thisoptionallowsuscustomizetheresultantqualitylevelofthecompressionalgorithm,totweakqualityagainstfilesize.BestpracticeswiththeQualityslideraretosearchforaqualitylevelthatisassmallas
http://freepdf-books.com
![Page 179: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/179.jpg)
possible,butunnoticeabletousers.Someusertestingmayberequiredtofindthe“sweetspot”foreachfile.
TipDonotforgetthatanyadditionalaudioeffectsappliedtothefileatruntimewillnotplaythroughtheEditorinEditMode,soanychangesshouldbefullytestedthroughtheapplicationinPlayMode.
http://freepdf-books.com
![Page 180: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/180.jpg)
AudioperformanceenhancementsNowthatwehaveabetterunderstandingofaudiofileformats,loadingmethods,andcompressionmodes,let’sexploresomeapproachesthatwecanmaketoimproveperformancethroughtweakingaudiobehavior.
MinimizeactiveAudioSourcecountSinceeachactivelyplayingAudioSourceconsumesaparticularamountofCPU,thenitstandstoreasonthatwecansaveCPUcyclesforeachredundantAudioSourcethatisplayinginourScene.OneapproachistocontrolourAudioSourcesinsuchawaythatweputahardcaponhowmanyinstancesofanAudioClipcanplaysimultaneouslysothatwedon’tattempttoplaytoomanyofthesamesoundeffectssimultaneously.WecandothisbyhavingamanagementobjecttakecontrolofourAudioSources.ItshouldacceptsoundplaybackrequestsandplaysthefilethroughanyAudioSourcesthataren’talreadybusyplayinganexistingsound.
Themanagementobjectcouldalsothrottletherequestssuchthatthereisalimittohowmanyversionsofthesamesoundeffectcanplay,andhowmanytotalsoundeffectsareplayingatanygiventime.Thiswouldbebestusedon2Dsoundeffectsorsingleinstancesof3Dsoundeffects(whichwouldrequiremovingtheAudioSourcetothecorrectlocationatthemomentofplayback).
AlmosteveryAudioManagementAssetavailableintheUnityAssetStoreimplementsanaudio-throttlingfeatureofsomekind(oftenknownas“audiopooling”),andforgoodreason;it’sthebesttrade-offinminimizingexcessiveaudioplaybackwiththesmallestamountofeffortinpreparingaudioassetstomakeuseofit.Forthisreason,andbecausetheseassetsoftenprovidemanymoresubtleperformance-enhancingfeatures,itisrecommendedtouseapre-existingsolution,ratherthanrollingoutourown,asthescriptingprocesscanbeveryinvolved.
Notethatambient3DsoundsstillneedtobeplacedatspecificlocationsintheScenetomakeuseofthelogarithmicvolumeeffect,whichgivesitthepseudo-3Deffect,sotheaudiomanagementsystemwouldprobablynotbeanidealsolution.Limitingplaybackonambientsoundeffectsisbestachievedbyreducingthetotalnumberofsources.Thebestapproachistoeitherremovesomeofthemorreducethemdowntoonelarger,louderAudioSource.Naturally,thisapproachaffectsthequalityoftheuserexperience,sinceitwouldappearthatthesoundiscomingfromasinglesourceandnotmultiplesources,andsoitshouldbeusedwithcare.
MinimizeAudioClipreferencesEachAudioSourceintheScenewithareferencetoanAudioClipwithPreloadAudioDataenabledwillconsumeacertainamountofmemoryfortheAudioClip(compressed,decompressed,orbuffered,dependingonLoadType)throughouttheentirelengthofthegivenScene.TheexceptiontothisruleisiftwoormoreAudioSourcesreferencethesameAudioClip,inwhichcasenoadditionalmemoryisconsumedasalloftheAudioSourcesarereferencingthesamelocationinmemoryandreadingfromitonanas-needed
http://freepdf-books.com
![Page 181: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/181.jpg)
basis.
AudioClipsareunmanagedresourceswithinUnity,whichmeanstheywillnotbereleasedfrommemorymerelybysettingallreferencestonull.Unityexpectsustoloadandreleasetheseresourcesourselves,creatingandreleasingthemfrommemoryas-needed.Keepingfilesinmemoryforlongperiodsisreasonableforfrequentlyusedsoundeffects,sinceloadingafileintomemoryeverytimeitisrequestedwouldcostussomemeasureofCPUuse.
However,ifwefindthatweareusingtoomuchmemoryfromthesefrequentlyusedsoundeffects,thenwemustmakethedifficultchoiceofeitherreducingtheirqualityorremovingthementirely,tofindmemorysavings.Removingsoundeffectscompletelyisnotnecessarilyabadoption.Wemightbeabletoachieveauniquesoundeffectbyreusingexistingsoundeffectscombinedwithspecialeffectsandfilters.
Ontheotherhand,keepinginfrequentlyusedsoundeffectsinmemoryforthelengthofaScenecanposeasignificantproblem.Wemighthavemanyone-time-onlysoundeffects,suchasdialogclips,wherethereislittlereasontokeeptheminmemoryjustfortheoneuniquemomenttheyareneeded.CreatingAudioSourceswithassignedAudioClips(intheirAudioClipproperty)willgeneratesuchreferences,andcauseexcessmemoryconsumptionevenifweonlyusethemforasinglemomentduringgameplay.
ThesolutionistomakeuseofResources.Load()andResources.UnloadAsset()tokeeptheaudiodatainmemoryonlyforaslongasitisbeingplayed,andthenimmediatelyreleaseitonceitisnolongerneeded.Thefollowingcodesamplewillachievethiseffectinthesimplestmannerpossible(trackingonlyasingleAudioSourceandAudioClip)usingourSingletonAsComponentclass,justtogiveusanideaofwhatsuchasystemmightlooklike:
usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
publicclassAudioSystem:SingletonAsComponent<AudioSystem>{
[SerializeField]AudioSource_source;
AudioClip_loadedResource;
publicstaticAudioSystemInstance{
get{return((AudioSystem)_Instance);}
set{_Instance=value;}
}
publicvoidPlaySound(stringresourceName){
_loadedResource=Resources.Load(resourceName)asAudioClip;
_source.PlayOneShot(_loadedResource);
}
voidUpdate(){
if(!_source.isPlaying&&_loadedResource!=null){
Resources.UnloadAsset(_loadedResource);
http://freepdf-books.com
![Page 182: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/182.jpg)
_loadedResource=null;
}
}
}
ThisclasscanbetestedwiththefollowingComponent,whichloadsasoundfilewhentheAkeyispressed:
publicclassAudioSystemTest:MonoBehaviour{
voidUpdate(){
if(Input.GetKeyDown(KeyCode.A)){
AudioSystem.Instance.PlaySound("TestSound");
}
}
}
TipNotethat,totestthiscode,anaudiofilenamedTestSoundmustbeplacedwithinafoldernamedResourcesinorderforUnitytofinditatruntime.
Usingthisapproachtoplaysoundeffects,weshouldnotethatmemoryforthesoundisonlyallocatedwhenitisplayed,andthenimmediatelyfreedwhenthesoundeffectends.Onceagain,multipleaudiotoolsintheUnityAssetStoreprovidethisfeature,buttheAudioSystemclasscanbeexpandedtohandlemultipleAudioSourcesandAudioClipsfairlyeasilyifwewishtocustomizethesolution.
EnableForcetoMonofor3DsoundsEnablingtheForcetoMonosettingonastereoAudioFilewillmixittogetherwiththechannelsintoasinglechannel,saving50percentofthefile’stotaldiskandmemoryspaceusage.Enablingthisoptionisgenerallynotagoodideaforsome2Dsoundeffectswherethestereoeffectisoftenusedtocreateacertainaudioexperience.Butwecanenablethisoptionforsomegoodspacesavingson3Dsoundeffects,wherebeingastereosourceisgenerallymeaningless,and2Dsoundswherethestereoeffectisn’timportant.
ResampletolowerfrequenciesResamplingimportedaudiofilestolowerfrequencieswillreducethefilesizeandruntimememoryfootprint.ThiscanbeachievedthroughanAudioClip’sSampleRateSettingandSampleRateproperties.Somefilesrequirehighsampleratestosoundreasonable,suchasfileswithhighpitchesandmodernmusicfiles.However,lowersettingscanreducethefile’ssizewithoutmuchnoticeablequalitydegradationinmostcases.22050Hzisacommonvalueforsourcesthatinvolvehumanspeechandclassicalmusic.Somesoundeffectsmaybeabletogetawaywithevenlowerfrequencyvalues.But,eachsoundeffectwillbeaffectedbythissettinginauniqueway,soitwouldbewisetospendsometimedoingsometestingbeforewefinalizeourdecisiononsamplingrate.
ConsiderallencodingformatsIfmemoryandharddiskconsumptionarenotaburdenonourapplication,thentheWAVformatcanbeusedtoreduceCPUcostsatruntime,duetohavingasmalleroverhead
http://freepdf-books.com
![Page 183: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/183.jpg)
requiredtodecodethedataduringeachplayback.Meanwhile,ifwehaveCPUcyclestospare,wecansavespacewithcompressedencoding.
BewareofstreamingStreamingfilesfromdiskshouldberestrictedtolarge,single-instancefilesonly,asitrequiresruntimeharddiskaccess;oneoftheslowestformsofdataaccessavailabletous.Layeredortransitioningmusicclipsmayrunintomajorhiccupsusingthismethod,atwhichpointitwouldbewisetoconsidertheResources.Load()approach.Weshouldalsoavoidstreamingmorethanonefileatatimeasitlikelytoinflictalotofcachemissesonthediskthatinterruptgameplay.
ApplyFiltereffectsthroughMixergroupstoreduceduplicationFiltereffectsareadditionalComponentsthatwecanattachtoanAudioSourcetomodifysoundplayback.EachindividualFiltereffectwillcostsomeamountofbothmemoryandCPU,andattachingduplicatestomanyAudioSourcesinourScenecanresultindireconsequencesifthey’reusedtoofrequently.AbetterapproachistomakeuseofUnity’sAudioMixerutilitytogeneratecommontemplatesthatmultipleAudioSourcescanreferencetominimizetheamountofmemoryoverhead.
TheofficialtutorialonAudioMixerscoversthetopicinexcellentdetail:
https://unity3d.com/learn/tutorials/modules/beginner/5-pre-order-beta/audiomixer-and-audiomixer-groups
Use“WWW.audioClip”responsiblyUnity’sWWWclasscanbeusedtostreamgamecontentinviatheWeb.But,accessingaWWWobject’saudioClippropertywillallocateawholenewAudioClipresourceeachtimeitisinvoked,andsimilarlywithotherWWWresource-acquiringmethods.ThisresourcemustbefreedwiththeResources.UnloadAsset()methodonceitisnolongerrequired.
Discardingthereference(settingittonull)willnotautomaticallyfreetheresource,soitwillcontinuetoconsumememory.Ergo,weshouldonlyobtaintheAudioClipthroughtheaudioClippropertyoncetoobtaintheresourcereference,useonlythatreferencefromthatpointforward,andreleaseitwhenitisnolongerrequired.
ConsiderAudioModulefilesforbackgroundmusicAudioModulefiles,alsoknownasTrackerModules,areanexcellentmeansofsavingasignificantamountofspacewithoutanynoticeablequalityloss.SupportedfileextensionsinUnityare.it,.s3m,.xm,and.mod.UnlikethecommonPCMaudioformats,whicharereadasbitstreamsofdatathatmustbedecodedatruntimetogenerateaspecificsound,TrackerModulescontainlotsofsmall,high-qualityPCMsamplesandorganizetheentiretracksimilartoamusicsheet;definingwhen,where,howloud,withwhatpitch,andwithwhatspecialeffectseachsampleshouldbeplayedwith.Thiscanprovidesignificantsizesavings,whilemaintaininghigh-qualitysampling.So,iftheopportunityisavailabletoustomakeuseofTrackerModuleversionsofourmusicfiles,thenitisworthexploring.
http://freepdf-books.com
![Page 184: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/184.jpg)
http://freepdf-books.com
![Page 185: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/185.jpg)
TexturefilesTheterms“Texture”and“Sprite”oftengetconfusedingamedevelopment,soit’sworthmakingthedistinctionthatinUnity3DaTextureissimplyanimagefile;abiglistofcolordatatellingtheinterpretingprogramwhatcoloreachpixeloftheimageshouldbe.WhereasaSpriteisthe2Dequivalentofamesh,whichjusthappenstobeasinglequadthatrendersflatagainstthecurrentcamera.TherearealsothingscalledSpriteSheets,whicharelargecollectionsofindividualimagescontainedwithinalargerTexturefile,commonlyusedtocontaintheanimationsofa2Dcharacter.ThesefilescanbesplitapartbyUnity’sSpriteBatchtool,toformindividualTexturesfortheanimationframes.
Let’strytoignorealloftheseconfusingnamingconventionoverlaps,andsimplytalkaboutTextures:theimagefileswe’reimportingintoourapplicationthatweregeneratedintoolssuchasAdobePhotoshoporGimp.Atruntime,thesefilesareloadedintomemory,pushedtotheGPU,andrenderedbytheShaderoverthetargetobjectduringagivenDrawCall.
http://freepdf-books.com
![Page 186: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/186.jpg)
CompressionformatsMuchlikeAudiofiles,UnityprovidesuswithavarietyofcompressiontechniquestostoreourTexturefilesmoreefficiently.WhenaTexturefileisimported,thereareseveralsettingsthatwecanmanipulate.ThefirstisTextureType.Thissettingdoesnotaffectthefileitself,butratherhowUnitywillinterpret,manipulate,andcompressitwithinthefinalexecutablewebuild.
WithmostoftheTextureTypeoptions,theonlythreecompressionoptionsUnityexposestousareCompressed,16-bit,andTrueColor.Alternatively,ifwesettheTextureTypetoAdvanced,thenweexposealargernumberofsettings.ThisgivesusfarmorecontrolovertheinterpretationoftheTexturefile.
http://freepdf-books.com
![Page 187: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/187.jpg)
Thiswillbeusefulinformationgoingforwardasthereareseveralperformance-enhancingopportunitiestofindthroughthisparticularviewofaTexturefile,whichwouldnotbevisibleordinarily.
ThenumberofcompressionformatsinAdvancedmodearesignificantlymorebroadandvaried,buttheoptionsremainidenticalbetweenUnity4andUnity5.Someformatsallowalphavalues,whereassomedonot,whichrestrictsourchoicesifwewishtomaintainalphatransparencyinourTexture(orafourthfloatdatavaluefromaTexturebeingusedasaHeightmap!).
SomeformatsalsocostdifferentlevelsofperformanceduringSceneinitializationtodecompressandpushintotheGPU,whichcanvaryenormouslydependingontheplatformwe’retargetingandthechosenformat.AdvancedmodeprovidestheAutomaticCompressedoption,whichtriestopickthebestoptionforthegivenplatformanddevice.Wecanusethisoptionifwe’renotcompletelysureaboutthebestformatforourgame,orwecanspendthetimetodosomeperformance-testingwithdifferentformatstoconfirmthebestchoice(s)forthetargetdevice.
http://freepdf-books.com
![Page 188: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/188.jpg)
NotethatthePreviewWindowatthebottomoftheInspectorViewprovidessomeusefulstatisticstohelpusdeterminehoweffectivelythecurrentlyselectedcompressionmethodisbehaving.
http://freepdf-books.com
![Page 189: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/189.jpg)
TextureperformanceenhancementsLet’sexploresomechangeswecanmaketoourTexturefiles,whichmighthelpimproveperformance,dependingonthesituationandthecontentofthefileswe’reimporting.Ineachcase,we’llexplorethechangesthatneedtobemade,andtheoveralleffecttheyhave,whetherthisresultsinapositiveornegativeimpactonmemoryorCPU,anincreaseordecreaseintheTexturequality,andunderwhatconditionswecanexpecttomakeuseofthesetechniques.
Also,becausetheUnity5PersonalEditionhasmademultiplefeaturesavailabletousthatwerepreviouslyonlyavailableintheProEdition,someusersmaynotbeawareofsomeadditionaltechniquesthatwecanapplytoourTexturestoimproveapplicationperformance.So,wewillalsocoversomeofthesetechniquestowardtheendofthissection.
ReduceTexturefilesizeThelargeragivenTexturefile,themoreGPUmemorybandwidthwillbeconsumedpushingtheTexturewhenitisneeded.Ifthetotalmemorypushedpersecondexceedsthegraphicscard’stotalmemorybandwidth,thenwewillhaveabottleneckastheGPUwaitsforallTexturestobeloadedbeforethenextrenderingpasscanbegin.SmallerTexturesarenaturallyeasiertopushthroughthepipelinethanlargerTextures,soweneedtofindagoodmiddlegroundbetweenhighqualityandperformance.
Acommontesttofindoutifwe’rebottleneckedinmemorybandwidthistosimplyreducetheresolutionofourgame’smostabundantandlargestTexturefilesandrelaunchtheScene.Iftheframeratesuddenlyimproves,thentheapplicationwasmostlikelyboundbytheTexturethroughput.Iftheframeratedoesnotimproveorimprovesverylittle,theneitherwestillhavesomememorybandwidthtomakeuseof,ortherearebottleneckselsewhereintherenderingpipelinepreventingusfromseeinganyfurtherimprovement.
UseMipMapswiselyTherewouldbenopointrenderingsmall,distantobjectssuchasrocksandtreeswithahigh-detailTextureifthere’snowaytheplayerwouldeverbeabletoseethatdetail,oriftheperformancelossistoogreattowarrantaminordetailincrease.MipMapswereinventedasawaytosolvethisproblem(aswellashelpingeliminatealiasingproblemsthatwereplaguingvideogamesataroundthesametime),bypregeneratinglower-resolutionalternativesofthesameTextureandkeepingthemtogetherinthesamememoryspace.Atruntime,theGPUpickstheappropriateMipMapoptionbasedonhowlargethesurfaceappearswithintheperspectiveview(essentiallybasedonthetexel-to-pixelratiowhentheobjectisrendered),andthenpicksanappropriatelyscaledMipMapoftheTexture.
ByenablingtheGenerateMipMapsoption,Unityautomaticallyhandlesthegenerationoftheselower-resolutioncopiesoftheTexture.Thesealternativesaregeneratedusinghigh-qualityresamplingandfilteringmethodswithintheEditor,ratherthanatruntime.
Thefollowingimageshowshowa1024x1024imagewillbeMipMappedintomultiple
http://freepdf-books.com
![Page 190: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/190.jpg)
lower-resolutionduplicates:
ThedownsidetoMipMappingisthatithasanegativeimpactonfilesizeandloadingtimeduetothelargercombinedTexturefilesthatarebeingautomaticallygenerated.ThefinalTexturefilewillbearound33percentlargerwhenMipMappingisenabled.TherearealsosomesituationswheretheMipMappingprocessisawasteofeffort,soweshouldexaminesomeofourTexturefilestoseeifMipMapsarebeingappliedwisely.
MipMappingisonlyusefulifwehaveTexturesthatneedtoberenderedatvaryingdistancesfromthecamera.IfwehaveTexturesthatalwaysrenderedatasimilardistancefromthemaincamera,suchthattheMipMappedalternativesareneverused,thenenablingMipMapsisjustwastingspace.Inthesecases,weshoulddisabletheMipMappingfeaturebydisablingtheGenerateMipMapsoptionfortheTexture.
IfonlyasingleMipMapalternativeisused,thenweshouldconsiderdisablingMipMappinganddownscalingtheresolutionoftheoriginalTexturefile.
AdditionalcandidatesfordisablingtheMipMappingfeatureare:
AlmostanyTexturefileusedina2DgameUserInterface(GUI)TexturesTexturesformeshes,Sprites,andParticleEffects,whichalwaysrendernearthecamera—examplesincludetheplayercharactersthemselves,anyobjectstheyholdorcarry,andanyParticleEffectswhichalwayscenteraroundtheplayer
ManageresolutiondownscalingexternallyUnityputsalotofeffortintomakingthingsaseasytouseaspossibleandprovidesuswiththeabilitytoplacetheprojectfilesfromexternaltoolstoourProjectworkspace,suchasPSDandTIFFfiles,whichareoftenlargeandsplitintomultiplelayeredimages.UnityautomaticallygeneratesaTexturefilefromthefile’scontentsfortherestoftheEngineto
http://freepdf-books.com
![Page 191: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/191.jpg)
makeuseof,whichcanbeveryconvenient,asweonlyneedtomaintainasinglecopyofthefilethroughSourceControlandtheUnitycopyisautomaticallyupdatedwhenanartistmakeschanges.
TheproblemisthatthealiasingintroducedbyUnity’sauto-Texturegenerationandcompressiontechniquesfromthesefilesmaynotbeasrobustandefficientasthetoolsweusetogeneratesuchfiles,suchasAdobePhotoshoporGimp.Unitymaybeintroducingartefactsthroughaliasing,andwemightfindourselvesgettingintothehabitofimportingimagefileswithahigherresolutionthannecessary,justtokeeptheintendedqualitylevel.But,hadwedownscaledtheimagethroughtheexternalapplicationfirst,wemightsuffermuchlessaliasing.Inthesecases,wemayhavebeenabletoachieveanacceptablelevelofqualitywithalowerresolution,whileconsuminglessoveralldiskandmemoryspace.
WecaneitheravoidusingPSDandTIFFfileswithinourUnityprojectasamatterofhabit(storingthemelsewhereandimportingthedownscaledversionintoUnity),orjustperformsomeoccasionaltestingtoensurewe’renotwastingfilesize,memory,andGPUmemorybandwidthusinglargerresolutionfilesthannecessary.Thiscostsussomeconvenienceinprojectfilemanagement,butcanprovidesomesignificantsavingsforsomeTextures,ifwe’rewillingtospendthetimecomparingthedifferentdownscaledversions.
AdjustAnisotropicFilteringlevelsAnisotropicFilteringisafeaturewhichimprovestheimagequalityofTextureswhentheyareviewedatveryshallow(oblique)angles.ThefollowingscreenshotshowstheclassicexampleofpaintedlinesonaroadwithandwithoutAnisotropicFilteringapplied.WithoutAnisotropicFiltering,thepaintedlinesappearblurryanddistortedthefurthertheyareawayfromthecamera,whereastheviewwithAnisotropicFilteringappliedmakestheselinesmorecrispandclear.
ThestrengthofAnisotropicFilteringappliedtotheTexturecanbehand-modifiedonaper-TexturebasiswiththeAnisoLevelsettingaswellasgloballyenabled/disabledusingtheAnisotropicTexturesoptionwithintheQualitySettingsscreen.
MuchlikeMipMapping,thiseffectcanbecostlyandsometimesunnecessary.IfthereareTexturesinourScenewherewearecertainwillneverbeviewedatanobliqueangle(such
http://freepdf-books.com
![Page 192: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/192.jpg)
asdistantbackgroundspritesandparticle-effectTextures),thenwecansafelydisableAnisotropicFilteringforthemtosavesomeruntimeoverhead.WecanalsoconsideradjustingthestrengthoftheAnisotropicFilteringeffectonaper-Texturebasistofindthemagicspotbetweenqualityandperformance.
ConsiderAtlasingAtlasingisthetechniqueofcombininglotsofsmaller,isolatedTexturestogetherintoasingle-largeTexturefileinordertominimizethenumberofMaterials,andhenceDrawCalls,weneedtoapplybyexploitingDynamicBatching.Conceptually,thistechniqueisverysimilartotheapproachesofminimizingMaterialusageyoulearnedinChapter3,TheBenefitsofBatching.
EachuniqueMaterialwouldrequireanadditionalDrawCall,buteachMaterialonlysupportsasingleprimaryTexture(thisexcludesNormalMaps,EmissionMaps,andothersecondaryTextures).BycombiningallTexturesintoasinglecolossalTexture,wecanminimizethenumberofDrawCallsusedtorenderobjectsthatsharethisTexture:
Thebenefitsareclear;reducingDrawCallsresultsinreducingtheCPUworkloadandimprovingtheframerateifourapplicationisCPU-bound(orsimplyfreesupcyclesforothertasks).Therewillbenolossofquality,andmemoryconsumptionwillbeessentially
http://freepdf-books.com
![Page 193: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/193.jpg)
identical.Allwe’redoingisexploitingUnity’sDynamicBatchingsystemtoreduceDrawCalls.NotethatAtlasingdoesnotresultinreducedmemorybandwidthconsumption,sincetheamountofdatabeingpushedisidentical.ItjusthappenstobebundledtogetherinonebiggerTexturefile.
TipAtlasingisonlyanoptionwhenallofthegivenTexturesrequirethesameShader.IfsomeoftheTexturesneeduniquegraphicaleffectsappliedthroughShaders,thentheymusteitherbeisolatedintotheirownMaterialsorAtlasedwithotherTextures,whichusethesameShader.
AtlasingisacommontacticappliedtoUserInterfaceelements,andingamesthatfeaturealotof2Dgraphics.AtlasingbecomespracticallyessentialwhendevelopingmobilegameswithUnity,sinceDrawCallstendtobethemostcommonbottleneckonthoseplatforms.But,wewouldnotwanttogeneratetheseatlasfilesmanually.LifewouldbemuchsimplerifwecouldcontinuetoeditourTexturesindividually,andautomatethetaskofcombiningthemintoalargerfile.
ManyGUI-relatedtoolsintheUnityAssetStoreprovideanautomatedTexture-atlasingfeature,therearesomestandaloneprogramsscatteredacrosstheInternet,whichcanhandlethiswork,andUnityitselfprovidedabuilt-inSpritePackertoolwiththenewUIsysteminversion4.6,whichcanbeeasilycustomizedtopackTexturesindifferentways.
ChecktheUnitydocumentationtodiscovermoreaboutthisusefulfeature,ifinterested:
http://docs.unity3d.com/Manual/SpritePacker.html
Eitherway,itisrecommendedtomakeuseofanexistingsolutionforatlasgenerationinordertoavoidreinventingthewheel.
TipNotethatTexturesmustbedefinedastheSpritetypeinordertoberecognizedandpackedbytheSpritePackertool.
Atlasingdoesnotneedtoapplyto2DgraphicsandUIelementseither.Wecanapplythistechniqueto3Dmeshesifwehappentobecreatingalotoflow-resolutionTextures.3DgamesthatfeaturesimpleTextureresolutions,oraflat-shadedlow-polyartstyle,areidealcandidatesforAtlasinginthisway.
However,becauseDynamicBatchingonlyaffectsnon-animatedmeshes(thatis,MeshRenderers,andnotSkinnedMeshRenderers),thereisnoreasontocombineTexturefilesforanimatedcharactersintoanatlas.Sincetheyareanimated,theGPUneedstomultiplyeachobject’sbonesbythetransformofthecurrentanimationstate.Thismeansauniquecalculationisneededforeachcharacter,andtheywillresultinanextraDrawCallregardlessofanyattemptswemaketohavethemshareMaterials.
Asaresult,combiningTexturesforanimatedcharactersshouldonlybedoneasamatterofconvenienceandspace-saving;forexample,inaflat-shadedlow-polyartstylegame,whereeverythinghappenstouseacommoncolorpalette,wecanmakesomesignificant
http://freepdf-books.com
![Page 194: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/194.jpg)
spacesavingsbyusingasingleTexturefortheentiregameworld,objects,andcharacters.
ThedisadvantagesofAtlasingaremostlyintermsofdevelopmenttimeandworkflowcosts.ItrequiresalotofefforttooverhaulanexistingprojecttomakeuseofAtlasing,whichcanbealotofworkjusttofigureoutifitisworththeeffortornot.Inaddition,weneedtobewareofgeneratingatlasfiles,whicharetoolargeforthetargetplatform.
Somedevices(specificallymobiledevices)havearelativelylowlimitonthesizeofTexturesthatcanbepulledintothelowestmemorycacheoftheGPU.Iftheatlasistoolarge,thenitmustbebrokenupintosmallerTextures,tofitthetargetmemoryspace.IftherendererhappenstoneedTexturesfromdifferentpiecesoftheatlaseveryotherDrawCall,thennotonlywillweinflictalotofcachemisses,butalsowemightfindthatwechokethememorybandwidthasTexturesareconstantlypulledfromVRAMandthelower-levelcache.
WewouldprobablynothavethisproblemiftheatlaswasleftasindividualTextures.ThesameTextureswappingwouldoccur,butwillresultinmuchsmallerfilesbeingswappedatthecostofadditionalDrawCalls.OurbestoptionsatthisstagewouldbetolowertheatlasresolutionorgeneratemultiplesmalleratlasestohavebettercontroloverhowtheywillbeDynamicallyBatched.
So,Atlasingisclearlynotaperfectsolution.Ifitisnotclearwhetheritwouldresultinaperformancebenefit,thenweshouldbecarefulnottowastetoomuchtimeonimplementation.
Ingeneral,weshouldattempttoapplyAtlasingtomid-range/high-qualityMobilegamesrightfromthestartoftheproject,keepingwithintheTexturelimitforthetargetplatform,makingper-platformandper-deviceadjustmentsasnecessary.Ontheotherhand,thesimplestMobilegameswillmostlikelyfunctionwithoutneedinganyAtlasing.
Meanwhile,weshouldconsiderapplyingAtlasingtohigh-qualityDesktopgames,onlyifourDrawCallcountexceedsreasonablehardwareexpectations,sincewewillwantmanyofourTexturestomaintainhighresolutionsformaximumquality.Low-qualityDesktopgamescanprobablyaffordtoavoidAtlasing,sinceDrawCallsareunlikelytobethebiggestbottleneck.
Ofcourse,nomatterwhattheproductis,ifwe’reeverCPU-boundbyDrawCallsandwe’vealreadyexhaustedmanyofthealternativetechniques,thenAtlasingwouldbethenextbesttechniquetoimplement,asitcanresultinsomeimpressiveDrawCallsavingswhenusedproperly.
Adjustcompressionratesfornon-squareTexturesItisnotrecommendtoimportnon-squareand/ornon-power-of-2Texturesintoourapplication,becauseGPUsoftenrequirethepushedTexturetobesquare,andapower-of-2sizeresultsinunnecessaryworkloaddealingwithmalformedTexturesizes.UnitywillautomaticallyadjusttheTextureandaddadditionalemptyspaceinordertofittheformfactorthattheGPUexpects,whichwillresultinadditionalmemorybandwidthcosts,pushingwhatisessentiallyuselessdatatotheGPU.
http://freepdf-books.com
![Page 195: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/195.jpg)
So,thefirstrecommendationistoavoidnon-squareand/ornon-power-of-2Texturesaltogether.Iftheimagecanbeplacedwithinasquare,power-of-2Texture,anddoesnotresultintoomuchqualitydegradationduetosqueezing/stretching,thenweshouldapplythosechangesjusttokeeptheCPUandGPUhappy.
However,ifwestillwanttousenon-squareTextures,thereisatrickwecanapplytoachievehigherqualitywithoutcostinganyadditionalspace.Sincethewaynon-squareTexturesarepackedbycompressionalgorithms,wecanoftenincreasethebit-rate(andhencequality)ofthechosencompressionformatforanon-squareTextureandstillachieveanidenticalimportedfilesizeandruntimeoverheadcost.ThisonlycostsusthetimeittakestofindtheseTexturesandtestavarietyofcompressionalgorithmstofindthehighestqualityversion.
SparseTexturesSparseTextures,alsoknownasMega-TexturesorTiled-Textures,provideawayofeffectivelystreamingTexturedatafromdiskatruntime.Relativelyspeaking,iftheCPUperformsoperationsintheorderofseconds,thenthediskwilloperateintheorderofdays.Socommonadviceisthatharddiskaccessduringgameplayshouldbeavoidedatallcosts,sinceanysuchtechniquerisksinflictingmorediskaccessthanavailable,causingourapplicationtogrindtoahalt.
But,SparseTexturingbreaksthisruleandofferssomeinterestingperformancesavingtechniques.TheaimofSparseTexturingistocombinemanyTexturesintoanenormousTexturefile,whichwouldbefartoolargetoloadintographicsmemoryasasingleTexturefile.ThisissimilartotheconceptofAtlasing,exceptthefilecontainingtheTexturesisincrediblylarge(forexample,32,768x32,768resolution)andcontainsconsiderabledetail(32bitsperpixel).Theideaistosavelargeamountsofruntimememoryandmemorybandwidthbyhand-pickingsmallsubsectionsoftheTexturedynamically,andpullthemfromthediskjustbeforetheyareneededinthegame.Themaincostofthistechniqueisthefilesizerequirement(theexampleresolutionfilewouldconsume4GBofdiskspace!).OthercostsforthistechniquecanbeovercomewithagreatdealofScenepreparationwork.
ThegameworldneedstobecreatedinsuchawaythatitminimizestheamountofTextureswappingtakingplace.Inordertoavoidjarring,“texturepopping”problems,Texturesubsectionsmustbepulledfromadiskwithjustenoughtimetosparethattheplayerdoesnotnotice.ThistakesplaceinthedesignoftheTexturefileitself,bykeepingcommonelementsforagivenSceneinthesamegeneralareaoftheTexture,andthedesignoftheScene,bytriggeringnewTexturesubsectionloadingatkeymomentsduringgameplay.Ifitishandledwithgreatcareandattentiontodetail,thenSparseTexturingcanresultinsomeimpressiveScenequalityandequallyimpressivememorysavings.
SparseTexturingwaspreviouslyaProEdition-onlyfeatureinUnity4,butwasmadeavailablewiththePersonalEditionofUnity5.SparseTexturingrequiresspecializedhardwareandplatformsupport,however,sothisoptionisnotavailabletoallgames.Itisahighlyspecializedanduncommontechniquewithinthegamingindustry,whichisreflectedinthelackofdocumentation.TheUnitydocumentationdoesnotprovidemuch
http://freepdf-books.com
![Page 196: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/196.jpg)
informationonSparseTexturing,butitdoesprovideanexampleSceneshowingtheeffectatwork.ItcanbefoundatthefollowingURL:http://docs.unity3d.com/Manual/SparseTextures.html.
ForUnitydeveloperswhoconsiderthemselvesadvancedenoughtofigureitoutontheirown,itmightbeworthtakingthetimetoperformsomeresearchtoseeifSparseTexturingisrightfortheirprojectandwhethertheyarewillingtomaketheappropriateScenechangesnecessarytogaintheperformancebenefitsthatthisfeaturepresents.
ProceduralMaterialsAlsoknownasSubstances,ProceduralMaterialsareameansofprocedurallygeneratingTexturesatruntimebycombiningsmall,high-qualityTexturesampleswithcustommathematicalformulas.ThegoalofProceduralMaterialsistogreatlyminimizetheapplicationfootprintatthecostofadditionalruntimememoryandCPUprocessingduringinitialization.LikeSparseTexturing,thisfeaturewaspreviouslyonlyavailableintheProEditionofUnity4andisnowavailableinUnity5.
ThisgivesmanyusersanopportunitytoviewtheirMaterialsfromadifferentperspective,asProceduralMaterialsareamoremodernapproachtotheirgames.Texturefilesareoftenthebiggestdiskspaceconsumerofagameproject,andit’sfairlycommonknowledgethatdownloadtimeshaveatremendousnegativeimpactonthecompleteddownloadrateandjustgettingpeopletotryourgame(evenifit’sfree!).ProceduralMaterialsofferustheabilitytosacrificesomeinitializationandruntimeprocessingpowerformuchfasterdownloads.ThisisveryimportantforanupcominggenerationofMobilegamesthataretryingtocompeteviagraphicalfidelity.
TheUnitydocumentationonProceduralMaterialsisfarmoreextensivethanforSparseTexturing,soitisrecommendedtoworkthroughthedocumentationforaclearerpictureofhowSubstancesworkandhowtheycanprovideuswithperformancebenefits:
http://docs.unity3d.com/Manual/ProceduralMaterials.html
http://freepdf-books.com
![Page 197: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/197.jpg)
http://freepdf-books.com
![Page 198: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/198.jpg)
MeshandanimationfilesFinally,let’scovermeshandanimationfiles.Thesefiletypesareessentiallylargearraysofvertexandskinnedbonedata,andthereareavarietyoftechniqueswecanapplytominimizefilesize,whilekeepingasimilar,ifnotidentical,appearance.Therearealsosometimeswaystolowerthecostofrenderinglargegroupsoftheseobjectsthroughbatchingtechniques.Let’slookintoaseriesofperformance-enhancingtechniqueswecanapplytosuchfiles.
http://freepdf-books.com
![Page 199: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/199.jpg)
ReducingpolygoncountThisisthemostobviouswaytogainperformance,butweshouldneverdisregardit.Infact,sincewecannotbatchobjectsusingSkinnedMeshRenderers,it’soneoftheonlygoodwaysofreducingCPUandGPUruntimeoverheadforanimatedobjects.
Reducingthepolygoncountissimple,straightforward,andprovidesbothCPUandmemorycostsavingsforthetimerequiredforartiststocleanupthemesh.Muchofanobject’sdetailisprovidedalmostentirelybydetailedTexturingandcomplexShadinginthisdayandage,sowecanoftengetawaywithstrippingawayalotofverticesonmodernmeshesandmostuserswouldbeunabletotellthedifference.
TweakingMeshCompressionUnityoffersfourdifferentMeshCompressionsettingsforimportedmeshfiles:Off,Low,Medium,andHigh.IncreasingthissettingwillstripawaymoreandmorepartsofthemeshthatUnitythinksaren’tneededinordertomakeagoodestimateofthesamemeshwiththeaimofreducingoverallfilesize.Thisisessentiallyanautomatedversionofhavinganartistmanuallyreducingthepolygoncount.
However,automatedmeshoptimizationisaverydifficultproblemtosolvemathematicallyandeventhebestalgorithmstendtogeneratealotofartefactsandirregularities.DifferentlevelsofMeshCompressioncanbeattemptedasaquicksolutiontoreducingpolygoncount,butitwillprobablynevercomparetohavinganartistmakeappropriatepolycountreductionsbyhand.
TipThese3Dtoolsoftenprovidetheirownbuilt-inwaysofautomatedmeshoptimization,andshouldbetestedasameansofoptimizingthemeshbeforeimportingthemintoUnity.
UseRead-WriteEnabledappropriatelyTheRead-WriteEnabledflagallowschangestobemadetothemeshatruntimeeitherviaScriptingorautomaticallybyUnityduringruntime.Internally,thismeansitwillkeeptheoriginalmeshdatainmemoryuntilwewanttoduplicateitandmakechangesdynamically.DisablingthisoptionwillallowUnitytodiscardtheoriginalmeshdatafrommemoryonceithasdeterminedthefinalmeshtouse.
Ifweonlyeveruseauniformlyscaledversionofameshthroughouttheentiregame,thendisablingthisoptionwillsaveruntimememorysincewewillnolongerneedtheoriginalmeshdatatomakefurtherrescaledduplicatesofthemesh(incidentally,thisishowUnityorganizesobjectsbyscalefactorwhenitcomestoDynamicBatching).Unitycan,therefore,discardthisunwanteddataearlysincewewillneverneeditagainuntilthenexttimetheapplicationislaunched.
However,ifthemeshoftenreappearsatruntimewithdifferentscales,thenUnityneedstokeepthisdatainmemorysothatitcanrecalculateanewmeshmorequickly,andsotheRead-WriteEnabledflagshouldbeenabled.DisablingitwillrequireUnitytonotonlyreloadthemeshdata,butalsomaketherescaledduplicateatthesametime,causinga
http://freepdf-books.com
![Page 200: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/200.jpg)
potentialperformancehiccup.
Unitytriestodetectthecorrectbehaviorforthissettingatinitializationtime,butwhenmeshesareinstantiatedandscaledinadynamicfashionatruntime,thenwemustforcetheissuebyenablingthissetting.Thiswillimproveinstantiationspeedoftheobjects,butcostsomememoryoverheadsincetheoriginalmeshdataiskeptarounduntilit’sneeded.
TipNotethatthisalsoapplieswhenusingtheGenerateCollidersoption.
http://freepdf-books.com
![Page 201: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/201.jpg)
Import/calculateonlywhat’sneededThisappearstobeanotherobvioussuggestion,butmeshesdonotonlycontainvertexpositionaldata.TherecouldbeunnecessaryNormalsandTangentsinourmeshthattheShaderswon’tneed,orwecouldbeautogeneratingNormalandTangentcoordinatesthatwewon’tuse,particularlywhentheSmoothingAngleisverylow.Inthesecases,eachvertexrequiresmultiplenormalvectorstocreatethefaceted,flat-shadingstylethatresultsfromit.
Double-checkyourmeshimportsettingsandexaminetheresultantfilesizeandin-gameappearance,bytinkeringwiththeimportsettingstoseeifyoucanmakeanysavingsbystrippingawayunwantedandunnecessarydata.
http://freepdf-books.com
![Page 202: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/202.jpg)
ConsiderbakedanimationsThiswilldependonthe3Driggingandanimationtoolthatweareusing,andtheoverallvertexcountofourmesh;insomecasesbakinganimationscanresultinmuchsmallerfilesizesandmemoryoverheadthanblended/skinnedanimations.Bakedanimationsworkbystoringakeyframedpositionforeachvertexforeachframethatwassampled,andifthemesh’spolygoncountislowenough,thenwemayseesomesignificantsavingsthroughthissimplechange.
Inaddition,howoftenthebakedsampleistakencanusuallybecustomizedbytheexportingapplication.Differentsampleratesshouldbetestedtofindagoodvaluewherethekeymomentsoftheanimationstillshine-throughwhatisessentiallyasimplifiedestimate.
http://freepdf-books.com
![Page 203: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/203.jpg)
LetUnityoptimizemeshesTheOptimizeMeshesoptioninamesh’simportsettingswillreorganizethevertexdataforquickerreadability,andsometimesregeneratethelow-levelrenderingstyle(downtothelevelofpointsversustrisversusstrips)tooptimizetherenderingspeedofthemesh.Simplyput,thisoptionshouldbeenabledinalmostallcases,asthereisverylittlereasontonotletUnitymaketheseadjustmentsforus,unlesswe’vedonesomeprofilingandwe’repositivethatit’ssomehowgeneratingbottlenecks.
Ifwe’regeneratingmeshesprocedurally,thenwecantellUnitytoinvokethisprocessusingtheOptimize()methodonaMeshFilterComponent.Thisprocesscantakesometime,soitshouldbeusedduringinitializationorotherconvenientstoppingpoint.
http://freepdf-books.com
![Page 204: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/204.jpg)
CombinemeshesCombiningmeshesintoalarge,singlemeshcanbeconvenienttoreduceDrawCallsifthemeshesaretoolargeforDynamicBatchinganddon’tplaywellwithotherStaticallyBatchedgroups.ThisisessentiallytheequivalentofStaticBatching,butperformedmanually,sosometimesit’swastedeffortifStaticBatchingcouldtakecareoftheprocessforus.
However,ifwe’reusingtheUnity4FreeEditionwhereStaticBatchingisnotavailabletousorwewishthemeshtomovearoundtheScene,thenthisisagoodoptiontominimizeourDrawCalls.BewarethatitcomeswiththesameriskasStaticBatching.IfanysinglevertexofthemeshisvisibleintheScene,thentheentireobjectwillberenderedtogetherasonewhole.Thiscanleadtoalotofwastedprocessingifthemeshisonlypartiallyvisiblemostofthetime.
ThistechniquealsocomeswiththedrawbackthatitgeneratesawholenewmeshassetfilethatwemustdepositintoourScene,whichmeansanychangeswemaketotheoriginalmesheswillnotbereflectedinthecombinedone.Thisresultsinalotoftediousworkflowefforteverytimechangesneedtobemade,soifStaticBatchingisanoption,itshouldbeusedinstead.
Thereareseveraltoolsavailableonline,whichcancombinemeshfilestogetherforusinUnity.TheyareonlyanAssetStoresearch,orGooglesearchaway.
http://freepdf-books.com
![Page 205: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/205.jpg)
http://freepdf-books.com
![Page 206: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/206.jpg)
SummaryTherearemanydifferentopportunitiesthatwecanexploretoachieveperformancegainsforourapplicationjustbytinkeringwithourimportedassets.Or,fromanotherperspective,thereareplentyofwaystoruinourapplication’sperformancethroughassetmismanagement.
Almosteverysingleopportunityisatrade-offbetweenoneperformancemetricorworkflowtaskandanother.So,wemustremainvigilantandonlypicktherighttechniquesintherightprojectsfortherightreasons.Theworstthingwecandoisimplementsuchchangeswithoutunderstandingtheimpact.It’sexcitingtostumbleonsomebigperformanceenhancingsuggestionoutinthebig,wideworld,butunlessweunderstandhowitworks,andtheresultingcosts,wecaninvitefurtherperformanceproblemsandbottleneckswithoutrealizingit,costingusmoretimeandeffortdowntheroad.
Thisconcludesourexplorationofimprovingperformancethroughartassetmanipulation.Inthenextchapter,wewillbeinvestigatingtheBox2DandPhysXphysicssolutionsprovidedbyUnity,thechangeswecanmaketoourscriptcode,Scene,andprojecttomakethesecomponentsprocessourdatafaster;andbehaviortoavoidthatmightcausethemtostumble.
http://freepdf-books.com
![Page 207: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/207.jpg)
http://freepdf-books.com
![Page 208: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/208.jpg)
Chapter5.FasterPhysicsEachoftheperformance-enhancingsuggestionswe’veexploredthusfarhavebeenprimarilycenteredonreducingsystemrequirementsandavoidingframerateissues.Butatitsmostfundamentallevel,seekingpeakperformancemeansimprovingtheuserexperience.Thisisbecauseeveryframeratehiccup,everycrash,andeverysystemrequirementthatistoocostlyforagivenmarketultimatelydetractsfromthequalityoftheproduct,andleavesuswonderingwhetherweshouldhavetriedhardertotweaksettingsandfixmorebugsbeforerelease.
TherearecertainlyopportunitiestomanipulatePhysicsEnginebehaviorthatimprovealloftheaforementionedissues,butPhysicsEnginesalsofallintoauniquecategoryofhavingadirectimpactongameplayquality.Ifimportantgameplaycollisioneventsgetmissed(suchastheplayerfallingthroughthefloor),orthegamefreezeswhileitcalculatesacomplexsituation,thenthesehaveasignificantimpactongameplayquality.Thisoftenresultsinpullingtheplayeroutoftheexperience,andit’sacoin-tosswhethertheuserfindsitinconvenient,obnoxious,orhilarious.UnlessourgameisspecificallytargetingtheComedyPhysicsgenre(which,incidentally,hasgrowninpopularityinrecentyearswithgameslikeQWOPandGoatSimulator),thesearesituationsweshouldstrivetoavoid.
Forsomegames,thePhysicsEngineisusedtohandleasignificantnumberoftasksduringgameplay,fromcollisiondetectionwithotherobjectsandinvisibletriggerboxestoraycastingandgatheringalistofobjectsinagivenregion.Forexample,itisessentialinplatformerandactiongamestotunethephysicsproperly;howtheplayercharacterreactstoinputandhowtheworldreactstotheplayercharactercanbetwoofthemostimportantaspectsofwhatmakesthegamefeelresponsiveandfun.Othergamesmayonlyusephysicsforsimplegameplayevents,interestingspectacles,andothereye-candy,butthemoreefficientlythePhysicsSystemisused,themoreofaspectaclethatcanbecreated.
Therefore,inthischapter,wewillnotonlycoverwaystoreduceCPUspikes,overhead,andmemoryconsumptionthroughUnity’sPhysicsSystem,butalsoincludewaystoalterphysicsbehaviorwiththeaimofimprovinggameplayquality.Inaddition,becauseUnity’sPhysicsSystemsarea“black-box”,inthatwecan’tdomuchinternaldebugging,itcanbeverytrickytofigureoutexactlywhen,where,andwhycertainphysicsglitchesareplaguingourproject,andwhatweshoulddotopreventthem.Asaresult,themethodscoveredinthischapterwillincludeseveralsuggestionsonhowtoreduceinstabilityandproblematicphysicssituations.
http://freepdf-books.com
![Page 209: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/209.jpg)
PhysicsEngineinternalsUnitytechnicallyfeaturestwodifferentPhysicsEngines:NvidiaPhysXfor3DphysicsandtheOpenSourceprojectBox2Dfor2Dphysics.However,theirimplementationishighlyabstracted,andfromtheperspectiveoftheUnityAPI,bothenginesoperateinanearlyidenticalfashion.
Ineithercase,themoreweunderstandaboutUnity’sPhysicsSystem,themoresensewecanmakeofpossibleperformanceenhancements.So,firstwe’llcoversometheoryaboutUnity’sPhysicsEngines.
http://freepdf-books.com
![Page 210: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/210.jpg)
PhysicsandtimePhysicsEnginesgenerallyoperateundertheassumptionthattimeisiteratinginfixedvaluesoftime,andbothofUnity’sPhysicsEnginesoperateinthismanner.ThePhysicsEnginewillonlycalculateusingveryspecificvaluesoftime,independentofhowmuchtimeittooktorenderthepreviousframe.ThisisknownastheFixedUpdateTimestep,anditissettoavalueof20millisecondsbydefault,or50updatespersecond.
NoteItcanbeverydifficulttogenerateconsistentresultsforcollisionsandforcesbetweentwodifferentcomputersifaPhysicsEngineusesavariabletimestep.Suchenginestendtogenerateinconsistentresultsbetweenmultiplayerclients,andduringrecordedreplays.
Iftoomuchtimehaspassedbetweenframes(alowframerate),thenthePhysicsSystemmayupdatemultipletimesbeforerenderingbeginsagain.Conversely,ifnotenoughtimehaspassedsincethepreviousrender(ahighframerate),thenthephysicsupdatemaybeskippeduntilafterthenextrendercall.
TheFixedUpdate()methodrepresentsthemomentwhenthePhysicsSystemperformssimulationtimestepupdates.ItisoneofseveralimportantUnitycallbackswecandefineinaMonoBehaviourscriptand,ingeneral,FixedUpdate()isusedtodefineframe-rate-independentbehavior.Thiscallbackisusuallyusedforcalculationssuchasartificialintelligence(whicharealsoeasiertoworkwithifweassumeafixedupdatefrequency),butthisisalsowhereweshouldmodifyRigidbodyobjectsduringgameplay.
ThefollowingdiagramshowsanimportantsnippetoftheUnityOrderofExecutiondiagram:
Note
http://freepdf-books.com
![Page 211: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/211.jpg)
ThefullOrderofExecutiondiagramcanbefoundat:http://docs.unity3d.com/Manual/ExecutionOrder.html.
TheFixedUpdateloopAswecansee,FixedUpdate()isinvokedjustpriortothePhysicsSystemperformingitsownupdateandthetwoareinextricablylinked.TheprocessbeginswithdeterminingwhetherenoughtimehaspassedtobeginthenextFixedUpdate.TheoutcomewillvarydependingonhowmuchtimehaspassedsincethelastFixedUpdate.
Ifenoughtimehaspassed,thentheFixedUpdate()methodisinvokedglobally,andanyCoroutinestiedtoFixedUpdates(thatis,yieldstoWaitForFixedUpdate())arehandledimmediatelyafterward,followedbyphysicsupdatesandtrigger/collidercallbacks.
Iflessthan20mshasgonebysincethelastFixedUpdate,thenthecurrentFixedUpdateisskipped.Atthispoint,input,gameplaylogic,andrenderingmusttakeplaceandcompletebeforeUnityperformsthenextFixedUpdatecheck,andsoon,asthisprocessrepeatsitselfduringruntime.ThisdesigngivesbothFixedUpdatesandthePhysicsSystemahigherpriorityoverrendering,butforcesthephysicssimulationintoafixedframerate.
NoteInordertoensuresmoothmotionduringframeswherephysicsupdatesareskipped,somePhysicsEngines(includingUnity’s)interpolatethestatebetweenthepreviousstateandthecurrentstatebasedonhowmuchtimeremainsuntilthenextFixedUpdate.
Thisensuresthat,graphically,objectsappeartomovesmoothlyduringhighframerates,eventhoughtheyareonlybeingupdatedevery20ms.
MaximumAllowedTimestepItisimportanttonotethatifalotoftimehaspassedsincethelastFixedUpdate(forexample,thegamefrozemomentarily),thenphysicsandFixedUpdateswillcontinuetobecalculateduntiltheyhave“caughtup”withthecurrenttime.Forexample,ifthepreviousframetook100mstorender(forexample,asuddenperformancespikedroppingthegameto10FPS),thenthePhysicsSystemwillneedtoupdatefivetimes.TheFixedUpdate()methodwillthereforebecalledfivetimesbeforeUpdate()canbecalledagainduetothedefaultFixedUpdateTimestepof20ms.If,forwhateverreason,theprocessingofthesefiveupdatesconsumes20msormore,thenitwillneedtoinvokeasixthupdate!
Consequently,it’spossibleduringmomentsofheavyphysicsactivitythatthePhysicsEnginecantakemorethan20mstocompleteaphysicsupdate,whichitselftakesanother20ms,andsoon,suchthatitisneverabletoescapeandallowanotherframetorender(thisisoftenknownasthe“spiralofdeath”).TopreventthePhysicsEnginefromlockingupourgameduringthesemoments,thereisamaximumamountoftimethatthePhysicsEngineisallowedtoprocessbetweeneachrender.ThisthresholdiscalledtheMaximumAllowedTimestep,andifthecurrentFixedUpdateistakinglongertoprocessthanthisvalue,thenitwillsimplystopandforgofurtherprocessinguntiltheendofthenextrender.
http://freepdf-books.com
![Page 212: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/212.jpg)
Thisdesignallowstherenderingsystemtoatleastrenderthecurrentstate,andallowforgameplaylogictomakesomedecisionsduringraremomentswherephysicscalculationhasgoneballistic(punintended).
PhysicsupdatesandruntimechangesWhenthePhysicsSystemprocessesthenexttimestep,itmustmoveanyactiveRigidbodyobjects,detectanycollision,andinvokethecollisioncallbacksonthecorrespondingobjects.It’sforexactlythisreasonthattheUnitydocumentationexplicitlywarnsustoonlymakechangestoRigidbodyobjectsinFixedUpdate()andotherphysicscallbacks.Thesemethodsaretightly-coupledwiththeupdatefrequencyofthePhysicsEngine,asopposedtootherpartsofthegameloop,suchasUpdate().
ThismeansthatcallbackssuchasOnTriggerEnter()aresafeplacestomakeRigidbodychanges,whilemethodssuchasUpdate()andtime-basedCoroutinesarenot.NotfollowingthisadvicecouldcauseunexpectedphysicsbehaviorasmultiplechangesaremadetothesameobjectbeforethePhysicsSystemisgivenachancetocatchandprocessallofthem,resultinginsomeespeciallyconfusinggameplaybugs.
ItlogicallyfollowsthatthemoretimewespendinanygivenFixedUpdateiteration,thelesstimewehaveforthenextgameplayandrenderingpass.Mostofthetimethisresultsinminor,unnoticeablebackgroundprocessingtasks,asthePhysicsEnginebarelyhasanyworktodo,andFixedUpdate()callbackshavealotoftimetocompletetheirwork.
But,insomegames,thePhysicsEnginecouldbeperformingalotofcalculationsduringeachandeveryFixedUpdate.Thiskindofbottleneckinginphysicsprocessingtimewillaffectourrenderingframerate,causingittoplummetasthePhysicsSystemistaskedwithgreaterandgreaterworkloads.Essentially,therenderingsystemwillproceedasnormal,butwheneverit’stimeforaFixedUpdate,thenitwouldbegivenverylittletimetogeneratethecurrentdisplay,causingasuddenstutter.ThisisinadditiontothevisualeffectofthePhysicsSystemstoppingearlybecauseithittheMaximumAllowedTimestep.Allofthistogetherwillgenerateapooruserexperience.
Hence,tokeepasmoothandconsistentframerate,thegoalistofreeupasmuchtimeaswecanforrenderingbyminimizingtheamountoftimethePhysicsSystemtakestoprocessanygiventimestep.Thisappliesinboththebest-casescenario(nothingmoving)andworst-casescenario(everythingsmashingintoeverythingelseatonce).Thereareanumberoftime-relatedfeaturesandvalueswecantweakwithinthePhysicsSystemtoavoidperformancepitfallssuchasthese.
http://freepdf-books.com
![Page 213: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/213.jpg)
StaticandDynamicCollidersThereisarathersignificantnamespaceconflictwiththeterm“static”inUnity.WehavealreadycoveredstaticGameObjects,thevariousStaticsubflags,theStaticBatchingfeature,andthenthere’stheuseofstaticvariablesandclassesinC#.Meanwhile,Unity’soriginalphysicsimplementationfor3DobjectshasitsownconceptofStaticColliders.Later,when2Dphysicswasimplemented,itkeptthesameconceptofStaticColliderstokeepthingsconsistentbetweenthem.
So,withthisinminditisveryimportanttorememberthatStaticCollidersarenotobjectswiththeStaticflagenabled,sincethoseflagsareaUnityEngineconcept.StaticCollidersaresimplycollidersthatdonothaveanattachedRigidbody.Meanwhile,colliderswithanattachedRigidbodyarecalledDynamicColliders.
ThePhysicsSystemcombinesStaticCollidersintoadifferent,optimizeddatastructure,whichhelpstosimplifyfutureprocessingtasks.Theseobjectswillnotreacttoimpulsesappliedbyobjectscollidingwiththem,butwillpreventotherobjectsfrommovingthroughthem.ThismakesStaticCollidersidealforworldbarriersandotherobstaclesthatmustnotmove.
http://freepdf-books.com
![Page 214: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/214.jpg)
CollisiondetectionTherearethreesettingsforcollisiondetectioninUnity:Discrete,Continuous,andContinuousDynamic.TheDiscretesettingeffectivelyteleportsobjectsasmalldistanceeverytimestepbasedontheirvelocityandhowmuchtimehaspassed.Afteralltheobjectshavebeenmoved,itthenperformsabounding-volumecheckforanyoverlaps,treatsthemascollisions,andresolvesthembasedontheirphysicalpropertiesandhowtheyoverlap.Thismethodriskscollisionsbeingmissedifsmallobjectsaremovingtooquickly.
Bothofthecontinuouscollisiondetectionmethodsworkbyinterpolatingobjectsfromtheirstartingandendingpositionsforthecurrenttimestepandcheckingforanycollisionsalongtheway.Thisreducestheriskofmissedcollisionsandgeneratesamoreaccuratesimulation,attheexpenseofsignificantlygreaterCPUoverheadcomparedtotheDiscretesetting.
TheContinuoussettingonlyenablescontinuouscollisiondetectionbetweenthegivencolliderandStaticColliders(recallthatStaticCollidersaresimplycolliderswithoutanyattachedRigidbody).ThesameobjectswillbesimultaneouslytreatedasusingtheDiscretesettingwhenitcomestocollisiondetectionwithotherdynamicobjects(thosewithanattachedRigidbody).Meanwhile,theContinuousDynamicsettingisslightlydifferentasitenablesthesamecontinuouscollisiondetection,butdoessobetweenthegivencolliderandallothercolliders,bothStaticandDynamic.
Thefollowingscreenshotshowshowthediscreteandcontinuouscollisiondetectionmethodswouldworkforapairofsmall,fast-movingobjects:
Thisisanextremeexampleforthesakeofillustration.Inthediscretecase,wecanseethattheobjectsare“teleporting”adistancearoundfourtimestheirownsizeinasingletimestep,whichwouldtypicallyonlyhappenwithverysmallobjectswithveryhighvelocities,andishenceveryrareifourgameisrunningoptimally.Inmostcases,thedistancestheobjectstravelinasingle20mstimesteparemuchsmallerrelativetothesizeoftheobject,andsothecollisioniseasilydetected.
http://freepdf-books.com
![Page 215: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/215.jpg)
CollidertypesTherearefivedifferenttypesof3DCollidersinUnity5.Inorderofthelowestperformancecosttothegreatest,theyare:Sphere,Capsule,Cylinder,Box,andMeshColliders.Thefirstfourcollidertypesareconsideredprimitivesandmaintainconsistentshapes,althoughtheycangenerallybescaledindifferentdirectionstomeetcertainneeds.MeanwhileMeshColliderscanbecustomizedtoaparticularshapedependingontheassignedmesh.
NoteTherearealsothreemain2DColliders:Circle,Box,andPolygon,whicharefunctionallysimilartoSphere,Box,andMeshCollidersin3D.Allofthefollowinginformationisessentiallytransferabletotheequivalent2Dshape.
Inaddition,therearetwovarietiesofMeshCollider:convexandconcave.Thedifferenceisthataconcaveshapefeaturesatleastoneinternalangle(ananglebetweentwoedgesinsidetheshape)ofgreaterthan180degrees.Toillustratethis,thefollowingscreenshotshowsthedistinguishingdifferencebetweenconvexandconcaveshapes:
TipAneasywaytorememberthedifferencebetweenconvexandconcaveshapesisthataconcaveshapehasatleastone“cave”withinit.
BothMeshCollidertypesusethesameComponent(aMeshCollider!),andwhichtypeofMeshCollidergetsgeneratedistoggledusingtheConvexcheckbox.EnablingthisoptionwillallowtheobjecttocollidewithotherMeshCollidersmarkedasConvex,aswellasprimitiveshapes(Spheres,Boxes,andsoon.).Inaddition,iftheConvexcheckboxisenabledforaMeshColliderwithaconcaveshape,thenthePhysicsSystemwillautomaticallysimplifytheconcaveshape,generatingacolliderwiththenearestconvexshapeitcan.Intheprecedingexample,ifweimporttheconcavemeshontheright,and
http://freepdf-books.com
![Page 216: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/216.jpg)
enabletheConvexcheckbox,itwouldgenerateacollidershapeclosertotheconvexmeshontheleft.
Ineithercase,thePhysicsSystemwillattempttogenerateacolliderthatmatchestheshapeoftheattachedmesh,withanupperlimitof255vertices.Ifthetargetmeshhasmoreverticesthanthis,thenitwillthrowanerrorduringgenerationofthemesh.NotethatConcaveMeshColliderswithattachedRigidbodyobjectsarenotsupportedinUnity5.ConcaveshapescanonlybeusedasStaticColliders(forexample,acollidableobjectintheworldthatdoesn’tmove),orTriggerVolumes(forexample,anoddly-shapedpoolofacid).
http://freepdf-books.com
![Page 217: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/217.jpg)
TheCollisionMatrixThePhysicsSystemfeaturesaCollisionMatrixthatdefineswhichobjectsareallowedtocollidewithwhichotherobjects.ObjectsthatdonotfitthismatrixareautomaticallyignoredbythePhysicsSystemwhenthetimecomestoresolveboundingvolumeoverlapsandcollisions.Thissavesonphysicsprocessingduringcollisiondetectionstages,andalsoallowstheobjectstomovethroughoneanotherwithoutanycollisionstakingplace.
TheCollisionMatrixsystemworksthroughUnity’sLayersystem.Thematrixrepresentseverypossiblelayer-to-layercombinationthatmightbepossible,andenablingacheckboxmeansthatcollidersinbothofthoselayerswillbecheckedduringthecollisiondetectionphase.Notethatthere’snowaytoallowonlyoneofthetwoobjectstorespondtothecollision.Ifonelayercancollidewithanother,thentheymustbothrespondtothecollision(withtheexceptionofStaticColliders,whicharen’tallowedtorespondtocollisions).
TheCollisionMatrixcanbeaccessedthroughEdit|ProjectSettings|Physics(orPhysics2D)|LayerCollisionMatrix.
Notethatwearelimitedtoonly32totallayersforourentireproject(sincethePhysicsSystemusesa32-bitbitmasktodetermineinter-layercollisionopportunities),sowemustorganizeourobjectsintosensiblelayersthatwillextendthroughouttheentirelifetimeoftheproject.If,forwhateverreason,32layersarenotenoughforourproject,thenwemightneedtofindcunningwaystoreuselayers,orremovelayersthataren’tnecessary.
http://freepdf-books.com
![Page 218: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/218.jpg)
RigidbodyactiveandsleepingstatesEverymodernPhysicsEnginesharesacommonoptimizationtechniquewherebyobjectsthathavecometoresthavetheirinternalstatechangedfromanactivestatetoasleepingstate.Whilesleeping,little-to-noprocessortimewillbespentupdatingtheobjectuntilithasbeenawokenbysomeexternalforceorevent.
Thevalueofmeasurementthatisusedtodetermine“rest”tendstovarybetweenengines;itcouldbecalculatedusinglinearandrotationalspeed,kineticenergy,momentum,orsomeotherphysicalpropertyoftheRigidbody.Inanycase,ifanobjecthasnotexceededsomethresholdvalueinashorttime,thenthePhysicsEnginewillassumetheobjectwillnolongerneedtomoveagainuntilithasundergoneanewcollision,oranewforcehasbeenappliedtoit.Untilthen,thesleepingobjectwillmaintainitscurrentposition.
Inessence,thePhysicsEngineisautomaticallycullingsomeprocessingtasksforobjectsthathaveasmallamountofkineticenergy.Butthisdoesnotremoveitentirelyfromthesimulation.IfamovingRigidbodyapproachesthesleepingobject,thenitmuststillperformcheckstoseewhethernearbyobjectshavecollidedwithit,whichwouldreawakenthesleepingobject,reintroducingittothesimulationforprocessing.ThethresholdvalueforthesleepingstatecanbemodifiedunderEdit|ProjectSettings|Physics|SleepThreshold.WecanalsogetacountofthetotalnumberofactiveRigidbodyobjectsfromthePhysicsareaoftheProfiler.
http://freepdf-books.com
![Page 219: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/219.jpg)
RayandobjectcastingAnothercommonfeatureofPhysicsEnginesistheabilityto“cast”arayfromonepointtoanother,andgatherdataaboutoneormoreoftheobjectsinitspath.Itisprettycommontoimplementimportantgameplaytasksthroughcastingandbounding-volumechecks.Firinggunsistypicallyimplementedbyperformingraycastsfromtheplayertothetargetlocationandfindinganyviabletargetsinitspath(evenifit’sjustawall).
Wecanalsoobtainalistoftargetswithinanexplosionradius,suchasfromagrenadeorfireball,usingaPhysics.OverlapSphere()check,andsothisistypicallyhowsucharea-of-effectabilitiesareimplemented.
Wecanevencastentireobjectsforwardinspace,usingPhysics.SphereCast()andPhysics.CapsuleCast().Thesemethodsareoftenusedifweneedraysoflargersizes,orwewishtoseewhatwouldbeinthepathofamovingcharacter.
http://freepdf-books.com
![Page 220: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/220.jpg)
http://freepdf-books.com
![Page 221: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/221.jpg)
PhysicsperformanceoptimizationsNowthatwehaveanunderstandingofthemostsignificantfeaturesoftheUnityPhysicsEngine,wecancoversomeoptimizationtechniquestoimproveourgame’sphysicsperformance.
http://freepdf-books.com
![Page 222: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/222.jpg)
ScenesetupFirstly,thereareanumberofbestpracticeswecanapplytoourScenestoimproveconsistencyofthephysicssimulation.NotethatthesetechniqueswillnotnecessarilyimproveCPUormemoryusage,buttheywillresultinareducedlikelihoodofinstabilityfromthePhysicsEngine.
ScalingWeshouldtrytokeepallphysicsobjectscalesintheworldascloseto1:1:1aswepossiblycan.Thismeansthatforthedefaultgravityvalueof-9.81,theunitscaleoftheworldisimpliedtobe1meterperunit,sincetheforceofgravityatthesurfaceoftheEarthis9.81m/s²(mostgamesaretryingtosimulatethissituation).Ourobjectsizesshouldreflectourimpliedworldscale,sincescalingthemtoolargewillcausegravitytoappeartomovetheobjectsmuchmoreslowlythanwewouldexpect.Theconverseisalsotrue;scalingobjectstoosmallwillmakethemappeartofalltooquicklyandwillnotseemrealistic.
Wecantweaktheworld’simpliedscalebymodifyingthestrengthofgravityunderEdit|ProjectSettings|Physics(orPhysics2D)|Gravity.However,beawarethatanyfloating-pointarithmeticwillbemoreaccuratewithvaluescloserto0,soifwehavesomeobjectsthathavescalevaluesfarabove(1,1,1),eveniftheymatchtheimpliedworld-scale,thenwecouldstillobserveerraticphysicsbehavior.So,earlyintheprojectweshouldimportandscaleourmostcommonphysicsobjectsaroundascalevalueof(1,1,1),andthenadjustthevalueofgravitytomatch.Thiswillgiveusareferencepointtoworkwithasweintroducenewobjects.
TipBewarnedthatUnity4alsohasavalueforSpeedofSoundinitsAudiosettings,whichisusedduringanyDoppler-basedaudioeffects.Thedefaultvalueis343tomatchthespeedofsoundinairof343ms-1.Changingtheimpliedworldscaleviagravitywillrequirethisvaluetobeadjustedtomaintainconsistency.Unity5calculatestheDopplerEffectdifferentlyandsothisvariablewasremoved,nolongermakingthisissueaconcern.
PositioningSimilarly,keepingallobjectscloseto(0,0,0)inpositionwillresultinbetterfloating-pointaccuracy,improvingtheconsistencyofthesimulation.SpaceSimulatorandFree-Runninggamestrytosimulateincrediblylargespaces,andtheytypicallyusethistechniqueasmuchaspossiblebysecretlyteleporting,(orsimplykeeping)theplayercharactercenteredintheworld.Atthispoint,eithereverythingelseismovedtosimulatetravel,orvolumesofspacearecompartmentalizedsothatphysicscalculationsarealwayscalculatedwithvaluesclosetozero.Thisensuresthatallobjectsremaincloseto(0,0,0)inordertoavoidfloating-pointinaccuraciesastheplayertravelsgreatdistances.
Othertypesofgamesshouldnotriskintroducingfloating-pointinaccuracy,sounlesswe’realreadydeepintoourproject(suchthatchangingandre-testingeverythingatalate
http://freepdf-books.com
![Page 223: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/223.jpg)
stagewouldbetoomuchhassle),weshouldtrytokeepallofourphysicsobjectscloseto(0,0,0).Plus,thisissimplygoodpracticeforourprojectworkflowasitmakesitmuchfastertoaddandpositionobjectsinourgameworld.
MassTheUnitydocumentationrecommendsthatobjectmassvaluesstayaround0.1,withnovaluesexceeding10,duetotheinstabilityitgenerates:http://docs.unity3d.com/ScriptReference/Rigidbody-mass.html.
Thismeansweshouldnotthinkofmassintermsofmeasurementssuchaspoundsorkilograms,butratherarelativevaluebetweenobjects.Weshouldtrytomaintainconsistentandreasonableratiosofmassbetweencollidingobjects.Havingobjectscollidingwithamassratioofgreaterthan1,000willmostcertainlyresultinerraticbehaviorduetothelargemomentumdifferenceandeventuallossoffloatingpointprecision.Weshouldtrytoensureinter-objectcollisionsoccurwithobjectswithsimilarvaluesoftheirmassproperty,andobjectpairsthathaveasignificantscaledifferenceshouldbeculledwiththeCollisionMatrix(moreonthisshortly).
TipImpropermassratiosarethemostcommoncauseforphysicsinstabilityanderraticbehavior.
NotethattheforceofgravityatthecentreoftheEarthaffectsallobjectsequally,regardlessoftheirmass,soitdoesnotmatterifweconsideramasspropertyvalueof1tobethemassofarubberballorthemassofawarship.There’snoneedtoadjusttheforceofgravitytocompensateforanyassumptionswe’remakingwiththeserelativemasspropertyvalues.Whatdoesmatter,however,istheamountofairresistancethegivenobjectundergoeswhilefalling(thisiswhyafeatherfallsslowerthanasolidobjectofidenticalmass).So,tomaintainrealisticbehavior,wemayneedtocustomizethedragpropertyforsuchobjectsorcustomizetheforceofgravityonaper-objectbasis(suchasdisablingtheUseGravitycheckboxandapplyingacustomgravitationalforceviaScriptcode).
http://freepdf-books.com
![Page 224: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/224.jpg)
UseStaticCollidersappropriatelyAspreviouslymentioned,thePhysicsSystemautomaticallygeneratesadatastructurefromthedataofallStaticColliders(colliderswithoutRigidbodyobjects)separatelyfromthestructurethatmanagesDynamicColliders(colliderswithRigidbodyobjects).Unfortunately,ifnewobjectsareintroducedintothedatastructureatruntime,thenitmustberegenerated.ThisislikelytocauseasignificantCPUspike.ThismakesitvitalthatweavoidinstantiatingnewStaticCollidersduringgameplay.
Inaddition,merelymoving,rotating,orscalingStaticCollidersalsotriggersthisregenerationprocessandshouldbeavoided.Ifwehavecollidersthatwewishtomovearoundwithoutreactingtootherobjectscollidingwiththeminaphysicalway,thenweshouldattachaRigidbodytomakeitaDynamicColliderandsettheKinematicflagtotrue.Thisflagpreventstheobjectfromreactingtoexternalimpulsesfrominter-objectcollisions.ThisallowsittobehavesimilartoaStaticCollider,butitisnowinadatastructurethatproperlysupportsmovingobjects,sowecanmoveitaroundfromScriptcode(duringFixedUpdates!),anditwillapplyimpulsestootherobjects.
TipIt’sforthisreasonthattheKinematicflagisoftenusedonobjectscontrolledbyplayers;theycanpushotherobjectsaroundbutshouldn’tbepushedaroundthemselves.
http://freepdf-books.com
![Page 225: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/225.jpg)
OptimizetheCollisionMatrixAsweknow,thePhysicsSystem’sCollisionMatrixdefineswhichobjectsassignedtocertainlayersareallowedtocollidewithobjectsassignedtootherlayers.Ortoputitmoresuccinctly,whichobjectpairsareevenconsideredbythePhysicsSystem.Everyotherobject-layer-pairissimplyignoredbythePhysicsEngine,whichmakesthisanimportantavenueforminimizingPhysicsEngineworkloadsinceitreducesthenumberofbounding-volumechecksthatmustbeperformedateachandeverytimestep.
TipReminder:theCollisionMatrixcanbeaccessedthroughEdit|ProjectSettings|Physics(orPhysics2D)|LayerCollisionMatrix.
ThefollowingscreenshotshowsacommonCollisionMatrixforanarcadeshootergame:
Inthisexample,wehaveminimizedthenumberofpossibleinter-objectcollisionsforthePhysicsSystemtocheck.Sincepowerupscanonlybepickedupbytheplayer,thenthereisnoneedtocomparecollisionsbetweenpowerupsandobjectsfromanyotherlayers.Meanwhile,wedon’twishforprojectilestocollidewiththeobjectthatfiredit,whichexcludesEnemyProjectilesfromcollidingwithenemies,andPlayerProjectilesfromcollidingwiththeplayer.Wewanteverythingtocollidewiththegameworld(wallsandothersurfaces),andperhapswedon’twantprojectilescollidingwithotherprojectiles(althoughsomegamesmightwantthis!).
WeshouldperformlogicalsanitycheckslikethisforalloftheLayercombinationsintheCollisionMatrixtoseewhetherwe’rewastingprecioustimecheckingforinter-objectcollisionsbetweenobject-pairsthataren’tnecessary.
http://freepdf-books.com
![Page 226: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/226.jpg)
PreferdiscretecollisiondetectionWeshouldusetheDiscreteoptionbydefaultforthemajorityofobjects.Teleportingobjectsonceandperformingasingleoverlapcheckbetweennearbyobject-pairsisafairlytrivialamountofwork.However,theamountofcalculationittakestointerpolatetheobjectsbetweentheirstartingandendingpositions,andsimultaneouslyverifyanyslightbounding-volumeoverlapsbetweenthesepointsovertime,issignificantlygreater.
Consequently,theContinuouscollisiondetectionoptionisanorderofmagnitudemoreexpensivethantheDiscretedetectionmethod,andtheContinuousDynamiccollisiondetectionsettingisanorderofmagnitudemoreexpensivethanContinuous!HavingtoomanyobjectsofthecontinuoustypeswillcauseseriousperformancedegradationincomplexScenes.Ineithercase,thecostsaremultipliedbythenumberofobjectsthatneedtobecomparedduringanygivenframeandwhetherornotthecomparisoncolliderisStaticorDynamic.
Ergo,thecontinuousdetectionsettingsshouldonlybeusedinextremecircumstances.TheContinuoussettingshouldbeusedwhenimportantcollisionsarefrequentlymissedwiththestaticworld,forinstance,ifweexpectcertainobjectstomovequickly,andwewishtobecertaintheyneverfallthroughthegameworldorteleportthroughwalls.Finally,theContinuousDynamicsettingshouldonlybeusedifthesamesituationappliesbutwewishtocatchcollisionsbetweenpairsofvery-fastmovingDynamicColliders.Unlesswehavegoodreasontousethem,allothersituationsshouldfavortheDiscretesetting.
But,perhaps,theDiscretesettingisn’tworkingwell-enoughonalargescale.Perhapsourentiregamerevolvesaroundalotofsmallphysicsobjectsanddiscretecollisiondetectionsimplyisn’tcatchingenoughcollisionstomaintainproductquality.Well,we’reinluck,becausewecancustomizethephysicstimesteptogivetheDiscretecollisionoptionabetterchanceofcatchingsuchcollisionsbymodifyinghowfrequentlytheenginechecksforFixedUpdates.
http://freepdf-books.com
![Page 227: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/227.jpg)
ModifytheFixedUpdatefrequencyAsmentionedpreviously,FixedUpdatesandphysicstimestepprocessingarestrongly-coupled,sobymodifyingthefrequencyofFixedUpdatecheckswenotonlychangethefrequencythatthePhysicsSystemwillcalculateandresolvethenextcallback,butwewillalsochangehowfrequentlyFixedUpdate()callbacksarebeinginvoked.Consequently,changingthisvaluecanberiskyifwe’redeepintoourprojectandhavealotofbehaviorthatdependsonthesecallbacks.
AlteringtheFixedUpdatefrequencycanbeaccomplishedthroughtheEdit|ProjectSettings|Time|FixedTimesteppropertyintheEditor,orthroughtheTime.fixedDeltaTimepropertyinscriptcode.
Reducingthisvalue(increasingthefrequency)willforcethePhysicsSystemtoprocessmorefrequently,givingitabetterchanceofcatchingcollisionsbetweenourDynamic,Discreteobjects.Naturally,thiscomeswithaCPUcostsincewe’reinvokingmoreFixedUpdate()callbacks,aswellasaskingthePhysicsEnginetoupdatemorefrequently,havingitmoveobjectsandverifycollisionsmoreoften.
Conversely,increasingthisvalue(decreasingthefrequency)providesmoretimefortheCPUtocompleteothertasksbeforeitmusthandlephysicsprocessingagain,orlookingatitfromanotherperspective,givingthePhysicsSystemmoretimetoprocessthelasttimestepbeforeitbeginsprocessingthenextone.But,loweringtheFixedUpdatefrequencywouldessentiallylowerthemaximumvelocityatwhichobjectscanbemovingbeforethePhysicsSystemcannolongercapturecollisionsbetweendiscreteobjects(dependingontheobjects’sizes).
ThismakesitabsolutelyvitaltoperformasignificantamountoftestingeachtimetheFixedTimestepvalueischanged.Evenwithacompleteunderstandingofhowthisvalueworks,itisdifficulttopredictwhattheoveralloutcomewilllooklikeduringgameplay,
http://freepdf-books.com
![Page 228: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/228.jpg)
andwhethertheresultispassableforqualitypurposes.Hence,changestothisvalueshouldbemadeearlyintheproject’slifecycleandthenmadeinfrequentlyinordertogetasufficientamountoftestingagainstasmanyphysicssituationsaspossible.
ItmighthelptocreateatestScenethatflingssomeofourhigh-velocityobjectsatoneanothertoseeiftheresultsareacceptable,andrunthroughthisScenewheneverFixedTimestepchangesaremade.Butactualgameplaytendstoberathercomplex,withmanybackgroundtasksandunanticipatedplayerbehaviorthatcausesadditionalworkforthePhysicsSystem,orgivesitlesstimetoprocessthecurrentiteration.Actualgameplayconditionsaredifficulttoduplicateinavacuum,andthere’snosubstitutefortherealthing,sothemoretestingwecanaccomplishagainstthecurrentvalueofFixedTimestep,themoreconfidentwecanbethatthechangesmeetacceptablequalitystandards.
Wealwayshavethecontinuouscollisiondetectionoptionsasalastresorttooffsetsomeoftheresultinginstabilitywe’reobserving.Butunfortunately,evenifthechangesaretargeted,itismorelikelythatthiswillcausefurtherperformanceissuesthanwestartedwithduetotheoverheadcostsofcontinuouscollisiondetection.ItwouldbewisetoprofileourScenebeforeandafterenablingcontinuouscollisiondetectiontoverifythatthebenefitsareoutweighingthecosts.
http://freepdf-books.com
![Page 229: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/229.jpg)
AdjusttheMaximumAllowedTimestepIftheMaximumAllowedTimestepvaluegetshitregularly,thenitwillresultinsomeprettybizarre-lookingphysicsbehavior.Rigidbodyobjectswillappeartoslowdownorfreezeinspace,sincethePhysicsEngineneedstokeepexitingearlybeforeithasfullyresolveditsentiretimequota.Inthiscase,itisaclearsignthatweneedtooptimizeourphysicsfromotherangles.Butattheveryleastwecanbeconfidentthethresholdwillpreventthegamefromcompletelylockingupduringaphysicsprocessingspike.
ThissettingcanbeaccessedthroughEdit|ProjectSettings|Time|MaximumAllowedTimestep.Thedefaultsettingistoconsumeamaximumof0.333seconds,whichwouldmanifestitselfasaverynoticeabledropinframerate(amere3FPS)ifitwerebreached.Ifweeverfeeltheneedtochangethissetting,thenweobviouslyhavesomebigproblemswithourphysicsworkload,soitisrecommendedtoonlytweakthisvalueifwehaveexhaustedallotherapproaches.
http://freepdf-books.com
![Page 230: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/230.jpg)
Minimizecastandbounding-volumechecksAlloftheraycastingmethodsareincrediblyuseful,buttheyarerelativelyexpensive(particularlyCapsuleCast()andSphereCast()),requiringustominimizehowoftentheyarecalled.WeshouldavoidcallingthesemethodsregularlywithinUpdatecallbacksorCoroutines,savingthemonlyforkeyeventsinourscriptcode.
Ifweabsolutelymustrelyonpersistentline,ray,orarea-of-effectcollisionareasinourScene(examplesincludesecuritylasers,orcontinuouslyburningfires),thentheywouldbebettersimulatedusingasimpleTriggerCollider,ratherthanperformingcontinuousraycastingoroverlapchecks.
Ifsuchreplacementsarenotpossible,andwetrulyneedpersistentcastingchecksusingthesemethods(suchasared-dotlasersight),thenwecanminimizetheamountofprocessingeachcallmakesbyexploitingtheLayerMaskobjects.
Forexample,alazyraycastwouldlooklikeso:
[SerializeField]float_maxRaycastDistance;
voidPerformRaycast(){
RaycastHithitInfo=newRaycastHit();
if(Physics.Raycast(newRay(transform.position,transform.forward),
outhit,_maxRaycastDistance)){
//handleraycastresulthere
}
}
ButthisoverloadofPhysics.Raycast()willcausetheraytocollidewiththefirstobjectofanylayerinitspath.ThePhysics.RaycastmethodhasmultipleoverloadsthatacceptaLayerMaskobjectforanargument.Wecanusethistocustomizewhichobjectsshouldbecheckedbytheraycast,simplifyingtheworkloadforthePhysicsEngine:
[SerializeField]float_maxRaycastDistance;
[SerializeField]LayerMask_layerMask;
voidPerformRaycast(){
RaycastHithitInfo=newRaycastHit();
if(Physics.Raycast(newRay(transform.position,transform.forward),
outhit,_maxRaycastDistance,_layerMask)){
//handleraycastresulthere
}
}
TheLayerMaskobjectcanthenbeconfiguredthroughtheobject’sInspectorview:
http://freepdf-books.com
![Page 231: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/231.jpg)
TipNotethat,becausetheRaycastHitandRayclassesaremanagedbythenativememoryspaceoftheUnityEngine,theydon’tresultinmemoryallocationsthatdrawtheattentionoftheGarbageCollector.WewilllearnmoreaboutsuchactivityinChapter7,MasterfulMemoryManagement.
http://freepdf-books.com
![Page 232: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/232.jpg)
AvoidcomplexMeshCollidersInorderofefficiency,thevariouscollidersare:Spheres,Capsules,Cylinders,Boxes,ConvexMeshColliders,andfinallyConcaveMeshColliders.However,thefourmainprimitivesareanorderofmagnitudemoreefficientthaneitheroftheMeshColliders,asthemathematicalcalculationsfordetectingandresolvingcollisionsbetweenthemarefairlysuccinctandoptimized.Performingcomparisonsbetweenaconvexshapeandanothercollidercanbeacostlyprocess,whilecomparingbetweenaconcaveshapeandanythingelseisevenmoreexpensive.
NotePerformingruntimebounding-volumechecksbetweenpairsofconcaveshapesisperhapstheclosestthingto“MathematicalArmageddon”thatwemightfindinareal-timephysicssimulation(atleastforafewmoreyears!).Toprotectusfromourownstupidity,Unityeffectivelybansusfromperformingconcave-to-concaveMeshColliderboundingvolumechecks.
Agreatironybetweenphysicsandgraphicsin3Dapplicationsishowdifficultitistohandlesphericalandboxobjectsbetweenthetwoofthem.Theperfectsphericalmeshwouldrequireaninfinitenumberofpolygonstogenerate,buthowasphereisrepresentedinaPhysicsEngineisrelativelytrivialtoresolveforcontactpointsandcollisions.Conversely,asimpleboxtakesaminisculenumberofpolygonsandefforttoproducegraphically,andyettakessignificantlymoremathematicsandprocessingpowertofindcontactpointsandresolvecollisionsfor.Thisimpliesthatgettingthemostoutofbothgraphicsandphysicswouldbetopopulateourworldwithlow-polygongraphicalobjects,representedassphereswithinthePhysicsSystem.However,thiswouldmakeabsolutelynosensetoahumanobserverastheywitnesssharp,pointyobjectsrollingaroundlikeballs.
ItisalwaysimportanttorememberwhenworkingwithPhysicsEnginesthatthephysicalrepresentationofanobjectdoesnotnecessarilyneedtomatchitsgraphicalrepresentation.Thisisbeneficialasagraphicalmeshcanoftenbecondenseddownintoamuchsimplershape,generatingaverysimilarphysicsbehaviorandsparingustheneedtouseanoverly-complexMeshCollider.
Thisseparationofrepresentationsbetweengraphicsandphysicsallowsustooptimizetheperformanceofonesystemwithout(necessarily)negativelyaffectingtheother.Iftherewouldbenonoticeablerepercussionsongameplay,thenwearefreetorepresentcomplexgraphicalobjectswiththesimplestphysicsshapesbehind-the-scenes.Iftheplayernevernotices,thennoharmisdone!
So,wecansolvethisprobleminoneoftwoways:eitherbyapproximatingthephysicsbehaviorofthecomplexshapeusingone(ormore)ofthestandardprimitives,orausingamuchsimplerMeshCollider.
UsesimplerprimitivesMostshapescanbeapproximatedusingoneofthefourprimitivecolliders(inorderof
http://freepdf-books.com
![Page 233: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/233.jpg)
efficiency):Spheres,Capsules,Cylinders,orBoxes.Infact,wedonotneedtorepresenttheobjectusingonlyasinglecollider;wearefreetouseseveralcollidersifitservesourneedsforcreatingacomplexcollisionshapebyattachingadditionalchildGameObjectswiththeirowncolliders.ThisisalmostalwayslesscostlythanusingasingleMeshColliderandshouldbepreferredovermorecomplexsolutions.
Thefollowingimageshowsahandfulofcomplexgraphicalobjects,representedbyoneormoresimplerprimitivesinthePhysicsSystem:
UsingaMeshColliderforanyoneoftheseobjectswouldbesignificantlymorecostlythantheprimitivecollidersshownhere.Itisworthexploringanyandallopportunitiestosimplifyourobjectsdownusingtheseprimitivesasmuchaswecan,astheycanprovidesignificantperformancegains.
Forexample,concavemeshesareuniqueinthattheycanfeaturegaps,orholes,thatallowothermeshesto“fall”into,oreventhroughthem,whichintroducesopportunitiesfortheobjectstofallthroughtheworldifconcaveshapesareusedforworldcollisionareas.ItisoftenbettertoplaceBoxCollidersinstrategiclocationsforthispurpose.
UsesimplerMeshCollidersThemeshassignedtotheMeshColliderdoesnotnecessarilyneedtomatchthegraphicalrepresentationofthesameobject(Unitysimplypicksitasthedefault).ThisgivesusanopportunitytoreplacetheMeshCollider’smeshpropertywithadifferent,simplermeshforanobject’scolliderfromtheoneweuseforitsgraphicalrepresentation.
ThefollowingimageshowsanexampleofacomplexgraphicalmeshthathasbeengivenasimplifiedmeshforitsMeshCollider:
http://freepdf-books.com
![Page 234: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/234.jpg)
Simplifyingtherenderedmeshintoconvexshapeswithlowerpolygoncountsinthiswaywillgreatlyreducetheoverheadneededtodeterminebounding-volumeoverlapswithothercolliders.Dependingonhowwelltheoriginalobjectisestimated,theremaybefewtononoticeablegameplaydifferences,especiallyinthecaseofthisaxe,whichweexpecttobemovingquicklyascreaturesswingitduringattacks,makingitunlikelythatplayerswillnoticethedifferencebetweenthetwomeshesascolliders.
http://freepdf-books.com
![Page 235: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/235.jpg)
AvoidcomplexphysicscomponentsCertainspecialphysicsColliderComponents,suchasTerrain,Cloth,andWheelColliders,areordersofmagnitudemorecostlythanallprimitivecolliders,andevenMeshCollidersinsomecases.WeshouldsimplynotincludesuchComponentsinourScenesunlesstheyareabsolutelynecessary.Forinstance,ifwehaveTerrainobjectsinthedistancethattheplayerwillneverapproach,thenthere’slittlereasontoincludeanattachedTerrainCollider.
GamesfeaturingClothComponentsshouldconsiderinstantiatingdifferentobjectswithoutthemwhenrunninginlower-qualitysettings,orsimplyanimatingclothbehavior(althoughitistotallyunderstandableiftheteamhasgrownattachedandfalleninlovewithhowthestuffmovesaround).
GamesusingWheelCollidersshouldsimplytrytousefewerwheelcolliders!Vehicleswithmorethanfourwheelsmaybeabletouseonlyfourwheelstogeneratethecorrectphysicsbehavior,whilefakingthegraphicalrepresentationofadditionalwheels.
http://freepdf-books.com
![Page 236: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/236.jpg)
LetphysicsobjectssleepThePhysicsEngine’ssleepfeaturecanposeseveralproblemsforourgame.
NoteReminder:thesleepthresholdcanbemodifiedunderEdit|ProjectSettings|Physics|SleepThreshold.
Firstly,somedevelopersdon’trealizethatmanyoftheirRigidbodyobjectsaresleepingduringmostofthelifetimeoftheirapplication.Thistendstoleaddeveloperstoassumethattheycangetawaywith(forexample)doublingthenumberofRigidbodyobjectsintheirgame,andthecostswillsimplydoubletomatchit.Thisisunlikely.Thefrequencyofcollisionsandtotalaccumulatedtimeofactiveobjectsismorelikelytoincreaseinanexponentialfashion,ratherthanalinearone.Thisleadstounexpectedperformancecostswhennewphysicsobjectsareintroducedintothesimulation.WeshouldkeepthisinmindwhenwedecidetoincreasethephysicscomplexityofourScenes.
Secondly,thereisthedangerof“islands”ofsleepingphysicsobjectsbeinggenerated.IslandsarecreatedwhenalargenumberofRigidbodyobjectsaretouchingoneanother,andhavegraduallycometorest—imagineapileofboxesthathavebeenspawnedandformedalargepile.Eventually,alloftheRigidbodyobjectswillfallasleeponceenoughenergyinthesystemislostandtheyallcometorest.However,becausethey’reallstilltouchingoneanother,assoonasoneoftheseobjectsisawoken,itwillstartachainreaction,awakeningallothernearbyRigidbodyobjects.SuddenlywehavealargespikeinCPUusagebecausedozensofobjectshavenowre-enteredthesimulation,andtherearesuddenlymanymorecollisionstoresolveuntiltheobjectsfallasleepagain.
Ifwecouldfindawaytodetectthatislandsareforming,wecouldstrategicallydestroy/despawnsomeofthemtopreventtoomanylargeislandsfrombeinggenerated.Butworkaroundssuchasthesewillbedependentuponthegameitself,asperformingregular,globalchecks,anddistancecomparisonsbetweenallofourRigidbodyobjectsisnotacheaptasktoaccomplish.Forexample,agamethatrequirestheplayertomovelotsofphysicsobjectsintoanarea(forexample,agamethatinvolvesherdingsheepintoapen)couldchoosetodespawntheDynamicColliderobjectassoonastheplayermovesitintoposition,lockingtheobjecttoitsfinaldestination,andeasingtheworkloadonthePhysicsEngine.
Thirdly,changinganyofaRigidbody’spropertiesatruntime,suchasmass,drag,UseGravity,andsoon,willalsoreawakentheobject.Ifwe’reregularlychangingthesevalues(suchasagamewhereobjectsizesandmasseschangeovertime),thentheywillremainactiveforlongerperiodsoftimethanusual.Thisisalsothecaseforapplyingforces,soifwe’reusingacustomgravitysolution(suchassuggestedbackinthesectionentitledMass),weshouldtrytoavoidapplyingthegravitationalforceeveryFixedUpdate,otherwisetheobjectwillbeunabletofallasleep.
Sleepingobjectscanbeablessingandacurse.Theycansaveusalotofprocessingpower,butiftoomanyofthemreawakenatthesametimeoroursimulationistoobusytoallow
http://freepdf-books.com
![Page 237: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/237.jpg)
enoughofthemtofallasleep,thenwecouldbeincurringsomeunfortunateperformancecostsduringgameplay.Weshouldstrivetolimitthesesituationsasmuchaspossiblebylettingourobjectsenterthesleepingstateasmuchaspossible,andavoidgroupingthemtogetherinlargeclusters.
http://freepdf-books.com
![Page 238: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/238.jpg)
ModifySolverIterationCountJoints,Springs,andotherconnectedRigidbodyobjectsarenottrivialtosimulateintheworldofPhysicsEngines.Becauseoftheco-dependentinteractivity(internallyrepresentedasmovementconstraints)thatoccurswithjoiningtwoobjectstogether,thesystemmustoftenmakeseveralattemptsatsolvingthenecessarymathematicalequations.Thismulti-iterationapproachisrequiredtocalculateanaccurateresultwheneverthereisachangeinvelocitytoanypieceoftheobject-chain.
Itthereforebecomesabalancingactoflimitingthemaximumnumberofattemptsthe“Solver”makestoresolveaparticularsituation,versushowaccuratearesultwecangetawaywith.Wedon’twanttheSolvertospendtoomuchtimeonasinglecollision,becausethereisalotofotherworkthePhysicsEnginehastodowithinthesameiteration.But,wealsodon’twanttoreducethemaximumnumberofiterationstoofarasitwillonlyapproximatewhatthefinalsolutionwouldhavebeenifithadbeengivenmoretimetocalculatetheresult.
NoteThesameSolveralsogetsinvolvedwhenresolvinginter-objectcollisionsandcontacts.Itcanalmostalwaysdeterminethecorrectresultwithasingleiteration,withtheexceptionofsomeveryrareandcomplexcollisionsituations.Itisonlywhenthird-partyobjectswillbeaffectedthroughJointsthattheSolverrequiresadditionalefforttomathematicallyintegratethefinalresult.
TheSolverIterationCountcanbemodifiedunderEdit|ProjectSettings|Physics|SolverIterationCount.Inmostcases,thedefaultvalueofsixiterations(seveniterationsinUnity4)isperfectlyacceptable.But,gamesthatincludeverycomplexjointsystemsmaywishtoincreasethiscounttosuppressanyerratic(ordownrightexplosive)CharacterJointbehaviors,whilesomeprojectsmaybeabletogetawaywithreducingthiscount.Testingmustbeperformedafterchangingthisvaluetoseewhethertheprojectstillmaintainstheintendedlevelsofquality.
Incidentally,ifwefindourgameregularlyrunsintojarring,erratic,andphysics-breakingsituationswithcomplexJoint-basedobjects(suchasragdolls),thenweshouldconsidergraduallyincreasingtheSolverIterationCountuntiltheproblemshavebeensuppressed.TheseproblemstypicallyoccurifourragdollsabsorbtoomuchenergyfromcollidingobjectsandtheSolverisunabletoiteratethesolutiondowntosomethingreasonablebeforeitisaskedtogiveup.Atthispoint,oneoftheJointsgoessupernova,draggingtherestofthemintoorbitalongwithit!
Weshouldalsodoublecheckthatourragdoll’sRigidbodymassesareobeyingtherulessetforthearlierinthischapter,sothattheresultantenergyexchangeandvelocitieswillbemorereasonable.
http://freepdf-books.com
![Page 239: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/239.jpg)
OptimizingragdollsSpeakingofCharacterJoints,ragdollsareincrediblypopularfeaturesforgoodreason;they’retonsoffun!Ignoringthemorbidityofflingingcorpsesaroundagameworldforthemoment,there’ssomethingaboutwatchingacomplexchainofobjectsflailaroundandsmashintothingsthathitsalotofpsychological“funbuttons”.
ThismakesitverytemptingtoallowmanyragdollstocoexistwithinourSceneatthesametime,butaswequicklydiscover,thisrisksanenormousperformancehitwhentoomanyragdollsareinmotionand/orcollidewithotherobjectsduetotheamountofiterationstheSolverwouldneedtoresolvethemall.So,let’sexploresomewaystoimprovetheperformanceofanyragdollswewishtouse.
ReduceJointsandCollidersUnityprovidesasimpleragdoll-generationtoolunderGameObject|3DObject|Ragdoll…inUnity5,orGameObject|CreateOther|Ragdoll…inUnity4.Thistoolcanbeusedtocreateragdollsfromagivenobjectbyselectingtheappropriatechildobjectstoattachcolliderstoforanygivenbodypartorlimb.Thistoolalwayscreates11differentcollidersandassociatedJoints(pelvis,chest,head,andtwocollidersperlimb),butwemightwishtoconsiderusingonlysixcolliders(body,head,andonecolliderperlimb)togreatlyreducetheoverheadcostattheexpenseofragdollrealism.ThiscanbeachievedbydeletingunwantedcollidersandreassigningtheCharacterJoint’sConnectedBodypropertiestotheproperparentjoints.
Suchsimplificationscouldbeimplementedasameansofreducingoverheadforweakerhardware/lowerqualitysettings,asasimplecompromisetoallowmoreragdollstocoexistinourScene.Itcouldevenbeuseddynamicallyifaparticularnumberofragdollsarealreadypresent.Agodclasswouldneedtokeeptrackofhowmanyragdollscurrentlyexist,butwhennewragdollsareintroduced,wecouldinstantiateasimplerversioninordertokeepthingsrunningsmoothly.
Avoidinter-ragdollcollisionsUnlesswereallydesireinter-ragdollcollisionsthenweshouldperhapsdisablethemusingtheCollisionMatrix.Theperformancecostofragdollsgrowsexponentiallywhenragdollscollidewithoneanother,sincewewouldbeaskingtheSolvertoworkextrahardandriskingerraticbehaviorduetotheapproximationsitisforcedtomake.
DisableorremoveinactiveragdollsFinally,wecouldconsiderdisallowingragdollsfromre-enteringthephysicssimulationaftertheyhavecometorest.Insomegames,oncearagdollhasreacheditsfinal“destination,”wenolongerneedittoremaininthegameworldasaninteractableobject.
Wecanpollanygivencollider’ssleepstatewiththeIsSleepingmethodand,onceithasreachedthisstate,wehaveanumberofoptionswecanpursue.Wecoulddisablealloftheragdoll’scolliders,preventingitfrombeingreintroducedtothesimulation,wecouldremovetheragdollfromtheSceneforthesakeofcleanup,orwecouldkeeptrackofthis
http://freepdf-books.com
![Page 240: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/240.jpg)
ragdollandonlyremoveitwhenadifferentragdollhasbeenintroducedtotheScene.
Whateverapproachwechoosetoimprovetheperformanceofourragdollswillnodoubtresultinlimitingragdollsasagameplayfeature,eitherbyinstantiatingfewerofthem,givingthemlesscomplexity,orgivingthemashorterlifetime,butthesearereasonablecompromisestomakegiventheperformance-savingopportunities.
http://freepdf-books.com
![Page 241: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/241.jpg)
KnowwhentousephysicsAsalways,thebestmethodofimprovingtheperformanceofafeatureistoavoidusingitasmuchaspossible.Forallmoveableobjectsinourgame,weshouldtakeamomenttoaskourselvesifgettingthePhysicsEngineinvolvedisevennecessary.Ifnot,weshouldlookforopportunitiestoreplacethemwithsomethingsimplerandlesscostly.
Perhapswe’reusingphysicstodetectwhethertheplayerfellintoakill-zone,butourgameissimpleenoughthatweonlyhavekill-zonesataspecificheight.Inthiscase,wecouldavoidphysicscollidersaltogetherandgetawaywithonlycheckingwhethertheplayer’sypositionfallsbelowaparticularvalue.
Asanotherexample,maybewe’retryingtosimulateameteorshower,andourfirstinstinctwastohavemanyfallingobjectsthatmoveviaphysicsRigidbodyobjects,detectcollisionswiththegroundviacolliders,andthengenerateanexplosionatthepointofimpact.ButperhapsthegroundisconsistentlyflatorwehaveaccesstotheTerrain’sHeightMapforsomerudimentarycollisiondetection.Inthiscase,objecttravelcouldbesimplifiedbytweeningtheobjects’transform.positionpropertiesovertimetosimulatethesamebehaviorwithoutrequiringanyphysicscomponents.Inbothcases,wecanreducethephysicsoverheadbysimplifyingthesituationandpushingtheworkintoScriptcode.
TipTweeningisacommonshort-handtermforin-betweening,whichistheactofinterpolatingpropertiesfromonevaluetoanothermathematicallyovertime.Therearemanyuseful(andfree!)tweeninglibraries,availableontheUnityAssetStore,thatprovidealotofusefulfunctionality.
Thereverseisalsopossible;theremightbeoccasionswherewe’reperformingagreatdealofcalculationthroughScriptcodethatcouldbehandledthroughphysicsrelativelysimply.Forexample,wemighthaveimplementedaninventorysystemwithmanyobjectsthatcanbepickedup.WhentheplayerhitsthePickupkey,eachoftheseobjectsmightbecomparedagainsttheplayer’spositiontofigureoutwhichobjectisclosest.WecouldconsiderreplacingalloftheScriptcodewithasinglePhysics.OverlapSphere()calltogetnearbyobjectswhenthekeyispressed,andthenfigureouttheclosestpickupobjectfromtheresult(orjustpickupallofthem!).Thiscouldgreatlyreducethetotalnumberofobjectsthatmustbecomparedeachtimethekeyispressed.
Theopportunitiesareaswideandfar-reachingasourowningenuity.Theabilitytorecognizeopportunitiestoremoveunnecessaryphysicsgrunt-workfromourScenes,and/orusephysicstoreplacebehaviorthatiscostlywhenperformedthroughScriptcode,isavitalskillthatwillserveuswellwhensavingperformanceincurrentandfuturegamedevelopmentprojects.
http://freepdf-books.com
![Page 242: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/242.jpg)
ConsiderupgradingtoUnity5Ifwe’rerunningUnity4,anabsolutelastresorttoimprovephysicsperformancewouldbetoconsiderupgradingtoUnity5.TherewereamultitudeofhugeperformanceenhancementswithUnity5’supgradefromPhysXversion2.8.3toversion3.3.TheseimprovementscannotbeoverstatedastheygrantaboutdoubletheperformanceofthePhysicsSystemascomparedtoUnity4.TheupgradeincludeslessoverheadinmovingStaticColliders,improvedperformanceincontinuouscollisiondetectionmethods,supportformorerigidbodies,improvedClothandWheelCollidercomponents,aswellasmulticorephysicssupport.Inshort,itallowsustoreducetheperformancecostofthesameScene,orcrammorephysicsactivityintoourScenesforthesamecost.
However,thesechangesresultedinsomesignificantAPIchangesforcertaintasks,whichmeansScriptingandComponentsinUnity4maynotbefullycompatiblewithUnity5(andnotjustforphysics-relatedtasks).Consequently,theupgradeitselfisunlikelytobetrivial,andweshouldnotforgettomakeabackupofourprojectbeforeattemptingtodoso.TheamountofworkwillultimatelydependonthecomplexityofourprojectandhowitaffectsanyAssetStorepurchaseswerelyon.Eachassetislikelytoneedupdatesofitsownandanyassetsthathavefallenoutofsupportwillneedtobereplaced.
http://freepdf-books.com
![Page 243: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/243.jpg)
http://freepdf-books.com
![Page 244: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/244.jpg)
SummaryWe’vecoverednumerousmethodstoimproveourgame’sphysicssimulationbothintermsofperformance,andconsistency.ThebesttechniquewhenitcomestocostlysystemssuchasPhysicsEnginesissimplyavoidance.Thelessweneedtousethesystem,thelessweneedtoworryaboutitgeneratingbottlenecks.Intheworstcase,wemayneedtoreducethescopeofourgametocondensephysicsactivitydowntoonlytheessentials,butaswe’velearned,thereareplentyofwaystoreducephysicscomplexitywithoutcausinganynoticeablegameplayeffects.
Inthenextchapter,wewillimmerseourselvesinUnity’sgraphicssystem,discoveringhowtomaximizegraphicalfidelityusingalloftheCPUcycleswe’vefreedupusingtheperformanceenhancementsfromearlierchapters.
http://freepdf-books.com
![Page 245: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/245.jpg)
http://freepdf-books.com
![Page 246: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/246.jpg)
Chapter6.DynamicGraphicsThereisnoquestionthattherenderingsystemofmoderngraphicsdevicesiscomplicated.Evenrenderingasingletriangletothescreenengagesmanyofthesecomponents,sinceGPUsaredesignedforlargeamountsofparallelism,asopposedtoCPUs,whicharedesignedtohandlevirtuallyanycomputationalscenario.Moderngraphicsrenderingisahigh-speeddanceofprocessingandmemorymanagementthatspanssoftware,hardware,multiplememoryspaces,multiplelanguages,multipleprocessors,multipleprocessortypes,andalargenumberofspecial-casefeaturesthatcanbethrownintothemix.
Tomakemattersworse,everygraphicssituationwewillcomeacrossisdifferentinitsownway.Runningthesameapplicationagainstadifferentdevice,evenbythesamemanufacturer,oftenresultsinanapples-versus-orangescomparisonduetothedifferentcapabilitiesandfunctionalitytheyprovide.Itcanbedifficulttodeterminewhereabottleneckresideswithinsuchacomplexchainofdevicesandsystems,anditcantakealifetimeofindustryworkin3Dgraphicstohaveastrongintuitionaboutthesourceofperformanceissuesinmoderngraphicssystems.
Thankfully,Profilingcomestotherescueonceagain.Ifwecangatherdataabouteachcomponent,usemultipleperformancemetricsforcomparison,andtweakourScenestoseehowdifferentgraphicsfeaturesaffecttheirbehavior,thenweshouldhavesufficientevidencetofindtherootcauseoftheissueandmakeappropriatechanges.Sointhischapter,youwilllearnhowtogathertherightdata,digjustdeepenoughintothegraphicssystemtofindthetruesourceoftheproblem,andexplorevarioussolutionstoworkaroundagivenproblem.
Asyoulearnedinearlierchapters,theCPUandGPUworkintandemtodeterminewhattextures,meshes,renderstates,Shaders,andsoon,areneededtorenderourScenesatanygivenmoment.We’vealsocoveredseveraltechniquestoreducesomeoftherenderingworkloadthroughStaticandDynamicBatching,andbymanipulatingourmeshandtexturefilesthroughcompressionandencoding,MipMapping,Atlasing,andevensomeproceduralalternatives.
However,therearestillmanymoretopicstocoverwhenitcomestoimprovingrenderingperformance,sointhischapterwewillbeginwithsomegeneraltechniquesonhowtodeterminewhetherourrenderingislimitedbytheCPUorbytheGPU,andwhatwecandoabouteithercase.WewilldiscussoptimizationtechniquessuchasOcclusionCullingandLevelOfDetail(LOD)andprovidesomeusefuladviceonShaderoptimization,aswellaslarge-scalerenderingfeaturessuchaslightingandshadows.Finally,sincemobiledevicesareacommontargetforUnityprojects,wewillalsocoversometechniquesthatmayhelpimproveperformanceonlimitedhardware.
http://freepdf-books.com
![Page 247: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/247.jpg)
ProfilingrenderingissuesPoorrenderingperformancecanmanifestitselfinanumberofways,dependingonwhetherthedeviceisCPU-bound,orGPU-bound;inthelattercase,therootcausecouldoriginatefromanumberofplaceswithinthegraphicspipeline.Thiscanmaketheinvestigatorystageratherinvolved,butoncethesourceofthebottleneckisdiscoveredandtheproblemisresolved,wecanexpectsignificantimprovementsassmallfixestendtoreapbigrewardswhenitcomestotherenderingsubsystem.
WebrieflytoucheduponthesubjectofbeingCPU/GPU-boundinChapter3,TheBenefitsofBatching.Tosummarizetheearlierdiscussion,weknowthattheCPUsendsrenderinginstructionsthroughthegraphicsAPI,thatfunnelthroughthehardwaredrivertotheGPUdevice,whichresultsincommandsenteringtheGPU’sCommandBuffer.ThesecommandsareprocessedbythemassivelyparallelGPUsystemonebyoneuntilthebufferisempty.Buttherearealotmorenuancesinvolvedinthisprocess.
Thefollowingshowsa(greatlysimplified)diagramofatypicalGPUpipeline(whichcanvarybasedontechnologyandvariousoptimizations),andthebroadrenderingstepsthattakeplaceduringeachstage:
ThetoprowrepresentstheworkthattakesplaceontheCPU,theactofcallingintothegraphicsAPI,throughthehardwaredriver,andpushingcommandsintotheGPU.Ergo,aCPU-boundapplicationwillbeprimarilylimitedbythecomplexity,orsheernumber,ofgraphicsAPIcalls.
Meanwhile,aGPU-boundapplicationwillbelimitedbytheGPU’sabilitytoprocessthosecalls,andemptytheCommandBufferinareasonabletimeframetoallowfortheintendedframerate.Thisisrepresentedinthenexttworows,showingthestepstakingplaceintheGPU.But,becauseofthedevice’scomplexity,theyareoftensimplifiedintotwodifferentsections:thefrontendandthebackend.
http://freepdf-books.com
![Page 248: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/248.jpg)
ThefrontendreferstothepartoftherenderingprocesswheretheGPUhasreceivedmeshdata,adrawcallhasbeenissued,andalloftheinformationthatwasfedintotheGPUisusedtotransformverticesandrunthroughVertexShaders.Finally,therasterizergeneratesabatchoffragmentstobeprocessedinthebackend.ThebackendreferstotheremainderoftheGPU’sprocessingstages,wherefragmentshavebeengenerated,andnowtheymustbetested,manipulated,anddrawnviaFragmentShadersontotheframebufferintheformofpixels.
TipNotethat“FragmentShader”isthemoretechnicallyaccuratetermforPixelShaders.Fragmentsaregeneratedbytherasterizationstage,andonlytechnicallybecomepixelsoncethey’vebeenprocessedbytheShaderanddrawntotheFrameBuffer.
Thereareanumberofdifferentapproacheswecanusetodeterminewheretherootcauseofagraphicsrenderingissuelies:
ProfilingtheGPUwiththeProfilerExaminingindividualframeswiththeFrameDebuggerBruteForceCulling
http://freepdf-books.com
![Page 249: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/249.jpg)
GPUprofilingBecausegraphicsrenderinginvolvesboththeCPUandGPU,wemustexaminetheproblemusingboththeCPUUsageandGPUUsageareasoftheProfilerasthiscantelluswhichcomponentisworkinghardest.
Forexample,thefollowingscreenshotshowstheProfilerdataforaCPU-boundapplication.Thetestinvolvedcreatingthousandsofsimpleobjects,withnobatchingtechniquestakingplace.ThisresultedinanextremelylargeDrawCallcount(around15,000)fortheCPUtoprocess,butgivingtheGPUrelativelylittleworktododuetothesimplicityoftheobjectsbeingrendered:
ThisexampleshowsthattheCPU’s“rendering”taskisconsumingalargeamountofcycles(around30msperframe),whiletheGPUisonlyprocessingforlessthan16ms,indicatingthatthebottleneckresidesintheCPU.
Meanwhile,ProfilingaGPU-boundapplicationviatheProfilerisalittletrickier.Thistime,thetestinvolvescreatingasmallnumberofhighpolycountobjects(foralowDrawCallpervertexratio),withdozensofreal-timepointlightsandanexcessivelycomplexShaderwithatexture,normaltexture,heightmap,emissionmap,occlusionmap,andsoon,(forahighworkloadperpixelratio).
ThefollowingscreenshotshowsProfilerdatafortheexampleScenewhenitisruninastandaloneapplication:
http://freepdf-books.com
![Page 250: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/250.jpg)
Aswecansee,therenderingtaskoftheCPUUsageareamatchescloselywiththetotalrenderingcostsoftheGPUUsagearea.WecanalsoseethattheCPUandGPUtimecostsatthebottomoftheimagearerelativelysimilar(41.48msversus38.95ms).ThisisveryunintuitiveaswewouldexpecttheGPUtobeworkingmuchharderthantheCPU.
TipBeawarethattheCPU/GPUmillisecondcostvaluesarenotcalculatedorrevealedunlesstheappropriateUsageAreahasbeenaddedtotheProfilerwindow.
However,let’sseewhathappenswhenwetestthesameexactScenethroughtheEditor:
ThisisabetterrepresentationofwhatwewouldexpecttoseeinaGPU-boundapplication.WecanseehowtheCPUandGPUtimecostsatthebottomareclosertowhatwewouldexpecttosee(2.74msvs64.82ms).
However,thisdataishighlypolluted.ThespikesintheCPUandGPUUsageareasarethe
http://freepdf-books.com
![Page 251: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/251.jpg)
resultoftheProfilerWindowUIupdatingduringtesting,andtheoverheadcostofrunningthroughtheEditorisalsoartificiallyincreasingthetotalGPUtimecost.
Itisunclearwhatcausesthedatatobetreatedthisway,andthiscouldcertainlychangeinthefutureifenhancementsaremadetotheProfilerinfutureversionsofUnity,butitisusefultoknowthisdrawback.
NoteTryingtodeterminewhetherourapplicationistrulyGPU-boundisperhapstheonlygoodexcusetoperformaProfilertestthroughtheEditor.
http://freepdf-books.com
![Page 252: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/252.jpg)
TheFrameDebuggerAnewfeatureinUnity5istheFrameDebugger,adebuggingtoolthatcanrevealhowtheSceneisrenderedandpiecedtogether,oneDrawCallatatime.WecanclickthroughthelistofDrawCallsandobservehowtheSceneisrendereduptothatpointintime.ItalsoprovidesalotofusefuldetailsfortheselectedDrawCall,suchasthecurrentrendertarget(forexample,theshadowmap,thecameradepthtexture,themaincamera,orothercustomrendertargets),whattheDrawCalldid(drawingamesh,drawingastaticbatch,drawingdepthshadows,andsoon),andwhatsettingswereused(texturedata,vertexcolors,bakedlightmaps,directionallighting,andsoon).
ThefollowingscreenshotshowsaScenethatisonlybeingpartiallyrenderedduetothecurrentlyselectedDrawCallwithintheFrameDebugger.Notetheshadowsthatarevisiblefrombakedlightmapsthatwererenderedduringanearlierpassbeforetheobjectitselfisrendered:
IfweareboundbyDrawCalls,thenthistoolcanbeeffectiveinhelpingusfigureoutwhattheDrawCallsarebeingspenton,anddeterminewhetherthereareanyunnecessaryDrawCallsthatarenothavinganeffectonthescene.Thiscanhelpuscomeupwithwaystoreducethem,suchasremovingunnecessaryobjectsorbatchingthemsomehow.WecanalsousethistooltoobservehowmanyadditionalDrawCallsareconsumedbyrenderingfeatures,suchasshadows,transparentobjects,andmanymore.Thiscouldhelpus,whenwe’recreatingmultiplequalitylevelsforourgame,todecidewhatfeaturestoenable/disableunderthelow,medium,andhighqualitysettings.
http://freepdf-books.com
![Page 253: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/253.jpg)
BruteforcetestingIfwe’reporingoverourProfilingdata,andwe’restillnotsurewecandeterminethesourceoftheproblem,wecanalwaystrythebruteforcemethod:cullaspecificactivityfromtheSceneandseeifitresultsingreatlyincreasedperformance.Ifasmallchangeresultsinabigspeedimprovement,thenwehaveastrongclueaboutwherethebottlenecklies.There’snoharminthisapproachifweeliminateenoughunknownvariablestobesurethedataisleadingusintherightdirection.
Wewillcoverdifferentwaystobruteforcetestaparticularissueineachoftheupcomingsections.
http://freepdf-books.com
![Page 254: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/254.jpg)
CPU-boundIfourapplicationisCPU-bound,thenwewillobserveagenerallypoorFPSvaluewithintheCPUUsageareaoftheProfilerwindowduetotherenderingtask.However,ifVSyncisenabledthedatawilloftengetmuddiedupwithlargespikesrepresentingpausesastheCPUwaitsforthescreenrefreshratetocomearoundbeforepushingthecurrentframebuffer.So,weshouldmakesuretodisabletheVSyncblockintheCPUUsageareabeforedecidingtheCPUistheproblem.
Brute-forcingatestforCPU-boundingcanbeachievedbyreducingDrawCalls.Thisisalittleunintuitivesince,presumably,we’vealreadybeenreducingourDrawCallstoaminimumthroughtechniquessuchasStaticandDynamicBatching,Atlasing,andsoforth.Thiswouldmeanwehaveverylimitedscopeforreducingthemfurther.
Whatwecando,however,isdisabletheDraw-Call-savingfeaturessuchasbatchingandobserveifthesituationgetssignificantlyworsethanitalreadyis.Ifso,thenwehaveevidencethatwe’reeitheralready,orveryclosetobeing,CPU-bound.Atthispoint,weshouldseewhetherwecanre-enablethesefeaturesanddisablerenderingforafewchoiceobjects(preferablythosewithlowcomplexitytoreduceDrawCallswithoutover-simplifyingtherenderingofourscene).Ifthisresultsinasignificantperformanceimprovementthen,unlesswecanfindfurtheropportunitiesforbatchingandmeshcombining,wemaybefacedwiththeunfortunateoptionofremovingobjectsfromoursceneastheonlymeansofbecomingperformantagain.
TherearesomeadditionalopportunitiesforDrawCallreduction,includingOcclusionCulling,tweakingourLightingandShadowing,andmodifyingourShaders.Thesewillbeexplainedinthefollowingsections.
However,Unity’srenderingsystemcanbemultithreaded,dependingonthetargetedplatform,whichversionofUnitywe’rerunning,andvarioussettings,andthiscanaffecthowthegraphicssubsystemisbeingbottleneckedbytheCPU,andslightlychangesthedefinitionofwhatbeingCPU-boundmeans.
MultithreadedrenderingMultithreadedrenderingwasfirstintroducedinUnityv3.5inFebruary2012,andenabledbydefaultonmulticoresystemsthatcouldhandletheworkload;atthetime,thiswasonlyPC,Mac,andXbox360.Gradually,moredeviceswereaddedtothislist,andsinceUnityv5.0,allmajorplatformsnowenablemultithreadedrenderingbydefault(andpossiblysomebuildsofUnity4).
http://freepdf-books.com
![Page 255: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/255.jpg)
MobiledeviceswerealsostartingtofeaturemorepowerfulCPUsthatcouldsupportthisfeature.Androidmultithreadedrendering(introducedinUnityv4.3)canbeenabledthroughacheckboxunderPlatformSettings|OtherSettings|MultithreadedRendering.MultithreadedrenderingoniOScanbeenabledbyconfiguringtheapplicationtomakeuseoftheAppleMetalAPI(introducedinUnityv4.6.3),underPlayerSettings|OtherSettings|GraphicsAPI.
Whenmultithreadedrenderingisenabled,tasksthatmustgothroughtherenderingAPI(OpenGL,DirectX,orMetal),arehandedoverfromthemainthreadtoa“workerthread”.Theworkerthread’spurposeistoundertaketheheavyworkloadthatittakestopushrenderingcommandsthroughthegraphicsAPIanddriver,togettherenderinginstructionsintotheGPU’sCommandBuffer.ThiscansaveanenormousnumberofCPUcyclesforthemainthread,wheretheoverwhelmingmajorityofotherCPUtaskstakeplace.Thismeansthatwefreeupextracyclesforthemajorityoftheenginetoprocessphysics,scriptcode,andsoon.
Incidentally,themechanismbywhichthemainthreadnotifiestheworkerthreadoftasksoperatesinaverysimilarwaytotheCommandBufferthatexistsontheGPU,exceptthatthecommandsaremuchmorehigh-level,withinstructionslike“renderthisobject,withthisMaterial,usingthisShader”,or“drawNinstancesofthispieceofproceduralgeometry”,andsoon.ThisfeaturehasbeenexposedinUnity5toallowdeveloperstotakedirectcontroloftherenderingsubsystemfromC#code.ThiscustomizationisnotaspowerfulashavingdirectAPIaccess,butitisastepintherightdirectionforUnitydeveloperstoimplementuniquegraphicaleffects.
NoteConfusingly,theUnityAPInameforthisfeatureiscalled“CommandBuffer”,sobesurenottoconfuseitwiththeGPU’sCommandBuffer.
ChecktheUnitydocumentationonCommandBuffertomakeuseofthisfeature:http://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.html.
Gettingbacktothetaskathand,whenwediscussthetopicofbeingCPU-boundingraphicsrendering,weneedtokeepinmindwhetherornotthemultithreadedrendererisbeingused,sincetheactualrootcauseoftheproblemwillbeslightlydifferentdependingonwhetherthisfeatureisenabledornot.
Insingle-threadedrendering,whereallgraphicsAPIcallsarehandledbythemainthread,andinanidealworldwherebothcomponentsarerunningatmaximumcapacity,ourapplicationwouldbecomebottleneckedontheCPUwhen50percentormoreofthetimeperframeisspenthandlinggraphicsAPIcalls.However,resolvingthesebottleneckscanbeaccomplishedbyfreeingupworkfromthemainthread.Forexample,wemightfindthatgreatlyreducingtheamountofworktakingplaceinourAIsubsystemwillimproveourrenderingsignificantlybecausewe’vefreedupmoreCPUcyclestohandlethegraphicsAPIcalls.
But,whenmultithreadedrenderingistakingplace,thistaskispushedontotheworkerthread,whichmeansthesamethreadisn’tbeingaskedtomanagebothengineworkand
http://freepdf-books.com
![Page 256: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/256.jpg)
graphicsAPIcallsatthesametime.Theseprocessesaremostlyindependent,andeventhoughadditionalworkmuststilltakeplaceinthemainthreadtosendinstructionstotheworkerthreadinthefirstplace(viatheinternalCommandBuffersystem),itismostlynegligible.Thismeansthatreducingtheworkloadinthemainthreadwillhavelittle-to-noeffectonrenderingperformance.
NoteNotethatbeingGPU-boundisthesameregardlessofwhethermultithreadedrenderingistakingplace.
GPUSkinningWhilewe’reonthesubjectofCPU-bounding,onetaskthatcanhelpreduceCPUworkload,attheexpenseofadditionalGPUworkload,isGPUSkinning.Skinningistheprocesswheremeshverticesaretransformedbasedonthecurrentlocationoftheiranimatedbones.Theanimationsystem,workingontheCPU,onlytransformsthebones,butanotherstepintherenderingprocessmusttakecareofthevertextransformationstoplacetheverticesaroundthosebones,performingaweightedaverageoverthebonesconnectedtothosevertices.
ThisvertexprocessingtaskcaneithertakeplaceontheCPUorwithinthefrontendoftheGPU,dependingonwhethertheGPUSkinningoptionisenabled.ThisfeaturecanbetoggledunderEdit|ProjectSettings|PlayerSettings|OtherSettings|GPUSkinning.
http://freepdf-books.com
![Page 257: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/257.jpg)
http://freepdf-books.com
![Page 258: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/258.jpg)
FrontendbottlenecksWehavealreadycoveredsometechniquesonmeshoptimizationinChapter4,KickstartYourArt,whichcanhelpreduceourmesh’svertexattributes.Asaquickreminder,itisnotuncommontouseameshthatcontainsalotofunnecessaryUVandNormalvectordata,soourmeshesshouldbedouble-checkedforthiskindofsuperfluousfluff.WeshouldalsoletUnityoptimizethestructureforus,whichminimizescachemissesasvertexdataisreadwithinthefrontend.
WewillalsolearnsomeusefulShaderoptimizationtechniquesshortly,whenwebegintodiscussbackendoptimizations,sincemanyoptimizationtechniquesapplytobothFragmentandVertexShaders.
Theonlyattackvectorlefttocoverisfindingwaystoreduceactualvertexcounts.Theobvioussolutionsaresimplificationandculling;eitherhavetheartteamreplaceproblematicmesheswithlowerpolycountversions,and/orremovesomeobjectsfromthescenetoreducetheoverallpolygoncount.Iftheseapproacheshavealreadybeenexplored,thenthelastapproachwecantakeistofindsomekindofmiddlegroundbetweenthetwo.
http://freepdf-books.com
![Page 259: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/259.jpg)
LevelOfDetailSinceitcanbedifficulttotellthedifferencebetweenahighqualitydistanceobjectandalowqualityone,thereisverylittlereasontorenderthehighqualityversion.So,whynotdynamicallyreplacedistantobjectswithsomethingmoresimplified?
LevelOfDetail(LOD),isabroadtermreferringtothedynamicreplacementoffeaturesbasedontheirdistanceorformfactorrelativetothecamera.Themostcommonimplementationismesh-basedLOD:dynamicallyreplacingameshwithlowerandlowerdetailedversionsasthecameragetsfartherandfartheraway.Anotherexamplemightbereplacinganimatedcharacterswithversionsfeaturingfewerbones,orlesssamplingfordistantobjects,inordertoreduceanimationworkload.
TipThebuilt-inLODfeatureisavailableintheUnity4ProEditionandalleditionsofUnity5.However,itisentirelypossibletoimplementitviaScriptcodeinUnity4FreeEditionifdesired.
MakinguseofLODcanbeachievedbyplacingmultipleobjectsintheSceneandmakingthemchildrenofaGameObjectwithanattachedLODGroupcomponent.TheLODGroup’spurposeistogenerateaboundingboxfromtheseobjects,anddecidewhichobjectshouldberenderedbasedonthesizeoftheboundingboxwithinthecamera’sfieldofview.Iftheobject’sboundingboxconsumesalargeareaofthecurrentview,thenitwillenablethemesh(es)assignedtolowerLODgroups,andiftheboundingboxisverysmall,itwillreplacethemesh(es)withthosefromhigherLODgroups.Ifthemeshistoofaraway,itcanbeconfiguredtohideallchildobjects.So,withthepropersetup,wecanhaveUnityreplacemesheswithsimpleralternatives,orcullthementirely,whicheasestheburdenontherenderingprocess.
NoteChecktheUnitydocumentationformoredetailedinformationontheLODfeature:http://docs.unity3d.com/Manual/LevelOfDetail.html.
Thisfeaturecancostusalargeamountofdevelopmenttimetofullyimplement;artistsmustgeneratelowerpolygoncountversionsofthesameobject,andleveldesignersmustgenerateLODgroups,configurethem,andtestthemtoensuretheydon’tcausejarringtransitionsasthecameramovescloserorfartheraway.ItalsocostsusinmemoryandruntimeCPU;thealternativemeshesneedtobekeptinmemory,andtheLODGroupcomponentmustroutinelytestwhetherthecamerahasmovedtoanewpositionthatwarrantsachangeinLODlevel.
Inthiseraofgraphicscardcapabilities,vertexprocessingisoftentheleastofourconcerns.CombinedwiththeadditionalsacrificesneededforLODtofunction,developersshouldavoidpreoptimizingbyautomaticallyassumingLODwillhelpthem.Excessiveuseofthefeaturewillleadtoburdeningotherpartsofourapplication’sperformance,andchewuppreciousdevelopmenttime,allforthesakeofparanoia.Ifithasn’tbeenproventobeaproblem,thenit’sprobablynotaproblem!
http://freepdf-books.com
![Page 260: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/260.jpg)
Scenesthatfeaturelarge,expansiveviewsoftheworld,andlotsofcameramovement,shouldconsiderimplementingthistechniqueveryearly,astheaddeddistanceandmassivenumberofvisibleobjectswillexacerbatethevertexcountenormously.Scenesthatarealwaysindoors,orfeatureacamerawithaviewpointlookingdownattheworld(real-timestrategyandMOBAgames,forexample)shouldprobablysteerclearofimplementingLODfromthebeginning.Gamessomewherebetweenthetwoshouldavoidituntilnecessary.Italldependsonhowmanyverticesareexpectedtobevisibleatanygiventimeandhowmuchvariabilityincameradistancetherewillbe.
TipNotethatsomegamedevelopmentmiddlewarecompaniesofferthird-partytoolsforautomatedLODmeshgeneration.Thesemightbeworthinvestigatingtocomparetheireaseofuseversusqualitylossversuscosteffectiveness.
http://freepdf-books.com
![Page 261: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/261.jpg)
DisableGPUSkinningAspreviouslymentioned,wecouldenableGPUSkinningtoreducetheburdenonaCPU-boundapplication,butenablingthisfeaturewillpushthesameworkloadintothefrontendoftheGPU.SinceSkinningisoneofthose“embarrassinglyparallel”processesthatfitswellwiththeGPU’sparallelarchitecture,itisoftenagoodideatoperformthetaskontheGPU.Butthistaskcanchewupprecioustimeinthefrontendpreparingtheverticesforfragmentgeneration,sodisablingitisanotheroptionwecanexploreifwe’rebottleneckedinthisarea.Again,thisfeaturecanbetoggledunderEdit|ProjectSettings|PlayerSettings|OtherSettings|GPUSkinning.
TipGPUSkinningisavailableinUnity4ProEdition,andalleditionsofUnity5.
http://freepdf-books.com
![Page 262: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/262.jpg)
ReducetessellationThereisonelasttaskthattakesplaceinthefrontendprocessandthatweneedtoconsider:tessellation.TessellationthroughGeometryShaderscanbealotoffun,asitisarelativelyunderusedtechniquethatcanreallymakeourgraphicaleffectsstandoutfromthecrowdofgamesthatonlyusethemostcommoneffects.But,itcancontributeenormouslytotheamountofprocessingworktakingplaceinthefrontend.
Therearenosimpletrickswecanexploittoimprovetessellation,besidesimprovingourtessellationalgorithms,oreasingtheburdencausedbyotherfrontendtaskstogiveourtessellationtasksmoreroomtobreathe.Eitherway,ifwehaveabottleneckinthefrontendandaremakinguseoftessellationtechniques,weshoulddouble-checkthattheyarenotconsumingthelion’sshareofthefrontend’sbudget.
http://freepdf-books.com
![Page 263: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/263.jpg)
http://freepdf-books.com
![Page 264: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/264.jpg)
BackendbottlenecksThebackendisthemoreinterestingpartoftheGPUpipeline,asmanymoregraphicaleffectstakeplaceduringthisstage.Consequently,itisthestagethatissignificantlymorelikelytosufferfrombottlenecks.
Therearetwobruteforcetestswecanattempt:
ReduceresolutionReducetexturequality
Thesechangeswilleasetheworkloadduringtwoimportantstagesatthebackendofthepipeline:fillrateandmemorybandwidth,respectively.Fillratetendstobethemostcommonsourceofbottlenecksinthemoderneraofgraphicsrendering,sowewillcoveritfirst.
http://freepdf-books.com
![Page 265: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/265.jpg)
FillrateByreducingscreenresolution,wehaveaskedtherasterizationsystemtogeneratesignificantlyfewerfragmentsandtransposethemoverasmallercanvasofpixels.Thiswillreducethefillrateconsumptionoftheapplication,givingakeypartoftherenderingpipelinesomeadditionalbreathingroom.Ergo,ifperformancesuddenlyimproveswithascreenresolutionreduction,thenfillrateshouldbeourprimaryconcern.
FillrateisaverybroadtermreferringtothespeedatwhichtheGPUcandrawfragments.But,thisonlyincludesfragmentsthathavesurvivedallofthevariousconditionaltestswemighthaveenabledwithinthegivenShader.Afragmentismerelya“potentialpixel,”andifitfailsanyoftheenabledtests,thenitisimmediatelydiscarded.Thiscanbeanenormousperformance-saverasthepipelinecanskipthecostlydrawingstepandbeginworkonthenextfragmentinstead.
OnesuchexampleisZ-testing,whichcheckswhetherthefragmentfromacloserobjecthasalreadybeendrawntothesamepixelalready.Ifso,thenthecurrentfragmentisdiscarded.Ifnot,thenthefragmentispushedthroughtheFragmentShaderanddrawnoverthetargetpixel,whichconsumesexactlyonedrawfromourfillrate.Nowimaginemultiplyingthisprocessbythousandsofoverlappingobjects,eachgeneratinghundredsorthousandsofpossiblefragments,forhighscreenresolutionscausingmillions,orbillions,offragmentstobegeneratedeachandeveryframe.Itshouldbefairlyobviousthatskippingasmanyofthesedrawsaswecanwillresultinbigrenderingcostsavings.
Graphicscardmanufacturerstypicallyadvertiseaparticularfillrateasafeatureofthecard,usuallyintheformofgigapixelspersecond,butthisisabitofamisnomer,asitwouldbemoreaccuratetocallitgigafragmentspersecond;howeverthisargumentismostlyacademic.Eitherway,largervaluestellusthatthedevicecanpotentiallypushmorefragmentsthroughthepipeline,sowithabudgetof30GPix/sandatargetframerateof60Hz,wecanaffordtoprocess30,000,000,000/60=500millionfragmentsperframebeforebeingbottleneckedonfillrate.Witharesolutionof2560x1440,andabest-casescenariowhereeachpixelisonlydrawnoveronce,thenwecouldtheoreticallydrawtheentiresceneabout125timeswithoutanynoticeableproblems.
Sadly,thisisnotaperfectworld,andunlesswetakesignificantstepstoavoidit,wewillalwaysendupwithsomeamountofredrawoverthesamepixelsduetotheorderinwhichobjectsarerendered.Thisisknownasoverdraw,anditcanbeverycostlyifwe’renotcareful.
TipThereasonthatresolutionisagoodattackvectortocheckforfillrateboundingisthatitisamultiplier.Areductionfromaresolutionof2560x1440to800x600isanimprovementfactorofabouteight,whichcouldreducefillratecostsenoughtomaketheapplicationperformwellagain.
OverdrawDetermininghowmuchoverdrawwehavecanberepresentedvisuallybyrenderingall
http://freepdf-books.com
![Page 266: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/266.jpg)
objectswithadditivealphablendingandaverytransparentflatcolor.Areasofhighoverdrawwillshowupmorebrightlyasthesamepixelisdrawnoverwithadditiveblendingmultipletimes.ThisispreciselyhowtheSceneview’sOverdrawshadingmoderevealshowmuchoverdrawoursceneissuffering.
Thefollowingscreenshotshowsascenewithseveralthousandboxesdrawnnormally,anddrawnusingtheSceneview’sOverdrawshadingmode:
Attheendoftheday,fillrateisprovidedasameansofgaugingthebest-casebehavior.Inotherwords,it’sprimarilyamarketingtermandmostlytheoretical.But,thetechnicalsideoftheindustryhasadoptedthetermasawayofdescribingthebackendofthepipeline:thestagewherefragmentdataisfunneledthroughourShadersanddrawntothescreen.
Ifeveryfragmentrequiredanabsoluteminimumlevelofprocessing(suchasaShaderthatreturnedaconstantcolor),thenwemightgetclosetothattheoreticalmaximum.TheGPUisacomplexbeast,however,andthingsareneversosimple.Thenatureofthedevicemeansitworksbestwhengivenmanysmalltaskstoperform.But,ifthetasksgettoolarge,thenfillrateislostduetothebackendnotbeingabletopushthroughenoughfragmentsintimeandtherestofthepipelineisleftwaitingfortaskstodo.
Thereareseveralmorefeaturesthatcanpotentiallyconsumeourtheoreticalfillratemaximum,includingbutnotlimitedtoalphatesting,alphablending,texturesampling,theamountoffragmentdatabeingpulledthroughourShaders,andeventhecolorformatofthetargetrendertexture(thefinalFrameBufferinmostcases).Thebadnewsisthatthisgivesusalotofsubsectionstocover,andalotofwaystobreaktheprocess,butthegoodnewsisitgivesusalotofavenuestoexploretoimproveourfillrateusage.
OcclusionCullingOneofthebestwaystoreduceoverdrawistomakeuseofUnity’sOcclusionCullingsystem.ThesystemworksbypartitioningScenespaceintoaseriesofcellsandflyingthroughtheworldwithavirtualcameramakingnoteofwhichcellsareinvisiblefrom
http://freepdf-books.com
![Page 267: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/267.jpg)
othercells(areoccluded)basedonthesizeandpositionoftheobjectspresent.
NotethatthisisdifferenttothetechniqueofFrustumCulling,whichcullsobjectsnotvisiblefromthecurrentcameraview.Thisfeatureisalwaysactiveinallversions,andobjectsculledbythisprocessareautomaticallyignoredbytheOcclusionCullingsystem.
TipOcclusionCullingisavailableintheUnity4ProEditionandalleditionsofUnity5.
OcclusionCullingdatacanonlybegeneratedforobjectsproperlylabeledOccluderStaticandOccludeeStaticundertheStaticFlagsdropdown.OccluderStaticisthegeneralsettingforstaticobjectswherewewantittohideotherobjects,andbehiddenbylargeobjectsinitsway.OccludeeStaticisaspecialcasefortransparentobjectsthatallowsobjectsbehindthemtoberendered,butwewantthemtobehiddenifsomethinglargeblockstheirvisibility.
Naturally,becauseoneofthestaticflagsmustbeenabledforOcclusionCulling,thisfeaturewillnotworkfordynamicobjects.
ThefollowingscreenshotshowshoweffectiveOcclusionCullingcanbeatreducingthenumberofvisibleobjectsinourScene:
http://freepdf-books.com
![Page 268: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/268.jpg)
Thisfeaturewillcostusinbothapplicationfootprintandincursomeruntimecosts.ItwillcostRAMtokeeptheOcclusionCullingdatastructureinmemory,andtherewillbeaCPUprocessingcosttodeterminewhichobjectsarebeingoccludedineachframe.
TheOcclusionCullingdatastructuremustbeproperlyconfiguredtocreatecellsoftheappropriatesizeforourScene,andthesmallerthecells,thelongerittakestogeneratethedatastructure.But,ifitisconfiguredcorrectlyfortheScene,OcclusionCullingcanprovidebothfillratesavingsthroughreducedoverdraw,andDrawCallsavingsbycullingnon-visibleobjects.
ShaderoptimizationShaderscanbeasignificantfillrateconsumer,dependingontheircomplexity,howmuchtexturesamplingtakesplace,howmanymathematicalfunctionsareused,andsoon.Shadersdonotdirectlyconsumefillrate,butdosoindirectlybecausetheGPUmustcalculateorfetchdatafrommemoryduringShaderprocessing.TheGPU’sparallelnaturemeansanybottleneckinathreadwilllimithowmanyfragmentscanbepushedintothethreadatalaterdate,butparallelizingthetask(sharingsmallpiecesofthejobbetween
http://freepdf-books.com
![Page 269: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/269.jpg)
severalagents)providesanetgainoverserialprocessing(oneagenthandlingeachtaskoneafteranother).
Theclassicexampleisavehicleassemblyline.Acompletevehiclerequiresmultiplestagesofmanufacturetocomplete.Thecriticalpathtocompletionmightinvolvefivesteps:stamping,welding,painting,assembly,andinspection,andeachstepiscompletedbyasingleteam.Foranygivenvehicle,nostagecanbeginbeforethepreviousoneisfinished,butwhateverteamhandledthestampingforthelastvehiclecanbeginstampingforthenextvehicleassoonasithasfinished.Thisorganizationallowseachteamtobecomemastersoftheirparticulardomain,ratherthantryingtospreadtheirknowledgetoothin,whichwouldlikelyresultinlessconsistentqualityinthebatchofvehicles.
Wecandoubletheoveralloutputbydoublingthenumberofteams,butifanyteamgetsblocked,thenprecioustimeislostforanygivenvehicle,aswellasallfuturevehiclesthatwouldpassthroughthesameteam.Ifthesedelaysarerare,thentheycanbenegligibleinthegrandscheme,butifnot,andonestagetakesseveralminuteslongerthannormaleachandeverytimeitmustcompletethetask,thenitcanbecomeabottleneckthatthreatensthereleaseoftheentirebatch.
TheGPUparallelprocessorsworkinasimilarway:eachprocessorthreadisanassemblyline,eachprocessingstageisateam,andeachfragmentisavehicle.Ifthethreadspendsalongtimeprocessingasinglestage,thentimeislostoneachfragment.Thisdelaywillmultiplysuchthatallfuturefragmentscomingthroughthesamethreadwillbedelayed.Thisisabitofanoversimplification,butitoftenhelpstopaintapictureofhowpoorlyoptimizedShadercodecanchewupourfillrate,andhowsmallimprovementsinShaderoptimizationprovidebigbenefitsinbackendperformance.
Shaderprogrammingandoptimizationhavebecomeaverynicheareaofgamedevelopment.Theirabstractandhighly-specializednaturerequiresaverydifferentkindofthinkingtogenerateShadercodecomparedtogameplayandenginecode.Theyoftenfeaturemathematicaltricksandback-doormechanismsforpullingdataintotheShader,suchasprecomputingvaluesintexturefiles.Becauseofthis,andtheimportanceofoptimization,Shaderstendtobeverydifficulttoreadandreverse-engineer.
Consequently,manydevelopersrelyonprewrittenShaders,orvisualShadercreationtoolsfromtheAssetStoresuchasShaderForgeorShaderSandwich.ThissimplifiestheactofinitialShadercodegeneration,butmightnotresultinthemostefficientformofShaders.Ifwe’rerelyingonpre-writtenShadersortools,wemightfinditworthwhiletoperformsomeoptimizationpassesoverthemusingsometried-and-truetechniques.So,let’sfocusonsomeeasilyreachablewaysofoptimizingourShaders.
ConsiderusingShadersintendedformobileplatformsThebuilt-inmobileShadersinUnitydonothaveanyspecificrestrictionsthatforcethemtoonlybeusedonmobiledevices.Theyaresimplyoptimizedforminimumresourceusage(andtendtofeaturesomeoftheotheroptimizationslistedinthissection).
DesktopapplicationsareperfectlycapableofusingtheseShaders,buttheytendtofeaturealossofgraphicalquality.Itonlybecomesaquestionofwhetherthelossofgraphical
http://freepdf-books.com
![Page 270: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/270.jpg)
qualityisacceptable.So,considerdoingsometestingwiththemobileequivalentsofcommonShaderstoseewhethertheyareagoodfitforyourgame.
Usesmalldatatypes
GPUscancalculatewithsmallerdatatypesmorequicklythanlargertypes(particularlyonmobileplatforms!),sothefirsttweakwecanattemptisreplacingourfloatdatatypes(32-bit,floatingpoint)withsmallerversionssuchashalf(16-bit,floatingpoint),orevenfixed(12-bit,fixedpoint).
NoteThesizeofthedatatypeslistedabovewillvarydependingonwhatfloatingpointformatsthetargetplatformprefers.Thesizeslistedarethemostcommon.Theimportanceforoptimizationisintherelativesizebetweenformats.
Colorvaluesaregoodcandidatesforprecisionreduction,aswecanoftengetawaywithlessprecisecolorvalueswithoutanynoticeablelossincoloration.However,theeffectsofreducingprecisioncanbeveryunpredictableforgraphicalcalculations.So,changessuchasthesecanrequiresometestingtoverifywhetherthereducedprecisioniscostingtoomuchgraphicalfidelity.
NotethattheeffectsofthesetweakscanvaryenormouslybetweenoneGPUarchitectureandanother(forexample,AMDversusNvidiaversusIntel),andevenGPUbrandsfromthesamemanufacturer.Insomecases,wecanmakesomedecentperformancegainsforatrivialamountofeffort.Inothercases,wemightseenobenefitatall.
Avoidchangingprecisionwhileswizzling
SwizzlingistheShaderprogrammingtechniqueofcreatinganewvector(anarrayofvalues)fromanexistingvectorbylistingthecomponentsintheorderinwhichwewishtocopythemintothenewstructure.Herearesomeexamplesofswizzling:
float4input=float4(1.0,2.0,3.0,4.0);//initialtestvalue
float2val1=input.yz;//swizzletwocomponents
float3val2=input.zyx;//swizzlethreecomponentsinadifferentorder
float4val3=input.yyy;//swizzlethesamecomponentmultipletimes
floatsclr=input.w;
float3val4=sclr.xxx//swizzleascalarmultipletimes
Wecanuseboththexyzwandrgbarepresentationstorefertothesamecomponents,sequentially.Itdoesnotmatterwhetheritisacolororvector;theyjustmaketheShadercodeeasiertoread.Wecanalsolistcomponentsinanyorderweliketofillinthedesireddata,repeatingthemifnecessary.
ConvertingfromoneprecisiontypetoanotherinaShadercanbeacostlyoperation,butconvertingtheprecisiontypewhilesimultaneouslyswizzlingcanbeparticularlypainful.Ifwehavemathematicaloperationsthatrelyonbeingswizzledintodifferentprecision
http://freepdf-books.com
![Page 271: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/271.jpg)
types,itwouldbewiserifwesimplyabsorbedthehigh-precisioncostfromtheverybeginning,orreducedprecisionacrosstheboardtoavoidtheneedforchangesinprecision.
UseGPU-optimizedhelperfunctions
TheShadercompileroftenperformsagoodjobofreducingmathematicalcalculationsdowntoanoptimizedversionfortheGPU,butcompiledcustomcodeisunlikelytobeaseffectiveasboththeCglibrary’sbuilt-inhelperfunctionsandtheadditionalhelpersprovidedbytheUnityCgincludedfiles.IfweareusingShadersthatincludecustomfunctioncode,perhapswecanfindanequivalenthelperfunctionwithintheCgorUnitylibrariesthatcandoabetterjobthanourcustomcodecan.
TheseextraincludefilescanbeaddedtoourShaderwithintheCGPROGRAMblocklikeso:
CGPROGRAM
//otherincludes
#include"UnityCG.cginc"
//Shadercodehere
ENDCG
ExampleCglibraryfunctionstouseareabs()forabsolutevalues,lerp()forlinearinterpolation,mul()formultiplyingmatrices,andstep()forstepfunctionality.UsefulUnityCG.cgincfunctionsincludeWorldSpaceViewDir()forcalculatingthedirectiontowardsthecamera,andLuminance()forconvertingacolortograyscale.
NoteCheckthefollowingURLforafulllistofCgstandardlibraryfunctions:http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html.
ChecktheUnitydocumentationforacompleteandup-to-datelistofpossibleincludefilesandtheiraccompanyinghelperfunctions:http://docs.unity3d.com/Manual/SL-BuiltinIncludes.html.
Disableunnecessaryfeatures
PerhapswecanmakesavingsbysimplydisablingShaderfeaturesthataren’tvital.DoestheShaderreallyneedmultiplepasses,transparency,Z-writing,alpha-testing,and/oralphablending?Willtweakingthesesettingsorremovingthesefeaturesgiveusagoodapproximationofourdesiredeffectwithoutlosingtoomuchgraphicalfidelity?Makingsuchchangesisagoodwayofmakingfillratecostsavings.
Removeunnecessaryinputdata
SometimestheprocessofwritingaShaderinvolvesalotofbackandforthexperimentationineditingcodeandviewingitintheScene.ThetypicalresultofthisisthatinputdatathatwasneededwhentheShaderwasgoingthroughearlydevelopmentisnowsurplusfluffoncethedesiredeffecthasbeenobtained,andit’seasytoforgetwhatchangesweremadewhen/iftheprocessdragsonforalongtime.But,theseredundantdatavaluescancosttheGPUvaluabletimeastheymustbefetchedfrommemoryeveniftheyarenotexplicitlyusedbytheShader.So,weshoulddoublecheckourShaderstoensure
http://freepdf-books.com
![Page 272: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/272.jpg)
alloftheirinputgeometry,vertex,andfragmentdataisactuallybeingused.
Onlyexposenecessaryvariables
ExposingunnecessaryvariablesfromourShadertotheaccompanyingMaterial(s)canbecostlyastheGPUcan’tassumethesevaluesareconstant.ThismeanstheShadercodecannotbecompiledintoamoreoptimizedform.ThisdatamustbepushedfromtheCPUwitheverypasssincetheycanbemodifiedatanytimethroughtheMaterial’smethodssuchasSetColor(),SetFloat(),andsoon.Ifwefindthat,towardstheendoftheproject,wealwaysusethesamevalueforthesevariables,thentheycanbereplacedwithaconstantintheShadertoremovesuchexcessruntimeworkload.Theonlycostisobfuscatingwhatcouldbecriticalgraphicaleffectparameters,sothisshouldbedoneverylateintheprocess.
Reducemathematicalcomplexity
Complicatedmathematicscanseverelybottlenecktherenderingprocess,soweshoulddowhateverwecantolimitthedamage.ComplexmathematicalfunctionscouldbereplacedwithatexturethatisfedintotheShaderandprovidesapre-generatedtableforruntimelookup.Wemaynotseeanyimprovementwithfunctionssuchassinandcos,sincethey’vebeenheavilyoptimizedtomakeuseofGPUarchitecture,butcomplexmethodssuchaspow,exp,log,andothercustommathematicalprocessescanonlybeoptimizedsomuch,andwouldbegoodcandidatesforsimplification.Thisisassumingweonlyneedoneortwoinputvalues,whicharerepresentedthroughtheXandYcoordinatesofthetexture,andmathematicalaccuracyisn’tofparamountimportance.
Thiswillcostusadditionalgraphicsmemorytostorethetextureatruntime(moreonthislater),butiftheShaderisalreadyreceivingatexture(whichtheyareinmostcases)andthealphachannelisnotbeingused,thenwecouldsneakthedatainthroughthetexture’salphachannel,costingusliterallynoperformance,andtherestoftheShadercodeandgraphicssystemwouldbenone-the-wiser.Thiswillinvolvethecustomizationofartassetstoincludesuchdatainanyunusedcolorchannel(s),requiringcoordinationbetweenprogrammersandartists,butisaverygoodwayofsavingShaderprocessingcostswithnoruntimesacrifices.
Infact,MaterialpropertiesandtexturesarebothexcellententrypointsforpushingworkfromtheShader(theGPU)ontotheCPU.Ifacomplexcalculationdoesnotneedtovaryonaperpixelbasis,thenwecouldexposethevalueasapropertyintheMaterial,andmodifyitasneeded(acceptingtheoverheadcostofdoingsofromtheprevioussectionOnlyexposenecessaryvariables).Alternatively,iftheresultvariesperpixel,anddoesnotneedtochangeoften,thenwecouldgenerateatexturefilefromscriptcode,containingtheresultsofthecalculationsintheRGBAvalues,andpullingthetextureintotheShader.Lotsofopportunitiesarisewhenweignoretheconventionalapplicationofsuchsystems,andremembertothinkofthemasjustrawdatabeingtransferredaround.
Reducetexturelookups
Whilewe’reonthesubjectoftexturelookups,theyarenottrivialtasksfortheGPUtoprocessandtheyhavetheirownoverheadcosts.Theyarethemostcommoncauseof
http://freepdf-books.com
![Page 273: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/273.jpg)
memoryaccessproblemswithintheGPU,especiallyifaShaderisperformingsamplesacrossmultipletextures,orevenmultiplesamplesacrossasingletexture,astheywilllikelyinflictcachemissesinmemory.SuchsituationsshouldbesimplifiedasmuchaspossibletoavoidsevereGPUmemorybottlenecking.
Evenworse,samplingatextureinarandomorderwouldlikelyresultinsomeverycostlycachemissesfortheGPUtosufferthrough,soifthisisbeingdone,thenthetextureshouldbereorderedsothatitcanbesampledinamoresequentialorder.
Avoidconditionalstatements
InmoderndayCPUarchitecture,conditionalstatementsundergoalotofcleverpredictivetechniquestomakeuseofinstruction-levelparallelism.ThisisafeaturewheretheCPUattemptstopredictwhichdirectionaconditionalstatementwillgoinbeforeithasactuallybeenresolved,andspeculativelybeginsprocessingthemostlikelyresultoftheconditionalusinganyfreecomponentsthataren’tbeingusedtoresolvetheconditional(fetchingsomedatafrommemory,copyingsomefloatsintounusedregisters,andsoon).Ifitturnsoutthatthedecisioniswrong,thenthecurrentresultisdiscardedandtheproperpathistakeninstead.
Solongasthecostofspeculativeprocessinganddiscardingfalseresultsislessthanthetimespentwaitingtodecidethecorrectpath,anditisrightmoreoftenthanitiswrong,thenthisisanetgainfortheCPU’sspeed.
However,thisfeatureisnotpossibleonGPUarchitecturebecauseofitsparallelnature.TheGPU’scoresaretypicallymanagedbysomehigher-levelconstructthatinstructsallcoresunderitscommandtoperformthesamemachine-code-levelinstructionsimultaneously.So,iftheFragmentShaderrequiresafloattobemultipliedby2,thentheprocesswillbeginbyhavingallcorescopydataintotheappropriateregistersinonecoordinatedstep.Onlywhenallcoreshavefinishedcopyingtotheregisterswillthecoresbeinstructedtobeginthesecondstep:multiplyingallregistersby2.
Thus,whenthissystemstumblesintoaconditionalstatement,itcannotresolvethetwostatementsindependently.Itmustdeterminehowmanyofitschildcoreswillgodowneachpathoftheconditional,grabthelistofrequiredmachinecodeinstructionsforonepath,resolvethemforallcorestakingthatpath,andrepeatforeachpathuntilallpossiblepathshavebeenprocessed.So,foranif-elsestatement(twopossibilities),itwilltellonegroupofcorestoprocessthe“true”path,thenasktheremainingcorestoprocessthe“false”path.Unlesseverycoretakesthesamepath,itmustprocessbothpathseverytime.
So,weshouldavoidbranchingandconditionalstatementsinourShadercode.Ofcourse,thisdependsonhowessentialtheconditionalistoachievingthegraphicaleffectwedesire.But,iftheconditionalisnotdependentonperpixelbehavior,thenwewouldoftenbebetteroffabsorbingthecostofunnecessarymathematicsthaninflictingabranchingcostontheGPU.Forexample,wemightbecheckingwhetheravalueisnon-zerobeforeusingitinacalculation,orcomparingagainstsomeglobalflagintheMaterialbeforetakingoneactionoranother.Bothofthesecaseswouldbegoodcandidatesforoptimizationbyremovingtheconditionalcheck.
http://freepdf-books.com
![Page 274: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/274.jpg)
Reducedatadependencies
ThecompilerwilltryitsbesttooptimizeourShadercodeintothemoreGPU-friendlylow-levellanguagesothatitisnotwaitingondatatobefetchedwhenitcouldbeprocessingsomeothertask.Forexample,thefollowingpoorly-optimizedcode,couldbewritteninourShader:
floatsum=input.color1.r;
sum=sum+input.color2.g;
sum=sum+input.color3.b;
sum=sum+input.color4.a;
floatresult=calculateSomething(sum);
IfwewereabletoforcetheShadercompilertocompilethiscodeintomachinecodeinstructionsasitiswritten,thenthiscodehasadatadependencysuchthateachcalculationcannotbeginuntilthelastfinishesduetothedependencyonthesumvariable.But,suchsituationsareoftendetectedbytheShadercompilerandoptimizedintoaversionthatusesinstruction-levelparallelism(thecodeshownnextisthehigh-levelcodeequivalentoftheresultingmachinecode):
floatsum1,sum2,sum3,sum4;
sum1=input.color1.r;
sum2=input.color2.g;
sum3=input.color3.b
sum4=input.color4.a;
floatsum=sum1+sum2+sum3+sum4;
floatresult=CalculateSomething(sum);
Inthiscase,thecompilerwouldrecognizethatitcanfetchthefourvaluesfrommemoryinparallelandcompletethesummationonceallfourhavebeenfetchedindependentlyviathread-levelparallelism.Thiscansavealotoftime,relativetoperformingthefourfetchesoneafteranother.
However,longchainsofdatadependencycanabsolutelymurderShaderperformance.IfwecreateastrongdatadependencyinourShader’ssourcecode,thenithasbeengivennofreedomtomakesuchoptimizations.Forexample,thefollowingdatadependencywouldbepainfulonperformance,asonestepcannotbecompletedwithoutwaitingonanothertofetchdataandperformingtheappropriatecalculation.
float4val1=tex2D(_tex1,input.texcoord.xy);
float4val2=tex2D(_tex2,val1.yz);
float4val3=tex2D(_tex3,val2.zw);
Strongdatadependenciessuchastheseshouldbeavoidedwheneverpossible.
SurfaceShaders
Ifwe’reusingUnity’sSurfaceShaders,whichareawayforUnitydeveloperstogettogripswithShaderprogramminginamoresimplifiedfashion,thentheUnityEnginetakescareofconvertingourSurfaceShadercodeforus,abstractingawaysomeoftheoptimizationopportunitieswehavejustcovered.However,itdoesprovidesomemiscellaneousvaluesthatcanbeusedasreplacements,whichreduceaccuracybut
http://freepdf-books.com
![Page 275: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/275.jpg)
simplifythemathematicsintheresultingcode.SurfaceShadersaredesignedtohandlethegeneralcasefairlyefficiently,butoptimizationisbestachievedwithapersonaltouch.
Theapproxviewattributewillapproximatetheviewdirection,savingcostlyoperations.halfasviewwillreducetheprecisionoftheviewvector,butbewareofitseffectonmathematicaloperationsinvolvingmultipleprecisiontypes.noforwardaddwilllimittheShadertoonlyconsideringasingledirectionallight,reducingDrawCallssincetheShaderwillrenderinonlyasinglepass,butreducinglightingcomplexity.Finally,noambientwilldisableambientlightingintheShader,removingsomeextramathematicaloperationsthatwemaynotneed.
UseShader-basedLOD
WecanforceUnitytorenderdistantobjectsusingsimplerShaders,whichcanbeaneffectivewayofsavingfillrate,particularlyifwe’redeployingourgameontomultipleplatformsorsupportingawiderangeofhardwarecapability.TheLODkeywordcanbeusedintheShadertosettheonscreensizefactorthattheShadersupports.IfthecurrentLODleveldoesnotmatchthisvalue,itwilldroptothenextfallbackShaderandsoonuntilitfindstheShaderthatsupportsthegivensizefactor.WecanalsochangeagivenShaderobject’sLODvalueatruntimeusingthemaximumLODproperty.
Thisfeatureissimilartothemesh-basedLODcoveredearlier,andusesthesameLODvaluesfordeterminingobjectformfactor,soitshouldbeconfiguredassuch.
http://freepdf-books.com
![Page 276: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/276.jpg)
MemorybandwidthAnothermajorcomponentofbackendprocessingandapotentialsourceofbottlenecksismemorybandwidth.MemorybandwidthisconsumedwheneveratexturemustbepulledfromasectionoftheGPU’smainvideomemory(alsoknownasVRAM).TheGPUcontainsmultiplecoresthateachhaveaccesstothesameareaofVRAM,buttheyalsoeachcontainamuchsmaller,localTextureCachethatstoresthecurrenttexture(s)theGPUhasbeenmostrecentlyworkingwith.ThisissimilarindesigntothemultitudeofCPUcachelevelsthatallowmemorytransferupanddownthechain,asaworkaroundforthefactthatfastermemorywill,invariably,bemoreexpensivetoproduce,andhencesmallerincapacitycomparedtoslowermemory.
WheneveraFragmentShaderrequestsasamplefromatexturethatisalreadywithinthecore’slocalTextureCache,thenitislightningfastandbarelyperceivable.But,ifatexturesamplerequestismade,thatdoesnotyetexistwithintheTextureCache,thenitmustbepulledinfromVRAMbeforeitcanbesampled.ThisfetchrequestriskscachemisseswithinVRAMasittriestofindtherelevanttexture.Thetransferitselfconsumesacertainamountofmemorybandwidth,specificallyanamountequaltothetotalsizeofthetexturefilestoredwithinVRAM(whichmaynotbetheexactsizeoftheoriginalfile,northesizeinRAM,duetoGPU-levelcompression).
It’sforthisreasonthat,ifwe’rebottleneckedonmemorybandwidth,thenperformingabruteforcetestbyreducingtexturequalitywouldsuddenlyresultinaperformanceimprovement.We’veshrunkthesizeofourtextures,easingtheburdenontheGPU’smemorybandwidth,allowingittofetchthenecessarytexturesmuchquicker.GloballyreducingtexturequalitycanbeachievedbygoingtoEdit|ProjectSettings|Quality|TextureQualityandsettingthevaluetoHalfRes,QuarterRes,orEighthRes.
Intheeventthatmemorybandwidthisbottlenecked,thentheGPUwillkeepfetchingthenecessarytexturefiles,buttheentireprocesswillbethrottledastheTextureCachewaitsforthedatatoappearbeforeprocessingthefragment.TheGPUwon’tbeabletopushdatabacktotheFrameBufferintimetoberenderedontothescreen,blockingthewholeprocessandculminatinginapoorframerate.
Ultimately,properusageofmemorybandwidthisabudgetingconcern.Forexample,withamemorybandwidthof96GB/secpercoreandatargetframerateof60framespersecond,thentheGPUcanaffordtopull96/60=1.6GBworthoftexturedataeveryframebeforebeingbottleneckedonmemorybandwidth.
TipMemorybandwidthisoftenlistedonapercorebasis,butsomeGPUmanufacturersmaytrytomisleadyoubymultiplyingmemorybandwidthbythenumberofcoresinordertolistabigger,butlesspracticalnumber.Becauseofthis,researchmaybenecessarytoconfirmthememorybandwidthlimitwehaveforthetargetGPUhardwareisgivenonapercorebasis.
Notethatthisvalueisnotthemaximumlimitonthetexturedatathatourgamecan
http://freepdf-books.com
![Page 277: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/277.jpg)
containintheproject,norinCPURAM,noteveninVRAM.Itisametricthatlimitshowmuchtextureswappingcanoccurduringoneframe.ThesametexturecouldbepulledbackandforthmultipletimesinasingleframedependingonhowmanyShadersneedtousethem,theorderthattheobjectsarerendered,andhowoftentexturesamplingmustoccur,sorenderingjustafewobjectscouldconsumewholegigabytesofmemorybandwidthiftheyallrequirethesamehighquality,massivetextures,requiremultiplesecondarytexturemaps(normalmaps,emissionmaps,andsoon),andarenotbatchedtogether,becausetheresimplyisn’tenoughTextureCachespaceavailabletokeepasingletexturefilelongenoughtoexploititduringthenextrenderingpass.
Thereareseveralapproacheswecantaketosolvebottlenecksinmemorybandwidth.
UselesstexturedataThisapproachissimple,straightforward,andalwaysagoodideatoconsider.Reducingtexturequality,eitherthroughresolutionorbitrate,isnotidealforgraphicalquality,butwecansometimesgetawaywithusing16-bittextureswithoutanynoticeabledegradation.
MipMaps(Chapter4,KickstartYourArt)areanotherexcellentwayofreducingtheamountoftexturedatabeingpushedbackandforthbetweenVRAMandtheTextureCache.NotethattheSceneViewhasaMipmapsShadingMode,whichwillhighlighttexturesinoursceneblueorreddependingonwhetherthecurrenttexturescaleisappropriateforthecurrentSceneView’scamerapositionandorientation.Thiswillhelpidentifywhattexturesaregoodcandidatesforfurtheroptimization.
TipMipMapsshouldalmostalwaysbeusedin3DScenes,unlessthecameramovesverylittle.
TestdifferentGPUTextureCompressionformatsTheTextureCompressiontechniquesyoulearnedbackinChapter4,KickstartYourArt,weredescribedinsuchawaythathelpedreduceourapplication’sfootprint(executablefilesize),andruntimeCPUmemoryusage,thatis,thestorageareawherealltextureresourcedataiskeptuntilitisneededbytheGPU.However,oncethedatareachestheGPU,itusesadifferentformofcompressiontokeeptexturedatasmall.ThecommonformatsareDXT,PVRTC,ETC,andASTC.
Tomakemattersmoreconfusing,eachplatformandGPUhardwaresupportsdifferentcompressionformats,andifthedevicedoesnotsupportthegivencompressionformat,thenitwillbehandledatthesoftwarelevel.Inotherwords,theCPUwillneedtostopandrecompressthetexturetothedesiredformattheGPUwants,asopposedtotheGPUtakingcareofitwithaspecializedhardwarechip.
ThecompressionoptionsareonlyavailableifatextureresourcehasitsTextureTypefieldsettoAdvanced.Usinganyoftheothertexturetypesettingswillsimplifythechoices,andUnitywillmakeabestguesswhendecidingwhichformattouseforthetargetplatform,whichmaynotbeidealforagivenpieceofhardwareandthuswillconsumemorememorybandwidththannecessary.
http://freepdf-books.com
![Page 278: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/278.jpg)
ThebestapproachtodeterminingthecorrectformatistosimplytestabunchofdifferentdevicesandTextureCompressiontechniquesandfindonethatfits.Forexample,commonwisdomsaysthatETCisthebestchoiceforAndroidsincemoredevicessupportit,butsomedevelopershavefoundtheirgameworksbetterwiththeDXTandPVRTCformatsoncertaindevices.
Bewarethat,ifwe’reatthepointwhereindividuallytweakingTextureCompressiontechniquesisnecessary,thenhopefullywehaveexhaustedallotheroptionsforreducingmemorybandwidth.Bygoingdownthisroad,wecouldbecommittingtosupportingmanydifferentdeviceseachintheirownspecificway.Manyofuswouldprefertokeepthingssimplewithageneralsolutioninsteadofpersonalcustomizationandtime-consuminghandiworktoworkaroundproblemslikethis.
MinimizetexturesamplingCanwemodifyourShaderstoremovesometexturesamplingoverhead?Didweaddsomeextratexturelookupfilestogiveourselvessomefillratesavingsonmathematicalfunctions?Ifso,wemightwanttoconsiderloweringtheresolutionofsuchtexturesorrevertingthechangesandsolvingourfillrateproblemsinotherways.Essentially,thelesstexturesamplingwedo,thelessoftenweneedtousememorybandwidthandthecloserwegettoresolvingthebottleneck.
OrganizeassetstoreducetextureswapsThisapproachbasicallycomesbacktoBatchingandAtlasingagain.Arethereopportunitiestobatchsomeofourbiggesttexturefilestogether?Ifso,thenwecouldsavetheGPUfromhavingtopullinthesametexturefilesoverandoveragainduringthesameframe.Asalastresort,wecouldlookforwaystoremovesometexturesfromtheentireprojectandreusesimilarfiles.Forinstance,ifwehavefillratebudgettospare,thenwemaybeabletousesomeFragmentShaderstomakeahandfuloftexturesfilesappearinourgamewithdifferentcolorvariations.
http://freepdf-books.com
![Page 279: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/279.jpg)
VRAMlimitsOnelastconsiderationrelatedtotexturesishowmuchVRAMwehaveavailable.MosttexturetransferfromCPUtoGPUoccursduringinitialization,butcanalsooccurwhenanon-existenttextureisfirstrequiredbythecurrentview.Thisprocessisasynchronousandwillresultinablanktexturebeinguseduntilthefulltextureisreadyforrendering.Assuch,weshouldavoidtoomuchtexturevariationacrossourScenes.
TexturepreloadingEventhoughitdoesn’tstrictlyrelatetographicsperformance,itisworthmentioningthattheblanktexturethatisusedduringasynchronoustextureloadingcanbejarringwhenitcomestogamequality.WewouldlikeawaytocontrolandforcethetexturetobeloadedfromdisktothemainmemoryandthentoVRAMbeforeitisactuallyneeded.
AcommonworkaroundistocreateahiddenGameObjectthatfeaturesthetextureandplaceitsomewhereintheSceneontheroutethattheplayerwilltaketowardstheareawhereitisactuallyneeded.Assoonasthetexturedobjectbecomesacandidatefortherenderingsystem(evenifit’stechnicallyhidden),itwillbegintheprocessofcopyingthedatatowardsVRAM.Thisisalittleclunky,butiseasytoimplementandworkssufficientlywellinmostcases.
WecanalsocontrolsuchbehaviorviaScriptcodebychangingahiddenMaterial’stexture:
GetComponent<Renderer>().material.texture=textureToPreload;
TexturethrashingIntherareeventthattoomuchtexturedataisloadedintoVRAM,andtherequiredtextureisnotpresent,theGPUwillneedtorequestitfromthemainmemoryandoverwritetheexistingtexturedatatomakeroom.Thisislikelytoworsenovertimeasthememorybecomesfragmented,anditintroducesariskthatthetexturejustflushedfromVRAMneedstobepulledagainwithinthesameframe.Thiswillresultinaseriouscaseofmemory“thrashing”,andshouldbeavoidedatallcosts.
ThisislessofaconcernonmodernconsolessuchasthePS4,XboxOne,andWiiU,sincetheyshareacommonmemoryspaceforbothCPUandGPU.Thisdesignisahardware-leveloptimizationgiventhefactthatthedeviceisalwaysrunningasingleapplication,andalmostalwaysrendering3Dgraphics.But,allotherplatformsmustsharetimeandspacewithmultipleapplicationsandbecapableofrunningwithoutaGPU.TheythereforefeatureseparateCPUandGPUmemory,andwemustensurethatthetotaltextureusageatanygivenmomentremainsbelowtheavailableVRAMofthetargethardware.
Notethatthis“thrashing”isnotpreciselythesameasharddiskthrashing,wherememoryiscopiedbackandforthbetweenmainmemoryandvirtualmemory(theswapfile),butitisanalogous.Ineithercase,dataisbeingunnecessarilycopiedbackandforthbetweentworegionsofmemorybecausetoomuchdataisbeingrequestedintooshortatimeperiodforthesmallerofthetwomemoryregionstoholditall.
http://freepdf-books.com
![Page 280: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/280.jpg)
NoteThrashingsuchasthiscanbeacommoncauseofdreadfulgraphicsperformancewhengamesareportedfrommodernconsolestothedesktopandshouldbetreatedwithcare.
Avoidingthisbehaviormayrequirecustomizingtexturequalityandfilesizesonaper-platformandper-devicebasis.Bewarnedthatsomeplayersarelikelytonoticetheseinconsistenciesifwe’redealingwithhardwarefromthesameconsoleordesktopGPUgeneration.Asmanyofuswillknow,evensmalldifferencesinhardwarecanleadtoalotofapples-versus-orangescomparisons,buthardcoregamerswillexpectasimilarlevelofqualityacrosstheboard.
http://freepdf-books.com
![Page 281: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/281.jpg)
http://freepdf-books.com
![Page 282: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/282.jpg)
LightingandShadowingLightingandShadowingcanaffectallpartsofthegraphicspipeline,andsotheywillbetreatedseparately.Thisisperhapsoneofthemostimportantpartsofgameartanddesigntogetright.GoodLightingandShadowingcanturnamundanesceneintosomethingspectacularasthereissomethingmagicalaboutprofessionalcoloringthatmakesitvisuallyappealing.Eventhelow-polyartstyle(thinkMonumentValley)reliesheavilyonagoodlightingandshadowingprofileinordertoallowtheplayertodistinguishoneobjectfromanother.But,thisisn’tanartbook,sowewillfocusontheperformancecharacteristicsofvariousLightingandShadowingfeatures.
Unityofferstwostylesofdynamiclightrendering,aswellasbakedlightingeffectsthroughlightmaps.Italsoprovidesmultiplewaysofgeneratingshadowswithvaryinglevelsofcomplexityandruntimeprocessingcost.Betweenthetwo,therearealotofoptionstoexplore,andalotofthingsthatcantripusupifwe’renotcareful.
TheUnitydocumentationcoversallofthesefeaturesinanexcellentamountofdetail(startwiththispageandworkthroughthem:http://docs.unity3d.com/Manual/Lighting.html),sowe’llexaminethesefeaturesfromaperformancestandpoint.
Let’stacklethetwomainlightrenderingmodesfirst.ThissettingcanbefoundunderEdit|ProjectSettings|Player|OtherSettings|Rendering,andcanbeconfiguredonaper-platformbasis.
http://freepdf-books.com
![Page 283: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/283.jpg)
ForwardRenderingForwardRenderingistheclassicalformofrenderinglightsinourscene.EachobjectislikelytoberenderedinmultiplepassesthroughthesameShader.Howmanypassesarerequiredwillbebasedonthenumber,distance,andbrightnessoflightsources.Unitywilltrytoprioritizewhichdirectionallightisaffectingtheobjectthemostandrendertheobjectina“basepass”asastartingpoint.Itwillthentakeuptofourofthemostpowerfulpointlightsnearbyandre-renderthesameobjectmultipletimesthroughthesameFragmentShader.Thenextfourpointlightswillthenbeprocessedonaper-vertexbasis.Allremaininglightsaretreatedasagiantblobbymeansofatechniquecalledsphericalharmonics.
Someofthisbehaviorcanbesimplifiedbysettingalight’sRenderModetovaluessuchasNotImportant,andchangingthevalueofEdit|ProjectSettings|Quality|PixelLightCount.Thisvaluelimitshowmanylightswillbetreatedonaperpixelbasis,butisoverriddenbyanylightswithaRenderModesettoImportant.Itisthereforeuptoustousethiscombinationofsettingsresponsibly.
Asyoucanimagine,thedesignofForwardRenderingcanutterlyexplodeourDrawCallcountveryquicklyinsceneswithalotofpointlightspresent,duetothenumberofrenderstatesbeingconfiguredandShaderpassesbeingreprocessed.CPU-boundapplicationsshouldavoidthisrenderingmodeifpossible.
NoteMoreinformationonForwardRenderingcanbefoundintheUnitydocumentation:http://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html.
http://freepdf-books.com
![Page 284: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/284.jpg)
DeferredShadingDeferredShadingorDeferredRenderingasitissometimesknown,isonlyavailableonGPUsrunningatleastShaderModel3.0.Inotherwords,anydesktopgraphicscardmadeafteraround2004.Thetechniquehasbeenaroundforawhile,butithasnotresultedinacompletereplacementoftheForwardRenderingmethodduetothecaveatsinvolvedandlimitedsupportonmobiledevices.Anti-aliasing,transparency,andanimatedcharactersreceivingshadowsareallfeaturesthatcannotbemanagedthroughDeferredShadingaloneandwemustusetheForwardRenderingtechniqueasafallback.
DeferredShadingissonamedbecauseactualshadingdoesnotoccuruntilmuchlaterintheprocess;thatis,itisdeferreduntillater.Fromaperformanceperspective,theresultsarequiteimpressiveasitcangenerateverygoodperpixellightingwithsurprisinglylittleDrawCalleffort.TheadvantageisthatahugeamountoflightingcanbeaccomplishedusingonlyasinglepassthroughthelightingShader.ThemaindisadvantagesincludetheadditionalcostsifwewishtopileonadvancedlightingfeaturessuchasShadowingandanystepsthatmustpassthroughForwardRenderinginordertocomplete,suchastransparency.
NoteTheUnitydocumentationcontainsanexcellentsourceofinformationontheDeferredShadingtechnique,itsadvantages,anditspitfalls:http://docs.unity3d.com/Manual/RenderTech-DeferredShading.html.
http://freepdf-books.com
![Page 285: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/285.jpg)
VertexLitShading(legacy)Technically,therearemorethantwolightingmethods.Unityallowsustouseacoupleoflegacylightingsystems,onlyoneofwhichmayseeactualuseinthefield:VertexLitShading.Thisisamassivesimplificationoflighting,aslightingisonlyconsideredpervertex,andnotperpixel.Inotherwords,entirefacesarecoloredbasedontheincominglightcolor,andnotindividualpixels.
Itisnotexpectedthatmany,orreallyany,3Dgameswillmakeuseofthislegacytechnique,asalackofshadowsandproperlightingmakevisualizationsofdepthverydifficult.Itismostlyrelegatedto2Dgamesthatdon’tintendtomakeuseofshadows,normalmaps,andvariousotherlightingfeatures,butitisthereifweneedit.
http://freepdf-books.com
![Page 286: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/286.jpg)
Real-timeShadowsSoftShadowsareexpensive,HardShadowsarecheap,andNoShadowsarefree.ShadowResolution,ShadowProjection,ShadowDistance,andShadowCascadesareallsettingswecanfindunderEdit|ProjectSettings|Quality|Shadowsthatwecanusetomodifythebehaviorandcomplexityofourshadowingpasses.ThatsummarizesalmosteverythingweneedtoknowaboutUnity’sreal-timeshadowingtechniquesfromahigh-levelperformancestandpoint.Wewillcovershadowsmoreinthefollowingsectiononoptimizingourlightingeffects.
http://freepdf-books.com
![Page 287: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/287.jpg)
LightingoptimizationWithacursoryglanceatalloftherelevantlightingtechniques,let’srunthroughsometechniqueswecanusetoimprovelightingcosts.
UsetheappropriateShadingModeItisworthtestingbothofthemainrenderingmodestoseewhichonebestsuitsourgame.DeferredShadingisoftenusedasabackupintheeventthatForwardRenderingisbecomingaburdenonperformance,butitreallydependsonwhereelsewe’refindingbottlenecksasitissometimesdifficulttotellthedifferencebetweenthem.
UseCullingMasksALightComponent’sCullingMaskpropertyisalayer-basedmaskthatcanbeusedtolimitwhichobjectswillbeaffectedbythegivenLight.Thisisaneffectivewayofreducinglightingoverhead,assumingthatthelayerinteractionsalsomakesensewithhowweareusinglayersforphysicsoptimization.Objectscanonlybeapartofasinglelayer,andreducingphysicsoverheadprobablytrumpslightingoverheadinmostcases;thus,ifthereisaconflict,thenthismaynotbetheidealapproach.
NotethatthereislimitedsupportforCullingMaskswhenusingDeferredShading.Becauseofthewayittreatslightinginaveryglobalfashion,onlyfourlayerscanbedisabledfromthemask,limitingourabilitytooptimizeitsbehaviorthroughthismethod.
UseBakedLightmapsBakingLightingandShadowingintoaSceneissignificantlylessprocessor-intensivethangeneratingthematruntime.Thedownsideistheaddedapplicationfootprint,memoryconsumption,andpotentialformemorybandwidthabuse.Ultimately,unlessagame’slightingeffectsarebeinghandledexclusivelythroughLegacyVertexLightingorasingleDirectionalLight,thenitshouldprobablyincludeLightmappingtomakesomehugebudgetsavingsonlightingcalculations.Relyingentirelyonreal-timelightingandshadowsisarecipefordisasterunlessthegameistryingtowinanawardforthesmallestapplicationfilesizeofalltime.
OptimizeShadowsShadowingpassesmostlyconsumeourDrawCallsandfillrate,buttheamountofvertexpositiondatawefeedintotheprocessandourselectionfortheShadowProjectionsettingwillaffectthefrontend’sabilitytogeneratetherequiredshadowcastersandshadowreceivers.Weshouldalreadybeattemptingtoreducevertexcountstosolvefrontendbottleneckinginthefirstplace,andmakingthischangewillbeanaddedmultipliertowardsthateffort.
DrawCallsareconsumedduringshadowingbyrenderingvisibleobjectsintoaseparatebuffer(knownastheshadowmap)aseitherashadowcaster,ashadowreceiver,orboth.EachobjectthatisrenderedintothismapwillconsumeanotherDrawCall,whichmakesshadowsahugeperformancecostmultiplier,soitisoftenasettingthatgameswillexpose
http://freepdf-books.com
![Page 288: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/288.jpg)
tousersviaqualitysettings,allowinguserswithweakerhardwaretoreducetheeffectorevendisableitentirely.
ShadowDistanceisaglobalmultiplierforruntimeshadowrendering.Thefewershadowsweneedtodraw,thehappiertheentirerenderingprocesswillbe.Thereislittlepointinrenderingshadowsatagreatdistancefromthecamera,sothissettingshouldbeconfiguredspecifictoourgameandhowmuchshadowingweexpecttowitnessduringgameplay.Itisalsoacommonsettingthatisexposedtotheusertoreducetheburdenofrenderingshadows.
HighervaluesofShadowResolutionandShadowCascadeswillincreaseourmemorybandwidthandfillrateconsumption.Bothofthesesettingscanhelpcurbtheeffectsofartefactsinshadowrendering,butatthecostofamuchlargershadowmapsizethatmustbemovedaroundandofthecanvassizetodrawto.
NoteTheUnitydocumentationcontainsanexcellentsummaryonthetopicofthealiasingeffectofshadowmapsandhowtheShadowCascadesfeaturehelpstosolvetheproblem:http://docs.unity3d.com/Manual/DirLightShadows.html.
It’sworthnotingthatSoftShadowsdonotconsumeanymorememoryorCPUoverheadrelativetoHardShadows,astheonlydifferenceisamorecomplexShader.ThismeansthatapplicationswithenoughfillratetosparecanenjoytheimprovedgraphicalfidelityofSoftShadows.
http://freepdf-books.com
![Page 289: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/289.jpg)
http://freepdf-books.com
![Page 290: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/290.jpg)
OptimizinggraphicsformobileUnity’sabilitytodeploytomobiledeviceshascontributedgreatlytoitspopularityamonghobbyist,small,andmid-sizedevelopmentteams.Assuch,itwouldbeprudenttocoversomeapproachesthataremorebeneficialformobileplatformsthanfordesktopandotherdevices.
Notethatany,andall,ofthefollowingapproachesmaybecomeobsoletesoon,iftheyaren’talready.Themobiledevicemarketismovingblazinglyfast,andthefollowingtechniquesastheyapplytomobiledevicesmerelyreflectconventionalwisdomfromthelasthalfdecade.Weshouldoccasionallytesttheassumptionsbehindtheseapproachesfromtime-to-timetoseewhetherthelimitationsofmobiledevicesstillfitthemobilemarketplace.
http://freepdf-books.com
![Page 291: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/291.jpg)
MinimizeDrawCallsMobileapplicationsaremoreoftenbottleneckedonDrawCallsthanonfillrate.Notthatfillrateconcernsshouldbeignored(nothingshould,ever!),butthismakesitalmostnecessaryforanymobileapplicationofreasonablequalitytoimplementMeshCombining,Batching,andAtlasingtechniquesfromtheverybeginning.DeferredRenderingisalsothepreferredtechniqueasitfitswellwithothermobile-specificconcerns,suchasavoidingtransparencyandhavingtoomanyanimatedcharacters.
http://freepdf-books.com
![Page 292: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/292.jpg)
MinimizetheMaterialcountThisconcerngoeshandinhandwiththeconceptsofBatchingandAtlasing.ThefewerMaterialsweuse,thefewerDrawCallswillbenecessary.ThisstrategywillalsohelpwithconcernsrelatingtoVRAMandmemorybandwidth,whichtendtobeverylimitedonmobiledevices.
http://freepdf-books.com
![Page 293: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/293.jpg)
MinimizetexturesizeandMaterialcountMostmobiledevicesfeatureaverysmallTextureCacherelativetodesktopGPUs.Forinstance,theiPhone3Gcanonlysupportatotaltexturesizeof1024x1024duetorunningOpenGLES1.1withsimplevertexrenderingtechniques.MeanwhiletheiPhone3GS,iPhone4,andiPadgenerationrunOpenGLES2.0,whichonlysupportstexturesupto2048x2048.Latergenerationscansupporttexturesupto4096x4096.Doublecheckthedevicehardwarewearetargetingtobesureitsupportsthetexturefilesizeswewishtouse(therearetoomanyAndroiddevicestolisthere).However,later-generationdevicesareneverthemostcommondevicesinthemobilemarketplace.Ifwewishourgametoreachawideaudience(increasingitschancesofsuccess),thenwemustbewillingtosupportweakerhardware.
NotethattexturesthataretoolargefortheGPUwillbedownscaledbytheCPUduringinitialization,wastingvaluableloadingtime,andleavinguswithunintendedgraphicalfidelity.ThismakestexturereuseofparamountimportanceformobiledevicesduetothelimitedVRAMandTextureCachesizesavailable.
http://freepdf-books.com
![Page 294: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/294.jpg)
Maketexturessquareandpowerof2WehavealreadycoveredthistopicinChapter4,KickstartYourArt,butitisworthrevisitingthesubjectofGPU-levelTextureCompression.TheGPUwillfinditdifficult,orsimplybeunabletocompressthetextureifitisnotinasquareformat,somakesureyousticktothecommondevelopmentconventionandkeepthingssquareandsizedtoapowerof2.
http://freepdf-books.com
![Page 295: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/295.jpg)
UsethelowestpossibleprecisionformatsinShadersMobileGPUsareparticularlysensitivetoprecisionformatsinitsShaders,sothesmallestformatsshouldbeused.Onarelatednote,formatconversionshouldbeavoidedforthesamereason.
http://freepdf-books.com
![Page 296: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/296.jpg)
AvoidAlphaTestingMobileGPUshaven’tquitereachedthesamelevelsofchipoptimizationasdesktopGPUs,andAlphaTestingremainsaparticularlycostlytaskonmobiledevices.InmostcasesitshouldsimplybeavoidedinfavorofAlphaBlending.
http://freepdf-books.com
![Page 297: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/297.jpg)
http://freepdf-books.com
![Page 298: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/298.jpg)
SummaryIfyou’vemadeitthisfarwithoutskippingahead,thencongratulationsareinorder.ThatwasalotofinformationtoabsorbforjustonecomponentoftheUnityEngine,butthenitisclearlythemostcomplicatedofthemall,requiringamatchingdepthofexplanation.Hopefully,you’velearnedalotofapproachestohelpyouimproveyourrenderingperformanceandenoughabouttherenderingpipelinetoknowhowtousethemresponsibly!
Bynowweshouldbeusedtotheideathat,withtheexceptionofalgorithmimprovements,everyperformanceenhancementweimplementwillcomewithsomerelatedcostthatwemustbewillingtobearforthesakeofremovingonebottleneck.Weshouldalsobereadytoimplementmultipletechniquesuntilwe’vesquashedthemall.
We’vejustcoveredaveryabstractsystemingreatdetail,solet’smovethingsalongwithanexplorationofamoreconcretesystem:Unity’sunderlyingEngineandtheC#language.Inthenextchapter,wewilltakealookatourScriptcodeinamoreadvancedlightandinvestigatesomemethodstoimproveourCPUandmemorymanagement.
http://freepdf-books.com
![Page 299: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/299.jpg)
http://freepdf-books.com
![Page 300: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/300.jpg)
Chapter7.MasterfulMemoryManagementUsingmemoryproperlywithintheUnityEnginerequiresagoodamountofunderstandingoftheunderlyingUnityEngineandMonoFramework.Thiscanbeabitofanintimidatingplaceforsomedevelopers,sincemanypickedUnityastheirsolutionprimarilytoavoidthekindoflow-levelgruntworkthatcomesfromenginedevelopmentandmemorymanagement.Theywouldpreferinsteadtofocusonhigher-levelconcernsrelatedtogameplayimplementation,leveldesign,andartassetmanagement.
Manygamesoflimitedscopecangetawaywithfocusingonsuchhigher-levelconcerns,atthecostofwastedresources,andmayneverrunintoanyproblemsrelatedtomemory.Thisisallwellandgooduntilthedayitbecomesaproblem.Atthispoint,theirneglectinunderstandingtheimportantcomponentsoftheengineleadstoascrambletofindsolutionsthatcanbedifficulttounderstandandimplementwithoutproperknowledgetobackitup.
Therefore,understandingwhatishappeningwithmemoryallocationsandC#languagefeatures,howtheyinteractwiththeMonoPlatform,howMonointeractswiththeunderlyingengine,andthevariouslibrarieswehaveavailableareabsolutelyparamounttomakinghigh-quality,efficientscriptcode.So,inthischapter,youwilllearnaboutallofthenutsandboltsoftheunderlyingUnityEngine,MonoPlatform,C#language,and.NETFramework.
Let’sstartbyexploringthefamiliarpartoftheengine,whichhandlesmostoftheworkforourgame’sscriptingcode—theMonoplatform.
http://freepdf-books.com
![Page 301: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/301.jpg)
TheMonoplatformMonoisamagicalsauce,mixedintotheUnityrecipe,whichgivesitalotofitscross-platformcapability.MonoisanopensourceprojectthatbuiltitsownframeworkandlibrariesbasedontheAPI,specifications,andtoolsfromMicrosoft’s.NETFrameworkandcommonlibraries.Essentially,itisarecreationofthe.NETFramework,asitwasaccomplishedwithlittletonoaccesstothesourcecode.Notethat,despiteMono’slibrariesbeinganopensourcerecreationofMicrosoft’sbase.NETclasslibrary,itisfullycompatiblewiththeoriginallibraryfromMicrosoft.
ThegoaloftheMonoprojectistoprovideaframeworktoallowcross-platformcompatibilityusingthe.NETFrameworkasacommonlayer.Itallowsapplicationstobewritteninacommonprogramminglanguageandrunagainstmanydifferenthardwareplatforms,includingLinux,OSX,Windows,ARM,PowerPC,andmore.Monoalsosupportsmanylanguages,notjusttheC#,Boo,andUnityScriptwemaybefamiliarwith.Anylanguagethatcanbecompiledinto.NET’spureCommonIntermediateLanguage(CIL–moreonthislater)issufficienttointegratewiththeMonoplatform.ThisincludesC#,butevenincludeslanguagessuchasF#,Java,VisualBasic.NET,PythonNet,andIronPython.
AcommonmisconceptionabouttheUnityEngineisthatitisbuiltontopoftheMonoplatform.Thisisuntrue,astheMonosidedoesnothandlemanyimportantgametaskssuchasaudio,rendering,physics,andsoon.UnityTechnologiesbuiltanativeC++backendforthesakeofspeed,andallowsitsuserscontroloftheenginethroughMonoasascriptinginterface.Assuch,MonoismerelyacomponentoftheunderlyingUnityEngine.Thisisequivalenttomanyothergameengines,whichrunC++underthehood,handlingimportanttaskssuchasrendering,animation,resourcemanagement,andsoon,whilesimultaneouslyprovidingascriptinglanguageforgameplaylogictobeimplemented.TheMonoplatformwaschosenbyUnityTechnologiesforthistask.
TipNativecodesimplymeanscodethatiscompileddirectlytothetargetOS,andexecuteswithoutadditionallayersofcomplexityintheruntimeenvironment.Thiskeepsoverheadcostslow,butattheexpenseofneedingtomanagememoryandothertaskswithinthecodeinamoredirectfashion.
Scriptinglanguagestypicallyabstractawaycomplexmemorymanagementthroughautomaticgarbagecollection,andprovidevarioussafetyfeatures,whichsimplifytheactofprogrammingattheexpenseofruntimeoverhead.Somescriptinglanguagescanalsobeinterpretedatruntime,meaningthattheydon’tneedtobecompiledbeforeexecution.Therawinstructionsareconverteddynamicallyintomachinecodeandexecutedthemomenttheyarereadduringruntime.Thelastfeature,andprobablythemostimportantone,isthattheyallowsimplersyntaxofprogrammingcommands.Thisusuallyimprovesthedevelopmentworkflowimmensely,asteammemberswithoutmuchexperienceusinglanguagessuchasC++cancontributetothecodebase.Thisenablesthemtoimplementthingssuchasgameplaylogicinasimplerformat,attheexpenseofacertainamountof
http://freepdf-books.com
![Page 302: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/302.jpg)
controlandruntimeexecutionspeed.
Notethatsuchlanguagesareoftencalled“managed”languages,whichfeaturemanagedcode.Technically,thiswasatermcoinedbyMicrosofttorefertoanysourcecodethatmustruninsidetheirCommonLanguageRuntime(CLR)environment(morelater),asopposedtocodethatiscompiledandrunnativelythroughthetargetOperatingSystem(OS).But,becauseoftheprevalenceandcommonfeaturesthatexistbetweentheCLRandotherlanguagesthatfeaturetheirownsimilarlydesignedruntimeenvironments(suchasJava),theterm“managed”hassincebecomealittlevague.Ittendstobeusedtorefertoanylanguageorcodethatdependsonitsownruntimeenvironmentandthatmay,ormaynot,includeautomaticgarbagecollection.Fortherestofthischapter,wewillusetheterm“managed”torefertocodethatbothdependsonaseparateruntimeenvironmentandhasundergoneautomaticgarbagecollection.
Theruntimeperformancecostofmanagedlanguagesisbecominglessandlesssignificanteveryyear.Thisispartlyduetogradualoptimizationsintoolsandruntimeenvironments,andpartlyduetothecomputingpoweroftheaveragedevicegraduallybecominggreater.Butthemainpointofcontroversyinmanagedlanguagesstillremainstheirautomaticmemorymanagement.Managingmemorymanuallycanbeacomplextaskthatcantakemanyyearsofdifficultdebuggingtobeproficientat,butmanydevelopersfeelthatmanagedlanguagessolvethisprobleminwaysthataretoounpredictable,riskingtoomuchproductquality.Suchdevelopersmightcitethatmanagedcodewillneverreachthesamelevelofperformanceasnativecode,anditisfoolhardytobuildhigh-performanceapplicationswiththem.
Thisistruetoanextent,asmanagedlanguagesinvariablyinflictruntimeoverheads,andwelosepartialcontroloverruntimememoryallocations.But,aswithallthings,itbecomesabalancingact,sincenotallresourceusagewillnecessarilyresultinabottleneck,andthebestgamesaren’tnecessarilytheonesthatuseeverysinglebytetotheirfullest.Forexample,imagineauserinterfacethatrefreshesin30microsecondsvianativecodeversus60microsecondsinmanagedcodeduetoanextra100percentoverhead(extremeexample).Themanagedcodeversionisstillfastenoughsuchthattheuserwillneverbeabletonoticethedifference,soistherereallyanyharminusingmanagedcodeforsuchatask?
Inreality,workingwithmanagedlanguagesoftenjustmeansthatdevelopershaveauniquesetofconcernstoworryaboutcomparedtonativecodedevelopers.Assuch,choosingtouseamanagedlanguageispartlyamatterofpreference,andpartlyacompromiseofcontroloverdevelopmentspeed.
http://freepdf-books.com
![Page 303: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/303.jpg)
ThecompilationprocessWhenwemakechangestoourC#code,itistypicallycompiledimmediatelyafterweswitchbackfromourfavoriteIDE(whichistypicallyeitherMonoDevelopor,themuchmorefeature-richVisualStudio)totheUnityEditor.However,theC#codeisnotconverteddirectlyintomachinecode,aswewouldexpecttohappenwithstaticcompilersinthelandofC++.Instead,thecodeisconvertedintoanintermediatelanguagecalledCommonIntermediateLanguage(CIL),whichisanabstractionabovenativecode.CILissimilartoJavabytecode,uponwhichitisbased,butCILcodeisentirelyuselessonitsown,asCPUshavenoideahowtoruntheinstructionsdefinedinthislanguage.
Atruntime,thisintermediatecodeisrunthroughtheMonoVirtualMachine(VM),whichisaninfrastructurecomponentthatallowsthesamecodetorunagainstmultipleplatformswithoutneedingtochangethecodeitself.Thisisanimplementationofthe.NETCommonLanguageRuntimeorCLR.Ifwe’rerunningoniOS,werunontheiOS-basedVirtualMachineinfrastructure,andifwe’rerunningonLinux,thenwesimplyuseadifferentonethatisbettersuitedforLinux.
WithintheCLR,theintermediateCILcodewillactuallybecompiledintonativecodeondemand.Thison-demandnativecompilationcanbeaccomplishedeitherbyanAhead-Of-Time(AOT)orJust-In-Time(JIT)compiler,dependingonwhichplatformisbeingtargeted.Thesecompilersallowcodesegmentstobecompiledintonativecode(thatis,machinecodespecifictotheOSitisrunningagainst),andthemaindifferencebetweenthetwotypesiswhenthecodeiscompiled.
AOTcompilationhappensearly(aheadoftime),eitherduringthebuildprocessorduringinitialization.Ineithercase,thecodehasbeenprecompiledandnofurtherruntimecostsareinflictedduetodynamiccompilation.InthecurrentversionofUnity(Version5.2.2),theonlyplatformsthatsupportAOTcompilationareWebGL(andonlywhenUnityScriptisbeingused)andiOS.
JITcompilationhappensdynamicallyatruntimeinaseparatethreadandbeginsjustpriortoexecution(“justintime”forexecution).Often,thisdynamiccompilationcausesthefirstinvocationofapieceofcodetorunalittle(oralot!)moreslowly,becausethecodemustfinishcompilingbeforeitcanbeexecuted.But,fromthatpointforward,wheneverthesamecodeblockisexecuted,thereisnoneedforrecompilation,andtheinstructionsrunthroughthepreviouslycompilednativecode.
Itiscommoninsoftwarethat90percentoftheworkisbeingdonebyonly10percentofthecode.ThisgenerallymeansthatJITcompilationturnsouttobeanetpositiveonperformancethanifwesimplytriedtointerprettheCILcodedirectly.However,becausetheJITcompilermustcompilecodequickly,itisnotabletomakeuseofmanyoptimizationtechniquesthatstaticcompilersareabletoexploit.
ManualJITcompilationIntheeventthatJITcompilationiscausingaruntimeperformanceloss,beawarethatitisactuallypossibletoforceJITcompilationofamethodatanytimeviareflection.
http://freepdf-books.com
![Page 304: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/304.jpg)
ReflectionisausefulfeatureoftheC#language,thatallowsourcodebasetoexploreitselfintrospectivelyfortypeinformation,methods,values,andmetadata.Usingreflectionisoftenaverycostlyprocess.Itshouldbeavoidedatruntimeor,attheveryleast,onlyusedduringinitializationorotherloadingtimes.NotdoingsocaneasilycausesignificantCPUspikesandgameplayfreezing.
WecanmanuallyforceJITcompilationofamethodusingreflectiontoobtainafunctionpointertoit:
varmethod=typeof(MyComponent).GetMethod("MethodName");
if(method!=null){
method.MethodHandle.GetFunctionPointer();
Debug.Log("JITcompilationcomplete!");
}
Thiscodeonlyworksonpublicmethods.Obtainingnon-publicmethodscanbeaccomplishedthroughtheuseofBindingFlags:
usingSystem.Reflection;
//...
varmethod=typeof(MyComponent).GetMethod("MethodName",
BindingFlags.NonPublic|BindingFlags.Instance);
ThiskindofcodeshouldonlyberunforverytargetedmethodswherewearecertainthatJITcompilationiscausingCPUspikes.Thiscanbeverifiedbyrestartingtheapplicationandprofilingamethod’sfirstinvocationversusallsubsequentinvocations.ThedifferencewilltellustheJITcompilationoverhead.
TipNotethattheofficialmethodforforcingJITcompilationinthe.NETlibraryisRuntimeHelpers.PrepareMethod(),butthisisnotproperlyimplementedinthecurrentversionofMonothatcomeswithUnity(MonoVersion2.6.5).TheaforementionedworkaroundshouldbeuseduntilUnityhaspulledinamorerecentversionoftheMonoproject.
http://freepdf-books.com
![Page 305: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/305.jpg)
http://freepdf-books.com
![Page 306: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/306.jpg)
MemoryusageoptimizationInmostgameengines,wewouldhavetheluxuryofbeingabletoportinefficientscriptcodeintothefasterC++areaifwewerehittingperformanceissues.ThisisnotanoptionunlessweinvestseriouscashinobtainingtheUnitysourcecode,whichisofferedasalicenseseparatefromtheFree/Personal/Prolicensingsystem,andonapercase,pertitlebasis.ThisforcestheoverwhelmingmajorityofusintoapositionofneedingtomakeourC#script-levelcodeasperformantaspossible.So,whatdoesallofthisbackstorywe’vebeencoveringmeanforuswhenitcomestothetaskofperformanceoptimization?
Firstly,wewon’tbecoveringanythingthatisspecifictotheUnityScriptandBoolanguages(althoughmuchoftheknowledgetranslatestothoselanguages).
Secondly,eventhoughallofourscriptcodemightbeinC#,weneedtobeawarethattheoverallUnityEngineisbuiltfrommultiplecomponentsthateachmaintainsitsownmemorydomains.
Thirdly,onlysometasksweperformwillawakenthedreadedgarbagecollector.Therearequiteafewmemoryallocationapproachesthatwecanusetoavoiditentirely.
Finally,thingscanchangequiteabitdependingonthetargetplatformwe’rerunningagainstandeveryassumptionshouldbetestedforvalidityifwe’restumblingintounexpectedmemorybottlenecks.
http://freepdf-books.com
![Page 307: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/307.jpg)
UnitymemorydomainsThememoryspacewithintheUnityEnginecanbeessentiallysplitintothreedifferentmemorydomains.Eachdomainstoresdifferenttypesofdataandtakescareofaverydifferentsetoftasks.
ThefirstdomainistheNativeDomain.ThisistheunderlyingfoundationoftheUnityEngine,whichiswritteninC++andcompiledtonativecodedependingonwhichplatformisbeingtargeted.ThisareatakescareofallocatingmemoryspaceforthingssuchasAssetdata,forexampleTexturesandMeshes,memoryspaceforvarioussubsystems,suchastheRenderingsystem,Physics,Input,andsoon.Finally,itincludesnativerepresentationsofimportantgameplayobjectssuchasGameObjectandComponent.ThisiswherealotofthebaseComponentclasseskeeptheirdata,suchastheTransformandRigidbodyComponents.
Thesecondmemorydomain,theManagedDomain,iswheretheMonoplatformdoesitswork,andistheareaofmemorythatismaintainedbytheGarbageCollector.Anyscriptingobjectsandcustomclassesarestoredwithinthismemorydomain.ItalsoincludeswrappersfortheverysameobjectrepresentationsthatarestoredwithintheNativeDomain.ThisiswherethebridgebetweenMonocodeandNativecodederivesfrom;eachdomainhasitsownrepresentationforthesameentity,andcrossingthebridgebetweenthemtoomuchcaninflictsomefairlysignificantperformancehitsonourgame,aswelearnedinthepreviouschapters.
WhenanewGameObjectorComponentisinstantiated,itinvolvesallocatingmemoryinboththeManagedandNativeDomains.ThisallowssubsystemssuchasPhysicsandRenderingsystemstocontrolandrenderanobjectthroughitstransformdataontheNativeDomain,whiletheTransformComponentfromourscriptcodeismerelyawaytoreferencethroughthebridgeintotheNativememoryspaceandchangetheobject’stransformdata.Crossingbackandforthacrossthisbridgeshouldbeminimizedasmuchaspossible,duetotheoverheadinvolved,aswe’velearnedthroughtechniquessuchascachingposition/rotationchangesbeforeapplyingthem,backinChapter2,ScriptingStrategies.
Thethirdandfinalmemorydomain(s)arethoseofNativeandExternalDLLs,suchasDirectX,OpenGL,andanycustomDLLs,weattachtoourproject.ReferencingfromMonoC#codeintosuchDLLswillcauseasimilarmemoryspacetransitionasthatbetweenMonocodeandNativecode.
NativememoryWehavenodirectcontroloverwhatisgoingonintheNativeDomainwithouttheUnityEnginesourcecode,butwedohavealotofindirectcontrolbymeansofvariousscript-levelfunctions.Therearetechnicallyavarietyofmemoryallocatorsavailable,whichareusedinternallyforthingssuchasGameObjects,Graphicsobjects,andtheProfiler,butthesearehiddenbehindtheNativecodewall.
However,wecanobservehowmuchmemoryhasbeenallocatedandreservedinthis
http://freepdf-books.com
![Page 308: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/308.jpg)
memorydomainviatheMemoryAreaoftheProfiler.Nativememoryallocationsshowupunderthevalueslabeled“Unity”,andwecanevengetmoreinformationusingtheDetailedviewandsamplingthecurrentframe.
UndertheSceneMemorysectionoftheDetailedview,wecanobservethatMonoBehaviourobjectsalwaysconsumeaconstantamountofmemory,regardlessoftheirmemberdata.ThisisthememoryconsumedbytheNativerepresentationoftheobject.Notethat376bytesofmemoryisconsumedbyaMonoBehaviourinEditorMode,whileonly156bytesisconsumedwhenprofilingthroughastandaloneapplication.
TipMemoryconsumptioninEditorModeisalwayswildlydifferenttothatofastandaloneversion,duetovariousdebuggingandeditorhookdatabeingapplied.ThisaddsafurtherincentivetoavoidusingEditorModeforprofilingandbenchmarkingpurposes(althoughitcanstillbeusefulattimes).
WecanalsousetheProfiler.GetRuntimeMemorySize()methodtogettheNativememoryallocationsizeofaparticularobject.
ManagedobjectrepresentationsareintrinsicallylinkedtotheirNativerepresentations.ThebestwaytominimizeourNativememoryallocationsistosimplyoptimizeourManagedmemoryusage.
ManagedmemoryMemoryinmostmodernoperatingsystemssplitsdynamicmemoryintotwocategories:thestackandtheheap.Thestackisaspecialreservedspaceinmemory,dedicatedtosmall,short-liveddatavalues,whichareautomaticallydeallocatedthemomenttheygooutofscope.Thestackcontainslocalvariables,aswellashandlestheloadingandunloadingoffunctionsasthey’recalled,andexpandsandcontractsalongwiththecallstack.Deallocationsinthestackarebasicallyfreebecausethedataisessentiallyinstantlyforgottenaboutandnolongerreferenceable.Newdatasimplyoverwritestheolddata,sincethestartofthenextmemoryallocationisalwaysknown,andthere’snoreasontoperformanyclean-upoperations.
Becausedatainthestackisveryshort-lived,thetotalstacksizeisusuallyverysmall;intheorderofMegabytes.It’spossibletocauseastackoverflowbyallocatingmorespacethanthestackcansupport.Thiscanoccurduringexceptionallylargecallstacks(forexample,infiniteloops),orhavingalargenumberoflocalvariables,butinmostcasescausingastackoverflowshouldnotbeaconcerndespiteitsrelativelysmallsize.
Theheaprepresentsallremainingmemoryspace,anditisusedfortheoverwhelming
http://freepdf-books.com
![Page 309: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/309.jpg)
majorityofdynamicmemoryallocation.Wheneveradatatypeistoobigtofitinthestackormustexistoutsidethefunctionitwasdeclaredin,thenitmustbeallocatedontheheap.Mono’sheapisspecialinthatitismanagedbyaGarbageCollector(itissometimesreferredtoasaManagedHeap).Duringapplicationinitialization,MonowillrequestagivenchunkofmemoryfromtheOSanduseittogeneratetheheap.Theheapstartsofffairlysmall,lessthanoneMegabyte,butwillgrowasnewblocksofmemoryareneededbyourscriptcode.
WecanverifyhowmuchmemoryhasbeenallocatedandreservedfortheheapusingtheMemoryAreaoftheProfiler,butunderthevalueslabeled“Mono”.
WecanalsodeterminethecurrentusedandreservedheapspaceatruntimeusingtheProfiler.GetMonoUsedSize()andProfiler.GetMonoHeapSize()methods,respectively.
Garbagecollection
Whenamemoryrequestismade,andthereisenoughemptyspaceinthereservedheapblocktosatisfytherequest,thenMonoallocatesthespaceandhandsitovertowhoeverrequestedit.But,iftheheapdoesnothaveroomforit,thentheGarbageCollectorwillawakenandscanalltheexistingmemoryallocationsforanythingwhichisnolongerbeingusedandcleansthemupfirst,beforeattemptingtoexpandthecurrentheapspace.
TheGarbageCollectorintheversionofMonothatUnityusesisatypeofTracingGarbageCollector,whichusesaMark-and-Sweepstrategy.Thisalgorithmworksintwophases:eachallocatedobjectistrackedwithanadditionalbit.Thisflagswhethertheobjecthasbeenmarkedornot.Theseflagsstartoffsetto0(orfalse).
Whenthecollectionprocessbegins,itmarks(setstheflagto1ortrue)allobjectsthatarestillreachabletotheprogram.Eitherthereachableobjectisadirectreference,suchasstaticorlocalvariablesonthestack,oritisanindirectreferencethroughthefields(memberdata)ofotherdirectlyorindirectlyaccessibleobjects.Inthisway,itisgatheringasetofobjectsthatarestillreferenceable.
Thesecondphaseinvolvesiteratingthrougheveryobjectreferenceintheheap(whichMonowillhavebeentrackingthroughoutthelifetimeoftheapplication)andverifyingwhetherornottheyaremarked.Ifso,thentheobjectisignored.But,ifitisnotmarked,thenitisacandidatefordeallocation.Duringthisphase,allmarkedobjectsareskippedover,butnotbeforesettingtheirflagbacktofalseforthefirstphaseofthenextgarbagecollection.
Oncethesecondphaseends,allunmarkedobjectsaredeallocatedtofreespace,andthentheinitialrequesttocreatetheobjectisrevisited.Ifthereisenoughspacefortheobject,thenitisallocatedinthatspaceandtheprocessends.But,ifnot,thenitmustallocatea
http://freepdf-books.com
![Page 310: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/310.jpg)
newblockfortheheapbyrequestingitfromtheOperatingSystem,atwhichpointthememoryallocationrequestcanfinallybecompleted.
Inanidealworld,whereweonlykeepallocatinganddeallocatingobjectsbutonlyafinitenumberofthemexistatonce,theheapwouldmaintainaconstantsizebecausethere’salwaysenoughspacetofittheobject.However,allobjectsinanapplicationarerarelydeallocatedinthesameordertheywereallocated,andevenmorerarelydotheyallhavethesamesizeinmemory.Thisleadstomemoryfragmentation.Memoryfragmentation
Fragmentationoccurswhenobjectsareallocatedanddeallocatedindifferentorders.Thisisbestexplainedthroughanexample.Thefollowingshowsfourstagesofmemoryallocationwithinatypicalheapmemoryspace:
Hereishowthememoryallocationtakesplace:
1. Westartwithanemptyheapspace(1).2. Wethenallocatefourobjectsontheheap,A,B,CandD,eachsizedat64bytes(2).3. Atsomelatertime,wedeallocatetwooftheobjectsAandC(3).4. Thistechnicallyfrees128bytesworthofspace,butsincetheobjectswerenot
contiguous(adjoiningneighbors)inmemory,wehavereallyonlydeallocatedtwoseparate64-byteregionsofmemory.If,atsomepointlater,wewishtoallocateanewobjectthatislargerthan64bytes(4),thenwecannotusethespacethatwaspreviouslyfreedbyobjectsAandC,sinceneitherisindividuallylargeenoughtofitthenewobject(objectsmustalwaysconsumecontiguousmemoryspaces).Therefore,thenewobjectmustbeallocatedinthenextavailable128contiguousbytesintheheapspace.
http://freepdf-books.com
![Page 311: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/311.jpg)
Overtime,ourheapmemorywillbecomeriddledwithmoreandmore,smallerandsmalleremptyspacessuchasthese,asobjectsofdifferentsizesaredeallocated,andthenthesystemlatertriestoallocatenewobjectswithinthesmallestavailablespacethatitcanfitwithin.Thesmallertheseregionsbecome,thelessusabletheyarefornewmemoryallocations.Touseananalogy,thememoryspacebeginstoresembleSwisscheesewithmanysmallholesthatbecomeunusabletous.Intheabsenceofbackgroundtechniquesthatautomaticallycleanupthisfragmentation,thiseffectwouldoccurinliterallyanymemoryspace—RAM,heapspace,andevenharddrives—whicharejustlarger,slower,andmorepermanentmemorystorageareas(thisiswhyit’sagoodideatodefragmentourharddrivesfromtime-to-time!).
Memoryfragmentationcausestwoproblems.Firstly,iteffectivelyreducesthetotalusablememoryspacefornewobjectsoverlongperiodsoftime,dependingonthefrequencyofallocationsanddeallocations.Secondly,itmakesnewallocationstakelongertoresolve,duetotheextratimeittakestofindanewmemoryspacelargeenoughtofittheobject.
Thisbecomesimportantwhennewmemoryallocationsaremadeinaheap,sincewherethefreespacesarelocatedbecomesjustasimportantashowmuchfreespaceisavailable.Evenifwetechnicallyhave128bytesoffreespacetofitanewobject,ifitisnotcontiguousspace,thentheheapmusteithercontinuesearchinguntilitfindsalargeenoughspaceortheentireheapsizemustbeincreasedtofitthenewobject,byrequestinganewmemoryallocationfromtheOSinordertoexpandtheheapspace.Garbagecollectionatruntime
So,inaworstcasescenario,whenanewmemoryallocationisbeingrequestedbyourgame,theCPUwouldhavetospendcyclescompletingthefollowingtasksbeforetheallocationisfinallycompleted:
1. Verifyifthereisenoughcontiguousspaceforthenewobject.2. Ifnot,iteratethroughallknowndirectandindirectreferences,markingthemas
reachable.3. Iteratethroughtheentireheap,flaggingunmarkedobjectsfordeallocation.4. Verifyasecondtimeifthereisenoughcontiguousspaceforthenewobject.5. Ifnot,requestanewmemoryblockfromtheOS,inordertoexpandtheheap.6. Allocatethenewobjectatthefrontofthenewlyallocatedblock.
ThiscanbealotofworkfortheCPUtohandle,particularlyifthisnewmemoryallocationisanimportantgameobjectsuchasaparticleeffect,anewcharacterenteringthescene,acutscenetransition,andsoon.UsersarelikelytonotemomentswheretheGarbageCollectorisfreezinggameplaytohandlethesetasks.Tomakemattersworse,thegarbagecollectionworkloadscalesastheallocatedheapspacegrows,sincesweepingthroughafewmegabytesofspacewillbesignificantlyfasterthanscanningseveralgigabytesofspace.
Allofthismakesitabsolutelycriticaltocontrolourheapspaceintelligently.Thelazierourmemoryusagetacticsare,theworsetheGarbageCollectorwillbehaveinanalmostexponentialfashion.So,it’salittleironicthat,despitetheeffortsofmanagedlanguagesto
http://freepdf-books.com
![Page 312: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/312.jpg)
solvethememorymanagementproblem,managedlanguagedeveloperscanstillfindthemselvesbeingjustas,ifnotmore,concernedwithmemoryconsumptionthandevelopersofnativeapplications!Threadedgarbagecollection
TheGarbageCollectorrunsontwoseparatethreads:theMainthreadandtheFinalizerthread.WhentheGarbageCollectorisinvoked,itwillrunontheMainthreadandflagheapmemoryblocksforfuturedeallocation.Thisdoesnothappenimmediately.TheFinalizerthread,controlledbyMono,canhaveadelayofseveralsecondsbeforethememoryisfinallyfreedandavailableforreallocation.
WecanobservethisbehaviorintheTotalAllocatedblock(thegreenlinewithapologiestothat5percentofthepopulationwithdeuteranopia/deuteranomaly)oftheMemoryAreawithintheProfiler.Itcantakeseveralsecondsforthetotalallocatedvaluetodropafteragarbagecollectionhasoccurred.Becauseofthedelay,weshouldnotrelyonmemorybeingavailablethemomentithasbeendeallocated,andassuch,weshouldneverwastetimetryingtoekeouteverylastbyteofmemorythatwebelieveshouldbeavailable.Wemustensurethatthereisalwayssomekindofbufferzoneavailableforfutureallocations.
BlocksthathavebeenfreedbytheGarbageCollectormaysometimesbegivenbacktotheOperatingSystemaftersometime,whichwouldreducethereservedspaceconsumedbytheheapandallowthememorytobeallocatedforsomethingelse,suchasanotherapplication.But,thisisveryunpredictableanddependsontheplatformbeingtargeted,soweshouldn’trelyonit.Theonlysafeassumptiontomakeisthat,assoonasthememoryhasbeenallocatedtoMono,it’sthenreservedandisnolongeravailabletoeithertheNativeDomainoranyotherapplicationrunningonthesamesystem.Garbagecollectiontactics
Onestrategytominimizegarbagecollectionproblemsisconcealment;manuallyinvoketheGarbageCollectoratopportunemoments,whentheplayermaynotnotice.Acollectioncanbeinvokedbysimplycallingthefollowingmethod:
System.GC.Collect();
Goodopportunitiestoinvokeacollectionmaybeduringlevelloading,whengameplayispaused,shortlyafteramenuinterfacehasbeenopened,inthemiddleofcutscenetransitions,orreallyanybreakingameplaythattheplayerwouldnotwitness,orcareaboutasuddenperformancedrop.WecouldevenusetheProfiler.GetMonoUsedSize()andProfiler.GetMonoHeapSize()methodsatruntimetodetermineifagarbagecollectionneedstobeinvokedinthenearfuture.
Wecanalsocausethedeallocationofahandfulofspecificobjects.IftheobjectinquestionisoneoftheUnityobjectwrappers,suchasaGameObjectorMonoBehaviourcomponent,thentheFinalizerwillfirstinvoketheDispose()methodwithintheNativeDomain.Atthispoint,thememoryconsumedbyboththeNativeandManagedDomainswillthenbefreed.Insomerareinstances,iftheMonowrapperimplementstheIDisposableinterface(thatis,ithasaDispose()methodavailablefromscriptcode),thenwecanactuallycontrolthisbehaviorandforcethememorytobefreedinstantly.
http://freepdf-books.com
![Page 313: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/313.jpg)
Theonlyknownandusefulcaseofthis(thatthisauthoriscurrentlyawareof)istheWWWclass.ThisclassismostoftenusedtoconnecttoawebserveranddownloadAssetdataduringruntime.ThisclassneedstoallocateseveralbuffersintheNativeDomaininordertoaccomplishthistask.Itneedstomakeroomforthecompressedfile,adecompressionbuffer,andthefinaldecompressedfile.Ifwekeptallofthismemoryforalongtime,itwouldbeacolossalwasteofpreciousspace.So,bycallingitsDispose()methodfromscriptcode,wecanensurethatthememorybuffersarefreedpromptlyandpreciselywhentheyneedtobe.
AllotherAssetobjectsoffersomekindofunloadingmethodtocleanupanyunusedassetdata,suchasResources.UnloadUnusedAssets().ActualassetdataisstoredwithintheNativeDomain,sotheGarbageCollectortechnicallyisn’tinvolvedhere,buttheideaisbasicallythesame.ItwilliteratethroughallAssetsofaparticulartype,checkifthey’renolongerbeingreferenced,and,ifso,deallocatethem.But,again,thisisanasynchronousprocessandwecannotguaranteewhendeallocationwilloccur.ThismethodisautomaticallycalledinternallyafteraSceneisloaded,butthisstilldoesn’tguaranteeinstantdeallocation.
Attheveryleast,Resources.UnloadAsset()(thatis,unloadingonespecificAssetatatime)isthepreferredwaytocleanupAssetdata,sincetimewillnotbespentiteratingthroughtheentirecollection.However,it’sworthnotingthattheseunloadingmethodswereupgradedtobemultithreadedinUnity5,whichimprovestheperformancecostofcleaningupAssetdatarathersignificantlyonmostplatforms.
However,thebeststrategyforgarbagecollectionwillalwaysbeavoidance;ifweallocateaslittleheapmemoryandcontrolitsusageasmuchaspossible,thenwewon’thavetoworryabouttheGarbageCollectorinflictingperformancecostsasfrequentlyorashard.Youwilllearnmanytacticsforthisduringtheremainderofthechapter,butyoushouldfirstcoversometheoryonhowandwherememoryisallocated.
http://freepdf-books.com
![Page 314: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/314.jpg)
ValuetypesandReferencetypesNotallmemoryallocationswemakewithinMonowillgothroughtheheap.The.NETFramework(andbyextensiontheC#language,whichmerelyimplementsthe.NETspecification)hastheconceptofValuetypesandReferencetypes,andonlythelatterofwhichneedstobemarkedbytheGarbageCollectorwhileitisperformingitsMark-and-Sweepalgorithm.Referencetypesareexpectedto(orneedto)lastalongtimeinmemoryeitherduetotheircomplexity,theirsize,orhowthey’reused.Largedatasets,andanykindofobjectinstantiatedfromaclass,isaReferencetype.Thisalsoincludesarrays(whetheritisofValuetypesorReferencetypes),delegates,allclasses,suchasMonoBehaviour,GameObject,andanycustomclasseswedefine.
Valuetypesarenormallyallocatedonthestack.Primitivedatatypessuchasbools,ints,andfloatsareexamplesofValuetypes,butonlyifthey’restandaloneandnotamemberofaReferencetype.AssoonasaprimitivedatatypesiscontainedwithinaReferencetype,suchasaclassoranarray,thenitisimpliedthatitiseithertoolargeforthestackorwillneedtosurvivelongerthanthecurrentscopeandmustbeallocatedontheheapinstead.
Allofthiscanbebestexplainedthroughexamples.ThefollowingcodewillcreateanintegerasaValuetypethatexistsonthestackonlytemporarily:
publicclassTestComponent:MonoBehaviour{
voidStart(){
intdata=5;//allocatedonthestack
DoSomething(data);
}//integerisdeallocatedfromthestackhere
}
AssoonastheStart()methodends,thentheintegerisdeallocatedfromthestack.Thisisessentiallyafreeoperationsince,asmentionedpreviously,itdoesn’tbotherdoinganycleanup;itjustmovesthestackpointerbacktothepreviousmemorylocationinthecallstack.Anyfuturestackallocationssimplyoverwritetheolddata.Mostimportantly,noheapallocationtookplacetocreatethedata,andso,theGarbageCollectorwouldbecompletelyunawareofitsexistence.
But,ifwecreatedanintegerasamembervariableoftheMonoBehaviourclassdefinition,thenitisnowcontainedwithinaReferencetype(aclass)andmustbeallocatedontheheapalongwithitscontainer:
publicclassTestComponent:MonoBehaviour{
privateint_data=5;
voidStart(){
DoSomething(_data);
}
}
Similarly,ifweputtheintegerintoanindependentclass,thentherulesforReferencetypesstillapply,andtheobjectisallocatedontheheap:
http://freepdf-books.com
![Page 315: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/315.jpg)
publicclassTestData{
publicintdata=5;
}
publicclassTestComponent:MonoBehaviour{
voidStart(){
TestDatadataObj=newTestData();//allocatedontheheap
DoSomething(dataObj.data);
}//'dataObj'isnotdeallocatedhere,butitwillbecomeacandidate
duringthenextgarbagecollection
}
So,thereisabigdifferencebetweentemporarilyallocatingmemorywithinaclassmethodandstoringlong-termdatainaclass’memberdata.Inbothcases,we’reusingaReferencetype(aclass)tostorethedata,whichmeansitcanbereferencedelsewhere.Forexample,imagineDoSomething()storedthereferencetodataObjwithinamembervariable:
privateTestData_testDataObj;
voidDoSomething(TestDatadataObj){
_testDataObj=dataObj;//anewreferencecreated!Thereferenced
objectwillnowbemarkedduringmark-and-sweep
}
Inthiscase,wewouldnotbeabletodeallocatetheobjectpointedtodataObjassoonastheStart()methodendedbecausethetotalnumberofthingsreferencingtheobjectwouldgofrom2to1.Thisisnot0,andhencetheGarbageCollectorwouldstillmarkitduringmark-and-sweep.Wewillalsoneedtoset_testDataObjtonull,ormakeitreferencesomethingelse,beforetheobjectwasnolongerreachable.
NotethataValuetypemusthaveavalue,andcanneverbenull.Ifastack-allocatedValuetypeisassignedtoaReferencetype,thenthedataissimplycopied.ThisistrueevenforarraysoftheValuetypes:
publicclassTestClass{
privateint[]_intArray=newint[1000];//Referencetypefullof
Valuetypes
voidStoreANumber(intnum){
_intArray[0]=num;//storeaValuewithinthearray
}
}
Whentheinitialarrayiscreated(duringobjectinitialization),1,000integerswillbeallocatedontheheapsettoavalueof0.WhentheStoreANumber()methodiscalled,thevalueofnumismerelycopiedintothezerothelementofthearray,ratherthanstoringareferencetoit.
ThesubtlechangeinthereferencingcapabilityiswhatultimatelydecideswhethersomethingisaReferencetypeoraValuetype,andweshouldtrytousestandaloneValuetypeswheneverwehavetheopportunity,sothattheygeneratestackallocationsinsteadofheapallocations.Anysituationwherewe’rejustsendingaroundapieceofdatathatdoesn’tneedtolivelongerthanthecurrentscopeisagoodopportunitytouseaValuetypeinsteadofaReferencetype.Ostensibly,itdoesnotmatterifwepassthedataintoanother
http://freepdf-books.com
![Page 316: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/316.jpg)
methodofthesameclassoramethodofanotherclass;itstillremainsaValuetypethatwillexistonthestackuntilthemethodthatcreateditgoesoutofthescope.
PassbyvalueandpassbyreferenceTechnically,somethingisduplicatedeverytimeadatavalueispassedasanargumentfromonemethodtoanother,andthisistruewhetheritisaValuetypeoraReferencetype.Thisisknownaspassingbyvalue.ThemaindifferenceisthataReferencetypeismerelyapointerwhichconsumesonly4or8bytesinmemory(32-bitor64-bit,dependingonthearchitecture)regardlessofwhatitisactuallypointingto.WhenaReferencetypeispassedasanargumentitisactuallythevalueofthispointerthatgetscopied,whichisveryquicksincethedataisverysmall.
Meanwhile,aValuetypecontainsthefullandcompletebitsofdatastoredwithintheobject.Hence,allofthedataofaValuetypegetscopiedwhenevertheyarepassedbetweenmethods,orstoredinotherValuetypes.Insomecases,itcanmeanthatpassingalargeValuetypeasargumentsaroundtoomuchcanbemorecostlythanjustusingaReferencetype.FormostValuetypes,thisisnotaproblem,sincetheyarecomparableinsizetoapointer.Butthisbecomesimportantwhenwebegintotalkaboutstructs,inthenextsection.
Datacanbepassedaroundbyreferenceaswell,byusingtherefkeyword,butthisisverydifferentfromtheconceptofValueandReferencetypes,anditisveryimportanttokeepthemdistinctinourmindwhenwetrytounderstandwhatisgoingonunderthehood.WecanpassaValuetypebyvalue,orbyreference,andwecanpassaReferencetypebyvalue,orbyreference.Thismeansthattherearefourdistinctdatapassingsituationsthatcanoccurdependingonwhichtypeisbeingpassedandwhethertherefkeywordisbeingusedornot.
Whendataispassedbyreference(evenifitisaValuetype!)thenmakinganychangestothedatawillchangetheoriginal.Forexample,thefollowingcodewouldprintthevalue10:
voidStart(){
intmyInt=5;
DoSomething(refmyInt);
Debug.Log(String.Format("Value={0}",myInt));
}
voidDoSomething(refintval){
val=10;
}
Removingtherefkeywordfrombothplaceswouldmakeitprintthevalue5instead.Thisunderstandingwillcomeinhandywhenwestarttothinkaboutsomeofthemoreinterestingdatatypeswehaveaccessto.Namely,structs,arrays,andstrings.
StructsareValuetypesStructsareaninterestingspecialcaseinC#.IfwecomefromaC++backgroundtoC#,thenwewouldprobablyassumethattheonlydifferencebetweenastructandaclassis
http://freepdf-books.com
![Page 317: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/317.jpg)
thatastructhasadefaultaccessspecifier,public,whileaclassdefaultstoprivate.However,inC#,structsaresimilartoclassesinthattheycancontainotherprivate/protected/publicdata,havemethods,canbeinstantiatedatruntime,andsoon.ThecoredifferencebetweenthetwoisthatstructsareValuetypesandclassesareReferencetypes.
TherearesomeotherimportantdifferencesbetweenhowstructsandclassesaretreatedinC#;structsdon’tsupportinheritance,theirpropertiescannotbegivencustomdefaultvalues(memberdataalwaysdefaultstovaluessuchas0ornull,sinceitisaValuetype),andtheirdefaultconstructorscannotbeoverridden.Thisgreatlyrestrictstheirusagecomparedtoclasses,sosimplyreplacingallclasseswithstructs(undertheassumptionthatitwilljustallocateeverythingonthestack)isnotawisecourseofaction.
However,ifwe’reusingaclassinasituationwhoseonlypurposeistosendablobofdatatosomewhereelseinourapplication,anditdoesnotneedtolastbeyondthecurrentscope,thenweshoulduseastructinstead,sinceaclasswouldresultinaheapallocationfornoparticularlygoodreason:
publicclassDamageResult{
publicCharacterattacker;
publicCharacterdefender;
publicinttotalDamageDealt;
publicDamageTypedamageType;
publicintdamageBlocked;
//etc
}
publicvoidDealDamage(Character_target){
DamageResultresult=CombatSystem.Instance.CalculateDamage(this,
_target);
CreateFloatingDamageText(result);
}
Inthisexample,we’reusingaclasstopassabunchofdatafromonesubsystem(thecombatsystem)toanother(theUIsystem).Theonlypurposeofthisdataistobecalculatedandreadbyvarioussubsystems,sothisisagoodcandidatetoconvertintoastruct.
MerelychangingtheDamageResultdefinitionfromaclasstoastructcouldsaveusquiteafewunnecessarygarbagecollections,sinceitwouldbeallocatedonthestack.
publicstructDamageResult{
//...
}
Thisisnotacatch-allsolution.SincestructsareValuetypes,thismeanssomethingratheruniquewhenitispassedasanargumentbetweenmethods.Aswepreviouslylearned,everytimeaValuetypeispassedasanargumentbetweenonefunctionandanother,itwillbeduplicatedsinceitispassedbyvalue.ThiscreatesaduplicateValuetypeforthenextmethodtouse,whichwillbedeallocatedassoonasthatmethodgoesoutofscope,andsooneachtimeitispassedaround.So,ifastructispassedbyvaluebetweenfivedifferent
http://freepdf-books.com
![Page 318: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/318.jpg)
methodsinalongchain,thenfivedifferentstackcopieswilloccuratthesametime.Recallthatstackdeallocationsarefree,butdatacopyingisnot.
Thecopyingisprettymuchnegligibleforsmallvalues,suchasasingleintegerorfloat,butpassingaroundridiculouslylargedatasetsthroughstructsoverandoveragainisobviouslynotatrivialtaskandshouldbeavoided.Insuchcases,itwouldbewisertopassthestructbyreferenceusingtherefkeywordtominimizetheamountofdatabeingcopiedeachtime(justa32-bitor64-bitintegerforthememoryreference).However,thiscanbedangeroussincepassingbyreferenceallowsanysubsequentmethodstomakechangestothestruct,inwhichcaseitwouldbeprudenttomakeitsdatavaluesreadonly(itcanonlybeinitializedintheconstructor,andneveragain,evenbyitsownmemberfunctions)topreventlaterchanges.
AlloftheaboveisalsotruewhenstructsarecontainedwithinReferencetypes:
publicstructDataStruct{
publicintval;
}
publicclassStructHolder{
publicDataStruct_memberStruct;
publicvoidStoreStruct(DataStructds){
_memberStruct=ds;
}
}
Totheuntrainedeye,theprecedingcodeappearstobeattemptingtostoreastack-allocatedstructwithinaReferencetype.DoesthismeanthataStructHolderobjectontheheapcannowreferenceanobjectonthestack?WhatwillhappenwhentheStoreStruct()methodgoesoutofscopeandthestructiserased?Itturnsoutthatthesearethewrongquestions.
What’sactuallyhappeningisthat,whileaDataStructobject(_memberStruct)hasbeenallocatedontheheapwithintheStructHolderobject,itisstillaValuetypeanddoesnotmagicallytransformintoaReferencetype.So,alloftheusualrulesforValuetypesapply.The_memberStructvariablecannothaveavalueofnullandallofitsfieldswillbeinitializedto0ornullvalues.WhenStoreStruct()iscalled,thedatafromdswillbecopiedinto_memberStruct.Therearenoreferencestostackobjectstakingplace,andthereisnoconcernaboutlostdata.
ArraysareReferencetypesArrayscanpotentiallycontainahugeamountofdatawithinthem,whichmakethemdifficulttotreatasaValuetypesincethere’sprobablynotenoughroomonthestacktosupportthem.Therefore,theyaretreatedasaReferencetypesothattheentiredatasetcanbepassedaroundviaasinglereference,insteadofduplicatingtheentirearrayeverytimeitispassedaround.ThisistrueirrespectiveofwhetherthearraycontainsValuetypesorReferencetypes.
Thismeansthatthefollowingcodewillresultinaheapallocation:
TestStruct[]dataObj=newTestStruct[1000];
http://freepdf-books.com
![Page 319: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/319.jpg)
for(inti=0;i<1000;++i){
dataObj[i].data=i;
DoSomething(dataObj[i]);
}
Thefollowing,functionallyequivalentcode,wouldnotresultinanyheapallocations,sincethestructsareValuetypes,andhencewouldbecreatedonthestack:
for(inti=0;i<1000;++i){
TestStructdataObj=newTestStruct();
dataObj.data=i;
DoSomething(dataObj);
}
Thesubtledifferenceinthesecondcode-blockisthatonlyoneTestStructexistsonthestackatatime(atleastforthisfunctionDoSomething()canpotentiallycreatemore),whereasthefirstblockneedstoallocate1,000ofthemviaanarray.Obviously,thesemethodsarekindofridiculousasthey’rewritten,buttheyillustrateanimportantpointtoconsider.Thecompilerisn’tsmartenoughtoautomaticallyfindthesesituationsforusandmaketheappropriatechanges.OpportunitiestooptimizeourmemoryusagethroughValuetypereplacementswillbeentirelydowntoourabilitytodetectthem,andunderstandwhyachangewillresultinstackallocations,ratherthanheapallocations.
Notethat,whenweallocateanarrayofReferencetypes,we’recreatinganarrayofreferences,whichcaneachreferenceotherlocationsontheheap.However,whenweallocateanarrayofValuetypes,we’recreatingapackedlistofValuetypesontheheap.EachoftheseValuetypeswillbeinitializedwithavalueof0(orequivalent),sincetheycannotbenull,whileeachreferencewithinanarrayofReferencetypeswillalwaysinitializetonull,sincenoreferenceshavebeenassigned,yet.
StringsareimmutableReferencetypesWebrieflytoucheduponthesubjectofstringsbackinChapter2,ScriptingStrategies,butnowit’stimetogointomoredetailaboutwhyproperstringusageisextremelyimportant.
Becausestringsareessentiallyarraysofcharacters(chars),theyareReferencetypes,andfollowallofthesamerulesasotherReferencetypes;thevaluethatisactuallycopiedandpassedbetweenfunctionsismerelyapointer,andtheywillbeallocatedontheheap.
Theconfusingpartreallybeginswhenwediscoverthatstringsareimmutable,meaningtheycannotbechangedafterthey’vebeenallocated.Beinganarrayimpliesthattheentirelistofcharactersmustbecontiguousinmemory,whichcannotbetrueifweallowedstringstoexpandorcontractat-willwithinadynamicmemoryspace(howcouldwequicklyandsafelyexpandthestringifwe’veallocatedsomethingelseimmediatelyafterit?).
Thismeansthat,ifastringismodified,thenanewstringmustbeallocatedtoreplaceit,wherethecontentsoftheoriginalwillbecopiedandmodifiedas-neededintoawholenewcharacterarray.Inwhichcase,theoldversionwillnolongerbereferencedanywhere,willnotbemarkedduringmark-and-sweepandwillthereforeeventuallybegarbage-collected.Asaresult,lazystringprogrammingcanresultinalotofunnecessaryheapallocations
http://freepdf-books.com
![Page 320: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/320.jpg)
andgarbagecollection.
Forexample,ifwebelievedthatstringsworkedjustlikeotherReferencetypes,wemightbeforgivenforassumingthelogoutputofthefollowingtobeWorld!:
voidStart(){
stringtestString="Hello";
DoSomething(testString);
Debug.Log(testString);
}
voidDoSomething(stringlocalString){
localString="World!";
}
However,thisisnotthecase,anditwillstillprintoutHello.WhatisactuallyhappeningisthatthelocalStringvariable,withinthescopeofDoSomething(),startsoffreferencingthesameplaceinmemoryastestString,duetothereferencebeingpassedbyvalue.ThisgivesustworeferencespointingtothesamelocationinmemoryaswewouldexpectifweweredealingwithanyotherReferencetype.Sofar,sogood.
But,assoonaswechangethevalueoflocalString,werunintoalittlebitofaconflict.Stringsareimmutable,andwecannotchangethem,sothereforewemustallocateanewstringcontainingthevalueWorld!andassignitsreferencetothevalueoflocalString;nowthenumberofreferencestotheHellostringreturnsbacktoone.Theoriginalstring(Hello)willremaininmemorybecausethevalueoftestStringhasnotbeenchanged,andthatisstillthevaluewhichwillbeprintedbyDebug.Log().Allwe’vesucceededindoingbycallingDoSomething()iscreatinganewstringontheheapwhichgetsgarbage-collected,anddoesn’tchangeanything.Thisisthetextbookdefinitionofwasteful.
IfwechangethemethoddefinitionofDoSomething()topassthestringbyreference,viatherefkeyword,theoutputwouldindeedchangetoWorld!.ThisiswhatwewouldexpecttohappenwithaValuetype,whichleadsalotofdeveloperstoincorrectlyassumethatstringsareValuetypes.But,thisisanexampleofthefourthandfinaldata-passingcasewhereaReferencetypeisbeingpassedbyreference,whichallowsustochangewhattheoriginalreferenceisreferencing!
NoteSo,torecap;ifwepassaValuetypebyvalue,wecanonlychangethevalueofthecopy.IfwepassaValuetypebyreference,wecanchangetheactualvalueattributedtotheoriginalversion.IfwepassaReferencetypebyvalue,wecanmakechangestotheobjectthattheoriginalreferenceisreferencing.Andfinally,ifwepassaReferencetypebyreference,wecanchangewhichobjecttheoriginalreferenceisreferencing.
Stringconcatenation
Concatenationistheactofappendingstringstooneanothertoformalargerstring.Aswe’velearned,anysuchcasesarelikelytoresultinexcessheapallocations.Thebiggestoffenderinstring-basedmemorywasteisconcatenatingstringsusingthe+and+=operators,becauseoftheallocationchainingeffecttheycause.
http://freepdf-books.com
![Page 321: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/321.jpg)
Forexample,thefollowingcodetriestocombineagroupofstringstogethertoprintsomeinformationaboutacombatresult:
voidCreateFloatingDamageText(DamageResultresult){
stringoutputText=result.attacker.GetCharacterName()+"dealt"+
result.totalDamageDealt.ToString()+""+result.damageType.ToString()+"
damageto"+result.defender.GetCharacterName()+"("+
result.damageBlocked.ToString()+"blocked)";
//...
}
Anexampleoutputofthisfunctionmightbeastringthatreads:
Dwarfdealt15SlashingdamagetoOrc(3blocked)
Thisfunctionfeaturesahandfulofstringliterals(hard-codedstringsthatareallocatedduringapplicationinitialization)suchasdealt,damageto,andblocked.But,becauseoftheusageofvariableswithinthiscombinedstring,itcannotbecompiledawayatbuildtime,andthereforemustbegenerateddynamicallyatruntime.
Anewheapallocationwillbegeneratedeachtimea+,or+=,operatorisexecuted;onlyasinglepairofstringswillbemergedatatime,anditallocatesanewstringeachtime.Then,theresultofonemergerwillbefedintothenext,andmergedwithanotherstring,andsoonuntiltheentirestringhasbeenbuilt.
So,thepreviousexamplewillresultin9differentstringsbeingallocatedallinonego.Allofthefollowingstringswouldbeallocatedtosatisfythisinstruction,andallwouldeventuallyneedtobegarbagecollected(notethattheoperatorsareresolvedfromright-to-left):
"3blocked)"
"(3blocked)"
"Orc(3blocked)"
"damagetoOrc(3blocked)"
"SlashingdamagetoOrc(3blocked)"
"SlashingdamagetoOrc(3blocked)"
"15SlashingdamagetoOrc(3blocked)"
"dealt15SlashingdamagetoOrc(3blocked)"
"Dwarfdealt15SlashingdamagetoOrc(3blocked)"
That’s262charactersbeingused,insteadof49;orbecauseacharisa2-bytedatatype,that’s524bytesofdatabeingallocatedwhenweonlyneed98bytes.Chancesarethat,ifthiscodeexistsinthecodebaseonce,thenitexistsallovertheplace,soforanapplicationthat’sdoingalotoflazystringconcatenationlikethis,thatisatonofmemorybeingwastedongeneratingunnecessarystrings.
TipNotethatbig,constantstringliteralscanbesafelycombinedusingthe+and+=operatorstomakethemmorereadablewithinthecodebase,butonlyiftheywillresultinaconstantstring.Ifso,thecompilerwilltakecareofmergingallofthestringliteralstogetheratcompiletime.
http://freepdf-books.com
![Page 322: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/322.jpg)
BetterapproachesforgeneratingstringsaretouseeithertheStringBuilderclass,oroneofseveralstringclassmethods.
TheStringBuilderclassiseffectivelyamutable(changeable)stringclass.Itworksbyallocatingabuffertocopythetargetstringsintoandallocatesadditionalspacewheneveritisneeded.WecanretrievethestringusingtheToString()methodwhich,naturally,resultsinamemoryallocationfortheresultantstring,butatleastweavoidedalloftheunnecessarystringallocationswewouldhavegeneratedusingthe+or+=operators.
Conventionalwisdomsaysthatifweroughlyknowthefinalsizeoftheresultantstring,thenwecanallocateanappropriatebufferaheadoftimeandsaveourselvesundueallocations.Forourexampleabove,wemightallocateabufferof100characterstomakeroomforlongcharacternamesanddamagevalues:
usingSystem.Text;
//...
StringBuildersb=newStringBuilder(100);
sb.Append(result.attacker.GetCharacterName());
sb.Append("dealt");
sb.Append(result.totalDamageDealt.ToString());
//etc…
stringresult=sb.ToString();
Ifwedon’tknowthefinalsize,thenusingaStringBuilderclassislikelytogenerateabufferthatdoesn’tfitthesizeexactly,orclosely.Wewilleitherendupwithabufferthat’stoolarge(wastedallocationtimeandspace),or,worse,abufferthat’stoosmall,whichmustkeepexpandingaswegeneratethecompletestring.Ifwe’reunsureaboutthetotalsizeofthestring,thenitmightbebesttouseoneofthevariousstringclassmethods.
Therearethreestringclassmethodsavailableforgeneratingstrings;Format(),Join(),andConcat().Eachoperatesslightlydifferently,buttheoveralloutputisthesame;anewstringisallocatedcontainingthecontentsofthestring(s)wepassintothem,anditisalldoneinasingleactionwhichreducesexcessstringallocations.
Itissurprisinglyhardtosaywhichoneofthetwoapproacheswouldbemorebeneficialinagivensituationastherearealotofreallydeepnuancesinvolved.There’salotofdiscussionsurroundingthetopic(justdoaGooglesearchfor"csharpstringconcatenationperformance"andyou’llseewhatImean),sothebestapproachistoimplementoneortheotherusingtheconventionalwisdomdescribedpreviously.Wheneverwerunintobadperformancewithonemethod,weshouldtrytheother,profilethemboth,andpickthebestoptionofthetwo.
BoxingTechnically,everythinginC#isanobject(caveatsapply).Evenprimitivedatatypessuchasints,floats,andboolsarederivedfromSystem.Objectattheirlowestlevel(aReferenceType!),whichallowsthemaccesstohelpermethodssuchasToString(),sothattheycancustomizetheirstringrepresentation.
ButtheseprimitivetypesaretreatedasspecialcasesviabeingtreatedasValuetypes.WheneveraValuetypeisimplicitlytreatedinsuchawaythatitmustactlikeanobject,
http://freepdf-books.com
![Page 323: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/323.jpg)
theCLRautomaticallycreatesatemporaryobjecttostore,or“box”,thevalueinsidesothatitcanbetreatedasatypicalReferencetypeobject.Asweshouldexpect,thisresultsinaheapallocationtocreatethecontainingvessel.
TipNotethatboxingisnotthesamethingasusingValuetypesasmembervariablesofReferencetypes.ItonlytakesplacewhenValuetypesaretreatedlikeobjectsthemselves.
Forexample,thefollowingcodewouldcausethevariableitobeboxedinsideobjectobj:
inti=128;
objectobj=i;
Thefollowingwouldusetheobjectrepresentationobjtoreplacethevaluestoredwithintheinteger,and“unbox”itbackintoaninteger,storingitini.Thefinalvalueofiwouldbe256:
obj=256;
i=(int)obj;
Thesetypescantechnicallybechangeddynamically.ThefollowingisperfectlylegalC#code,whichusesthesameobjectobjasabove,whichwasoriginallyboxedfromanint:
obj=512f;
floatf=(float)obj;
Thefollowingisalsolegal:
obj=false;
boolb=(bool)obj;
Notethatattemptingtounboxobjintoatypethatisn’tthemostrecentlyassignedtypewouldresultinanInvalidCastException.Allofthiscanbealittletrickytowrapourheadarounduntilwerememberthat,attheendoftheday,everythingisjustbitsinmemory.What’simportantisknowingthatwecantreatourprimitivetypesasobjectsbyboxingthem,convertingtheirtypes,andthenunboxingthemintoadifferenttypeatalatertime.
NoteNotethatit’spossibletoconvertaboxedobject’stypeusingoneofthemanySystem.Convert.To…()methods.
Boxingcanbeeitherimplicit,aspertheexamplesabove,orexplicit,bytypecastingtoSystem.Object.Unboxingmustalwaysbeexplicitbytypecastingbacktoitsoriginaltype.WheneverwepassaValuetypeintoamethodwhichusesSystem.Objectasarguments,boxingwillbeappliedimplicitly.
MethodssuchasString.Format(),whichtakeSystem.Objectsasarguments,areonesuchexample.WetypicallyusethembypassinginValuetypessuchasints,floats,boolsandsoon,togenerateastringwith.Boxingisautomaticallytakingplaceinthesesituations,causingadditionalheapallocationswhichweshouldbeawareof.
http://freepdf-books.com
![Page 324: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/324.jpg)
Collections.Generic.ArrayListisanothersuchexample,sinceArrayListsalwayscontainSystem.Objectreferences.
AnytimeweuseafunctiondefinitionthattakesSystem.Objectasarguments,andwe’repassinginValuetypes,weshouldbeawarethatwe’reimplicitlycausingheapallocationsduetoboxing.
http://freepdf-books.com
![Page 325: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/325.jpg)
TheimportanceofdatalayoutTheimportanceofhowourdataisorganizedinmemorycanbesurprisinglyeasytoforgetabout,butcanresultinafairlybigperformanceboostifitishandledproperly.Cachemissesshouldbeavoidedwheneverpossible,whichmeansthatinmostcases,arraysofdatathatarecontiguousinmemoryshouldbeiteratedoversequentially,asopposedtoanyotheriterationstyle.
Thismeansthatdatalayoutisalsoimportantforgarbagecollection,sinceitisdoneinaniterativefashion,andifwecanfindwaystohavetheGarbageCollectorskipoverproblematicareas,thenwecanpotentiallysavealotofiterationtime.
Inessence,wewanttokeeplargegroupsofReferencetypesseparatedfromlargegroupsofValuetypes.IfthereisevenjustoneReferencetypewithinaValuetype,suchasastruct,thentheGarbageCollectorconsiderstheentireobject,andallofitsdatamembers,indirectlyreferenceableobjects.Whenitcomestimetomark-and-sweep,itmustverifyallfieldsoftheobjectbeforemovingon.But,ifweseparatethevarioustypesintodifferentarrays,thenwecanmaketheGarbageCollectorskipthemajorityofthedata.
Forinstance,ifwehaveanarrayofstructscontainingdatalikeso,thentheGarbageCollectorwillneedtoiterateovereverymemberofeverystruct,whichcouldbefairlytimeconsuming:
publicstructMyStruct{
intmyInt;
floatmyFloat;
boolmyBool;
stringmyString;
}
MyStruct[]arrayOfStructs=newMyStruct[1000];
But,ifwereplaceallofthisdatawithsimplearrays,thentheGarbageCollectorwillignorealloftheprimitivedatatypes,andonlycheckthestrings.Thiswouldresultinmuchafastergarbagecollectionsweep:
int[]myInts=newint[1000];
float[]myFloats=newfloat[1000];
bool[]myBools=newbool[1000];
string[]myStrings=newstring[1000];
Thereasonthisworksisbecausewe’regivingtheGarbageCollectorfewerindirectreferencestocheck.Whenthedataissplitintoseparatearrays(Referencetypes),itfindsthreearraysofValuetypes,marksthearrays,andthenimmediatelymovesonbecausethere’snoreasontomarkValuetypes.Itmuststilliteratethroughallofthestringswithinthestringarray,sinceeachisaReferencetypeanditneedstoverifythattherearenoindirectreferenceswithinit.Technically,stringscannotcontainindirectreferences,buttheGarbageCollectorworksatalevelwhereitonlyknowsiftheobjectisaReferencetypeorValuetype.However,wehavestillsparedtheGarbageCollectorfromneedingtoiterateoveranextra3,000piecesofdata(all1,000ints,floats,andbools).
http://freepdf-books.com
![Page 326: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/326.jpg)
TheUnityAPIThereareseveralinstructionswithintheUnityAPIwhichresultinheapmemoryallocations,whichweshouldbeawareof.Thisessentiallyincludeseverythingthatreturnsanarrayofdata.Forexample,thefollowingmethodsallocatememoryontheheap:
GetComponents<T>();//(T[])
Mesh.vertices;//(Vector3[])
Camera.allCameras;//(Camera[])
Suchmethodsshouldbeavoidedwheneverpossible,orattheveryleastcalledonceandcachedsothatwedon’tcausememoryallocationsmoreoftenthannecessary.
NotethatUnityTechnologieshashinteditmightcomeoutwithallocation-lessversionsofthesemethodssometimeinthelifecycleofUnity5.Presumably,itmightlooksomethinglikethewayParticleSystemsallowsaccesstoParticledata,whichinvolvesprovidingaParticle[]arrayreferencetopointtotherequireddata.Thisavoidsallocationsincewereusethesamebufferbetweencalls.
http://freepdf-books.com
![Page 327: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/327.jpg)
TheforeachloopsTheforeachloopkeywordisabitofacontroversialissueinUnitydevelopmentcircles.ItturnsoutthatalotofforeachloopsimplementedinUnityC#codewillincurunnecessaryheapmemoryallocationsduringthesecalls,astheyallocateanEnumeratorobjectasaclassontheheap,insteadofastructonthestack.Italldependsonthegivencollection’simplementationoftheGetEnumerator()method.
ItturnsoutthateverysinglecollectionthathasbeenimplementedintheversionofMonothatcomeswithUnity(Monoversion2.6.5)willcreateclassesinsteadofstructs,whichresultsinheapallocations.Thisincludes,butisnotlimitedto,List<T>,LinkedList<T>,Dictionary<K,V>,ArrayList,andsoon.But,notethatitisactuallysafetouseforeachloopsontypicalarrays!TheMonocompilersecretlyconvertsforeachoverarraysintosimpleforloops.
Thecostisfairlynegligibleastheheapallocationcostdoesnotscalewiththenumberofiterations.OnlyoneEnumeratorobjectisallocated,andreusedoverandoveragain,whichonlycostsahandfulofbytesofmemoryoverall.Sounlessourforeachloopsarebeinginvokedeveryupdate(whichistypicallydangerousinandofitself)thenthecostswillbemostlynegligibleonsmallprojects.Thetimetakentoconverteverythingtoaforloopmaynotbeworththetime.Butit’sdefinitelysomethingtokeepinmindforthenextprojectwebegintowrite.
Ifwe’reparticularlysavvywithC#,VisualStudio,andmanualcompilationoftheMonoassembly,thenwecanhaveVisualStudioperformcodecompilationforus,andcopytheresultingassemblyDLLintotheAssetsfolder,whichwillfixthismistakeforthegenericcollections.
NotethatperformingforeachoveraTransformComponentisatypicalshortcuttoiteratingoveraTransform’schildren.Forexample:
foreach(Transformchildintransform){
//dostuffwith'child'
}
However,thisresultsinthesameheapallocationsmentionedabove.Asaresult,thatcodingstyleshouldbeavoidedinfavorofthefollowing:
for(inti=0;i<transform.childCount;++i){
Transformchild=transform.GetChild(i);
//dostuffwith'child'
}
http://freepdf-books.com
![Page 328: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/328.jpg)
CoroutinesStartingaCoroutinecostsasmallamountofmemorytobeginwith,butnotethatnofurthercostsareincurredwhenthemethodyields.Ifmemoryconsumptionandgarbagecollectionaresignificantconcerns,weshouldtrytoavoidhavingtoomanyshort-livedCoroutines,andavoidcallingStartCoroutine()toomuchduringruntime.
http://freepdf-books.com
![Page 329: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/329.jpg)
ClosuresClosuresareuseful,butdangeroustools.AnonymousmethodsandlambdaexpressionsarenotalwaysClosures,buttheycanbe.Italldependsonwhetherthemethodusesdataoutsideofitsownscopeandparameterlist,ornot.
Forexample,thefollowinganonymousfunctionwouldnotbeaClosure,sinceitisself-containedandfunctionallyequivalenttoanyotherlocallydefinedfunction:
System.Func<int,int>anon=(x)=>{returnx;};
intresult=anon(5);
But,iftheanonymousfunctionpulledindatafromoutsideitself,thenitbecomesaClosure,asit“closestheenvironment”aroundtherequireddata.ThefollowingwouldresultinaClosure:
inti=1024;
System.Func<int,int>anon=(x)=>{returnx+i;};
intresult=anon(5);
Inordertocompletethistransaction,thecompilermustdefineanewclassthatcanreferencetheenvironmentwherethedatavalueiwouldbeaccessible.Atruntimeitcreatesthecorrespondingobjectontheheapandprovidesittotheanonymousfunction.NotethatthisincludesValuetypes(aspertheaboveexample),whichwereoriginallyonthestack,possiblydefeatingthepurposeofthembeingallocatedonthestackinthefirstplace.So,weshouldexpecteachinvocationofthesecondmethodtoresultinheapallocationsandinevitablegarbagecollection.
http://freepdf-books.com
![Page 330: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/330.jpg)
.NETlibraryfunctionsThe.NETlibraryoffersahugeamountofcommonfunctionalitythathelpssolvenumerousproblemsthatprogrammersmaycomeacrossduringday-to-dayimplementation.Mostoftheseclassesandfunctionsareoptimizedforgeneralusecases,whichmaynotbeoptimalforaspecificsituation.Itmaybepossibletoreplaceaparticular.NETlibraryclasswithacustomimplementationthatismoresuitedtoourspecificusecase.
Therearealsotwobigfeaturesinthe.NETlibrarythatoftenbecomebigperformancehogswheneverthey’reused.Thistendstobebecausetheyareonlyincludedasaquick-and-hackysolutiontoagivenproblemwithoutmucheffortputintooptimization.ThesefeaturesareLINQandRegularExpressions.
LINQprovidesawaytotreatarraysofdataasminiaturedatabasesandperformqueriesagainstthemusingSQL-likesyntax.Thesimplicityofitscodingstyle,andcomplexityoftheunderlyingsystem(throughitsusageofClosures),impliesthatithasafairlylargeoverheadcost.LINQisahandytool,butisnotreallyintendedforhigh-performance,real-timeapplicationssuchasgames,anddoesnotevenfunctiononplatformsthatdonotsupportJITcompilation,suchasiOS.
Meanwhile,RegularExpressions,usingtheRegexclass,allowustoperformcomplexstringparsingtofindsubstringsthatmatchaparticularformat,replacepiecesofastring,orconstructstringsfromvariousinputs.RegularExpressionisanotherveryusefultool,buttendstobeoverusedinplaceswhereitislargelyunnecessary,orinseemingly“clever”waystoimplementafeaturesuchastextlocalization,whenstraightforwardstringreplacementwouldbefarmoreefficient.
Specificoptimizationsforbothofthesefeaturesgofarbeyondthescopeofthisbook,astheycouldfillentirevolumesbythemselves.Weshouldeithertrytominimizetheirusageasmuchaspossible,replacetheirusagewithsomethinglesscostly,bringinaLINQorRegexexperttosolvetheproblemforus,ordosomeGooglingonthesubjecttooptimizehowwe’reusingthem.
TipOneofthebestwaystofindthecorrectansweronlineistosimplypostthewronganswer!Peoplewilleitherhelpusoutofkindness,ortakesuchgreatoffensetoourimplementationthattheyconsiderittheircivicdutytocorrectus!Justbesuretodosomekindofresearchonthesubjectfirst.Eventhebusiestofpeoplearegenerallyhappytohelpiftheycanseethatwe’veputinourfairshareofeffortbeforehand.
http://freepdf-books.com
![Page 331: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/331.jpg)
TemporaryworkbuffersIfwegetintothehabitofusinglarge,temporaryworkbuffersforonetaskoranother,thenitjustmakessensethatweshouldlookforopportunitiestoreusethem,insteadofreallocatingthemoverandoveragain,asthislowerstheoverheadinvolvedinallocation,aswellasgarbagecollection(so-called“memorypressure”).Itmightbeworthwhiletoextractsuchfunctionalityfromcase-specificclassesintoagenericgodclassthatcontainsabigworkareaformultipleclassestoreuse.
http://freepdf-books.com
![Page 332: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/332.jpg)
ObjectpoolingSpeakingoftemporaryworkbuffers,objectpoolingisanexcellentwayofbothminimizingandestablishingcontroloverourmemoryusagebyavoidingdeallocationandreallocation.Theideaistoformulateourownsystemforobjectcreation,whichhidesawaywhethertheobjectwe’regettinghasbeenfreshlyallocatedorhasbeenrecycledfromanearlierallocation.Thetypicaltermstodescribethisprocessareto“spawn”and“despawn”theobject,ratherthancreatinganddeletingthem,sinceanytimeanobjectisdespawnedwe’resimplyhidingitfromviewuntilweneeditagain,atwhichpointitisrespawnedandreused.
Let’scoveraquickimplementationofanobjectpoolingsystem.
Thefirstrequirementistoallowthepooledobjecttodecidehowtorecycleitselfwhenthetimecomes.Thefollowinginterfacewillsatisfytherequirementsnicely:
publicinterfaceIPoolableObject{
voidNew();
voidRespawn();
}
Thisinterfacedefinestwomethods;New()andRespawn().Theseshouldbecalledwhentheobjectisfirstcreated,andwhenithasbeenrespawned,respectively.
Thesecondrequirementistoprovideabaseimplementationofthisinterfacethatallowsobjectsofanytypetohandleanybookkeepingrequiredtotakecareoftheinitialcreationandrespawningofobjects.
ThefollowingObjectPoolclassdefinitionisafairlysimpleimplementationoftheobjectpoolingconcept.Itusesgenericstosupportanyobjecttypesolongasitfitstwocriteria;itmustimplementtheIPoolableObjectinterface,andmustallowforaparameter-lessconstructor(thenew()keywordintheclassdeclaration).
publicclassObjectPool<T>whereT:IPoolableObject,new(){
privateStack<T>_pool;
privateint_currentIndex=0;
publicObjectPool(intinitialCapacity){
_pool=newStack<T>(initialCapacity);
for(inti=0;i<initialCapacity;++i){
Spawn();//instantiateapoolofNobjects
}
Reset();
}
publicintCount{
get{return_pool.Count;}
}
publicvoidReset(){
_currentIndex=0;
}
publicTSpawn(){
if(_currentIndex<Count){
Tobj=_pool.Pop();
http://freepdf-books.com
![Page 333: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/333.jpg)
_currentIndex++;
IPoolableObjectip=objasIPoolableObject;
ip.Respawn();
returnobj;
}else{
Tobj=newT();
_pool.Push(obj);
_currentIndex++;
IPoolableObjectip=objasIPoolableObject;
ip.New();
returnobj;
}
}
}
AnexamplePoolableobjectwouldlooklikeso.Itmustimplementtwopublicmethods,New()andRespawn(),whichareinvokedbytheObjectPoolclassattheappropriatetimes:
publicclassTestObject:IPoolableObject{
publicvoidNew(){
//veryfirstinitializationhere
}
publicvoidRespawn(){
//resetdatawhichallowstheobjecttoberecycledhere
}
}
Andfinally,anexampleusagetocreateapoolof100TestObjectobjects:
privateObjectPool<TestObject>_objectPool=newObjectPool<TestObject>
(100);
Thefirst100callstoSpawn()onthe_objectPoolobjectwillcausetheobjectstoberespawnedandprovidedtothecaller.Ifthestackrunsoutofspace,thenitwilladdevenmoreTestObjectobjectstothestack.Finally,ifReset()iscalledon_objectPool,thenitwillbeginagainfromthestart,recyclingobjectsandprovidingthemtothecaller.
Notethatthispoolingsolutionwillnotworkforclasseswehaven’tdefined,andcannotderivefrom,suchasVector3,andQuaternion.Inthesecases,wewouldneedtodefineacontainingclass:
publicclassPoolableVector3:IPoolableObject{
publicVector3vector=newVector3();
publicvoidNew(){
Reset();
}
publicvoidRespawn(){
Reset();
http://freepdf-books.com
![Page 334: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/334.jpg)
}
publicvoidReset(){
vector.x=vector.y=vector.z=0f;
}
}
Wecouldextendthissysteminanumberofways,suchasdefiningaDespawn()methodtohandledestructionoftheobject,makinguseoftheIDisposableinterfaceandusingblockswhenwewishtoautomaticallyspawnanddespawnobjectswithinasmallscope,and/orallowingobjectsinstantiatedoutsidethepooltobeaddedtoit.
http://freepdf-books.com
![Page 335: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/335.jpg)
http://freepdf-books.com
![Page 336: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/336.jpg)
PrefabpoolingThepreviouspoolingsolutionisusefulfortypicalclasses,butitwon’tworkforspecialUnityobjects,suchasGameObjectandMonoBehaviour.Theseobjectstendtoconsumealargechunkofourruntimememory,cancostusagreatdealofCPUusagewhenthey’recreatedanddestroyed,andtendtoriskalargeamountofgarbagecollectionatruntime.Inotherwords,themaingoalofPrefabpoolingistopushtheoverwhelmingmajorityofobjectinstantiationtoSceneinitialization,ratherthanlettingthemgetcreatedatruntime.ThiscanprovidesomebigruntimeCPUsavings,andavoidsalotofspikescausedbyobjectcreation/destructionandgarbagecollection,attheexpenseofSceneloadingtimes,andruntimememoryconsumption.Asaresult,therearequiteafewpoolingsolutionsavailableontheAssetStoreforhandlingthistask,withvaryingdegreesofsimplicity,quality,andfeaturesets.
NoteItisoftenrecommendedthatpoolingshouldbeimplementedinanygamethatintendstodeployonmobiledevices,duetothegreateroverheadcostsinvolvedintheallocationanddeallocationofmemorycomparedtodesktopapplications.
However,creatingapoolingsolutionisaninterestingtopic,andbuildingonefromscratchisagreatwayofgettingtogripswithalotofimportantinternalUnityEnginebehavior.Also,knowinghowsuchasystemisbuiltmakesiteasiertoextendifwewishittomeettheneedsofourparticulargame,ratherthanrelyingonaprebuiltsolution.
ThegeneralideaofPrefabpoolingistocreateasystemthatcontainslistsofactiveandinactiveGameObjectsthatwereallinstantiatedfromthesamePrefabreference.Thefollowingdiagramshowshowthesystemmightlookafterseveralspawns,despawns,andrespawnsofvariousobjectsderivedfromfourdifferentPrefabs(Orc,Troll,Ogre,andDragon):
http://freepdf-books.com
![Page 337: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/337.jpg)
NoteNotethattheHeapMemoryarearepresentstheobjectsastheyexistinmemory,whilethePoolingSystemarearepresentsreferencestothoseobjects.
Inthisexample,severalinstancesofeachPrefabwereinstantiated(11Orcs,8Trolls,5Ogres,and1Dragon).Currentlyonlyelevenoftheseobjectsareactive,whiletheotherfourteenhavepreviouslybeendespawned,andareinactive.Notethatthedespawnedobjectsstillexistinmemory,althoughtheyarenotvisibleandcannotinteractwiththegameworlduntiltheyhavebeenrespawned.Naturally,thiscostsusaconstantamountofheapmemoryatruntimeinordertomaintaintheinactiveobjects,butwhenanewobjectisinstantiated,wecanreuseoneoftheexistinginactiveobjects,ratherthanallocatingmorememoryinordertosatisfytherequest.ThissavessignificantruntimeCPUcostsduringobjectcreationanddestruction,andavoidsgarbagecollection.
ThefollowingdiagramshowsthechainofeventsthatneedstooccurwhenanewOrcisspawned:
ThefirstobjectintheInactiveOrcpool(Orc7)isreactivatedandmovedintotheActivepool.Wenowhave6activeOrcs,and5inactiveOrcs.
ThefollowingfigureshowstheorderofeventswhenanOgreobjectisdespawned:
http://freepdf-books.com
![Page 338: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/338.jpg)
ThistimetheobjectisdeactivatedandmovedfromtheActivepoolintotheInactivepool,leavinguswith1activeOgreand4inactiveOgres.
Finally,thefollowingdiagramshowswhathappenswhenanewobjectisspawned,buttherearenoinactiveobjectstosatisfytherequest:
Inthisscenario,morememorymustbeallocatedtoinstantiatethenewDragonobject,sincetherearenoDragonobjectsinitsInactivepooltoreuse.Therefore,inordertoavoidruntimememoryallocationsforourGameObjects,itiscriticalthatweknowbeforehandhowmanywewillneed.Thiswillvarydependingonthetypeofobjectinquestion,and
http://freepdf-books.com
![Page 339: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/339.jpg)
requiresoccasionaltestinganddebuggingtoensurewehaveasensiblenumberofeachPrefabinstantiatedatruntime.
Withallofthisinmind,let’screateapoolingsystemforPrefabs!
http://freepdf-books.com
![Page 340: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/340.jpg)
PoolableComponentsLet’sfirstdefineaninterfaceforaPoolableComponent:
publicinterfaceIPoolableComponent{
voidSpawned();
voidDespawned();
}
TheapproachforIPoolableComponentwillbeverydifferentfromtheapproachtakenforIPoolableObject.TheobjectsbeingcreatedthistimeareGameObjects,whicharealottrickiertoworkwiththanstandardobjectsbecauseofhowmuchoftheirruntimebehaviorisalreadyhandledthroughtheUnityEngine,andhowlittleaccesswehavetoit.
GameObjectsdonotgiveusaccesstoanequivalentNew()methodthatwecaninvokeanytimetheobjectiscreated,andwecannotderivefromtheGameObjectclassinordertoimplementone.GameObjectsarecreatedeitherbyplacingtheminaScene,orbyinstantiatingthematruntimethroughGameObject.Instantiate(),andtheonlyinputswecanapplyareaninitialpositionandrotation.Ofcourse,theirComponentshaveanAwake()methodwecandefine,whichisinvokedthefirsttimetheComponentisbroughttolife,butthisismerelyacompositionalobject—it’snottheactualparentobjectwe’respawninganddespawning.
So,becauseweonlyhavecontroloveraGameObjectclass’sComponents,itisassumedthattheIPoolableComponentinterfaceisimplementedbyatleastoneoftheComponentsthatisattachedtotheGameObjectwewishtopool.
TheSpawned()methodshouldbeinvokedoneveryimplementingComponenteachtimethepooledGameObjectisrespawned,whiletheDespawned()methodgetsinvokedwheneveritisdespawned.ThisgivesusentrypointstocontrolthedatavariablesandbehaviorduringthecreationanddestructionoftheparentGameObject.
TheactofdespawningaGameObjectistrivial;turnitsactiveflagtofalse(throughSetActive()).ThisdisablestheColliderandRigidbodyforphysicscalculations,removesitfromthelistofrenderableobjects,andessentiallytakescareofdisablinginteractionswithallbuilt-inUnityEnginesubsystemsinasinglestroke.TheonlyexceptionisanyCoroutinesthatarecurrentlyinvokingontheobject,sinceaswelearnedearlierinChapter2,ScriptingStrategies,CoroutinesareinvokedindependentlyofUpdate()andGameObjectactivity.WewillthereforeneedtocallStopCoroutine(),orStopAllCoroutines()duringthedespawningofsuchobjects.
Inaddition,Componentstypicallyhookintoourowncustomgameplaysubsystemsaswell,andsotheDespawn()methodgivesourComponentstheopportunitytotakecareofanycustomcleanupbeforeshuttingdown.Forexample,wewouldprobablywanttouseDespawn()toderegistertheComponentfromtheMessagingSystemwedefinedbackinChapter2,ScriptingStrategies.
Unfortunately,successfullyrespawningtheGameObjectisalotmorecomplicated.Whenwerespawnanobject,therewillbemanysettingsthatwereleftbehindwhentheobject
http://freepdf-books.com
![Page 341: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/341.jpg)
waspreviouslyactive,andthesemustberesetinordertoavoidconflictingbehaviors.AcommonproblemwiththisisRigidbodyvelocity.Ifthisvalueisnotexplicitlyresetbeforetheobjectisreactivated,thenthenewlyrespawnedobjectwillcontinuemovingwiththesamevelocitytheoldversionhadwhenitwasdespawned.
Thisproblembecomesfurthercomplicatedbythefactthatbuilt-inComponentsaresealed,andthereforecannotbederivedfrom.So,toavoidtheseissues,wecancreateacustomComponentthatresetstheattachedRigidbodywhenevertheobjectisdespawned:
publicclassResetPooledRigidbodyComponent:MonoBehaviour,
IPoolableComponent{
Rigidbody_body;
publicvoidSpawned(){}
publicvoidDespawned(){
if(_body==null){
_body=GetComponent<Rigidbody>();
if(_body==null){
//noRigidbody!
return;
}
}
_body.velocity=Vector3.zero;
_body.angularVelocity=Vector3.zero;
}
}
Notethatthebestplacetoperformthistaskisduringdespawning,becausewecannotbecertaininwhatordertheGameObjectclass’sIPoolableComponentinterfaceswillhavetheirSpawned()methodsinvoked.ItisunlikelythatanotherIPoolableComponentwillchangetheobject’svelocityduringdespawning,butitispossiblethatadifferentIPoolableComponentattachedtothesameobjectmightwanttosettheRigidbody’sinitialvelocitytosomeimportantvalueduringitsownSpawned()method.Ergo,performingthevelocityresetduringtheResetPooledRigidbodyComponentclass’sSpawned()methodcouldpotentiallyconflictwithotherComponentsandcausesomeveryconfusingbugs.
TipInfact,creatingPoolableComponentsthatarenotself-contained,andtendtotinkerwithotherComponentslikethis,isoneofthebiggestdangersofimplementingapoolingsystem.Weshouldminimizesuchimplementations,androutinelyverifythemwhenwe’retryingtodebugstrangeissuesinourgame.
Forthesakeofillustration,hereisthedefinitionofasimplePoolableComponentthatreplacestheTestMessageListenerclasswedefinedbackinChapter2,ScriptingStrategies.ThisComponentautomaticallyhandlessomebasictaskseverytimetheobjectisspawnedanddespawned:
publicclassPoolableTestMessageListener:MonoBehaviour,
IPoolableComponent{
publicvoidSpawned(){
MessagingSystem.Instance.AttachListener(typeof(MyCustomMessage),
this.HandleMyCustomMessage);
http://freepdf-books.com
![Page 342: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/342.jpg)
}
boolHandleMyCustomMessage(BaseMessagemsg){
MyCustomMessagecastMsg=msgasMyCustomMessage;
Debug.Log(string.Format("Gotthemessage!{0},{1}",
castMsg._intValue,castMsg._floatValue));
returntrue;
}
publicvoidDespawned(){
if(MessagingSystem.IsAlive){
MessagingSystem.Instance.DetachListener(typeof(MyCustomMessage),
this.HandleMyCustomMessage);
}
}
}
http://freepdf-books.com
![Page 343: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/343.jpg)
ThePrefabpoolingsystemHopefully,wenowhaveanunderstandingofwhatweneedfromourpoolingsystem,soallthat’sleftistoimplementit.Therequirementsareasfollows:
ItmustacceptrequeststospawnaGameObjectfromaPrefab,aninitialposition,andaninitialrotation:
Ifadespawnedversionalreadyexists,itshouldrespawnthefirstavailableoneIfitdoesnotexist,thenitshouldinstantiateanewGameObjectfromthePrefabIneithercase,theSpawned()methodshouldbeinvokedonallIPoolableComponentinterfacesattachedtotheGameObject
ItmustacceptrequeststodespawnaspecificGameObject:
Iftheobjectismanagedbythepoolingsystem,itshoulddeactivateitandcalltheDespawned()methodonallIPoolableComponentinterfacesattachedtotheGameObjectIftheobjectisnotmanagedbythepoolingsystem,itshouldsendanerror
Therequirementsarefairlystraightforward,buttheimplementationrequiressomeinvestigationifwewishtomakethesolutionperformance-friendly.Firstly,atypicalSingletonwouldbeagoodchoiceforthemainentrypoint,sincewewantthissystemtobegloballyaccessiblefromanywhere:
publicstaticclassPrefabPoolingSystem{
}
ThemaintaskforobjectspawninginvolvesacceptingaPrefabreference,andfiguringifwehaveanydespawnedGameObjectsthatwereoriginallyinstantiatedfromthesamereference.Todothis,wewillessentiallywantourpoolingsystemtokeeptrackoftwodifferentlistsforanygivenPrefabreference:alistofactive(spawned)GameObjects,andalistofinactive(despawned)objectsthatwereinstantiatedfromit.Thisdatawouldbebestabstractedintoaseparateclass,whichwewillnamePrefabPool.
Inordertomaximizetheperformanceofthissystem(andhencemakethelargestgainspossible,relativetojustallocatinganddeallocatingobjectsfrommemoryallofthetime),wewillwanttousesomefastdatastructuresinordertoacquirethecorrespondingPrefabPoolobjectswheneveraspawnordespawnrequestcomesin.
BecausespawninginvolvesbeinggivenaPrefab,wewillwantonedatastructurethatcanquicklymapPrefabstothePrefabPoolthatmanagesthem.AndbecausedespawninginvolvesbeinggivenaGameObject,wewillwantanotherdatastructurethatcanquicklymapspawnedGameObjectstothePrefabPoolthatoriginallyspawnedthem.ADictionaryisagoodchoiceforbothoftheseneeds.
Let’sdefinethesemapsinourpoolingsystem:
publicstaticclassPrefabPoolingSystem{
staticDictionary<GameObject,PrefabPool>_prefabToPoolMap=new
Dictionary<GameObject,PrefabPool>();
http://freepdf-books.com
![Page 344: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/344.jpg)
staticDictionary<GameObject,PrefabPool>_goToPoolMap=new
Dictionary<GameObject,PrefabPool>();
}
Nextwe’lldefinewhathappenswhenwespawnanobject:
publicstaticGameObjectSpawn(GameObjectprefab,Vector3position,
Quaternionrotation){
if(!_prefabToPoolMap.ContainsKey(prefab)){
_prefabToPoolMap.Add(prefab,newPrefabPool());
}
PrefabPoolpool=_prefabToPoolMap[prefab];
GameObjectgo=pool.Spawn(prefab,position,rotation);
_goToPoolMap.Add(go,pool);
returngo;
}
TheSpawn()methodwillbegivenaPrefabreference,aninitialposition,andaninitialrotation.WeneedtofigureoutwhichPrefabPoolthePrefabbelongsto(ifany),askittospawnanewGameObjectusingthedataprovided,andthenreturnthespawnedobjecttotherequestor.Wefirstcheckour“Prefab-to-Pool”map,toseeifapoolalreadyexistsforthisPrefab.Ifnot,wequicklycreateone.Ineithercase,wethenaskthePrefabPooltospawnusanewobject.ThePrefabPoolwilleitherenduprespawninganobjectthatwasdespawnedearlier,orinstantiateanewone(iftherearen’tanyinactiveinstancesleft).
Eitherway,thisclassdoesn’tparticularlycare.ItjustwantstheinstancegeneratedbythePrefabPoolclasssothatitcanbeenteredintothe“GameObject-to-Pool”mapandreturnedtotherequestor.
Forconvenience,wecanalsodefineanoverloadwhichplacestheobjectattheworld’scenter(usefulforGameObjectsthataren’tvisible,andjustneedtoexistsomewhere):
publicstaticGameObjectSpawn(GameObjectprefab){
returnSpawn(prefab,Vector3.zero,Quaternion.identity);
}
NoteNotethatnoactualspawninganddespawningaretakingplace,yet.ThistaskwilleventuallybehandledwithinthePrefabPoolclass.
DespawninginvolvesbeinggivenaGameObject,andthenfiguringoutwhichPrefabPoolismanagingit.ThiscouldbeachievedbyiteratingthroughourPrefabPoolclassesandcheckingiftheycontainthegivenGameObject.ButifweendupgeneratingalotofPrefabPools,thenthisiterativeprocesscantakeawhile.WewillalwaysendupwithasmanyPrefabPoolclassesaswehavePrefabs(atleastsolongaswemanageallofthemthroughthepoolingsystem).Mostprojectstendtohavedozens,hundreds,ifnotthousandsofdifferentPrefabs.
So,theGameObject-to-PoolmapismaintainedtoensurethatwealwayshaverapidaccesstothePrefabPoolthatoriginallyspawnedtheobject.ItcanalsobeusedtoquicklyverifyifthegivenGameObjectisevenmanagedbythepoolingsystemtobeginwith.Hereisthemethoddefinitionforthedespawningmethod,whichtakescareofthesetasks:
http://freepdf-books.com
![Page 345: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/345.jpg)
publicstaticboolDespawn(GameObjectobj){
if(!_goToPoolMap.ContainsKey(obj)){
Debug.LogError(string.Format("Object{0}notmanagedbypool
system!",obj.name));
returnfalse;
}
PrefabPoolpool=_goToPoolMap[obj];
if(pool.Despawn(obj)){
_goToPoolMap.Remove(obj);
returntrue;
}
returnfalse;
}
TipNotethattheDespawn()methodofbothPrefabPoolingSystemandPrefabPoolreturnsaBooleanthatcanbeusedtoverifywhetherornottheobjectwassuccessfullydespawned.
Asaresult,thankstothetwomapswe’remaintaining,wecanquicklyaccessthePrefabPoolthatmanagesthegivenreference,andthissolutionwillscaleforanynumberofPrefabthatthesystemmanages.
http://freepdf-books.com
![Page 346: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/346.jpg)
PrefabpoolsNowthatwehaveasystemthatcanhandlemultiplePrefabpoolsautomatically,theonlythingleftistodefinethebehaviorofthepools.Asmentionedpreviously,wewillwantthePrefabPoolclasstomaintaintwodatastructures:oneforactive(spawned)objectsthathavebeeninstantiatedfromthegivenPrefabandanotherforinactive(despawned)objects.
Technically,thePrefabPoolingSystemclassalreadymaintainsamapofwhichPrefabisgovernedbywhichPrefabPool,sowecanactuallysavealittlememorybymakingthePrefabPoolaslavetothePrefabPoolingSystemclass,bynothavingitkeeptrackofwhichPrefabitismanaging.Consequently,thetwodatastructuresaretheonlymembervariablesthePrefabPoolneedstokeeptrackof.
However,foreachspawnedGameObject,itmustalsomaintainalistofallofitsIPoolableComponentreferencesinordertoinvoketheSpawned()andDespawned()methodsonthem.Acquiringthesereferencescanbeacostlyoperationtoperformatruntime,soitwouldbebesttocachethedatainasimplestruct:
publicstructPoolablePrefabData{
publicGameObjectgo;
publicIPoolableComponent[]poolableComponents;
}
ThisstructwillcontainareferencetotheGameObject,andtheprecachedlistofitsIPoolableComponents.
NowwecandefinethememberdataofourPrefabPoolclass:
publicclassPrefabPool{
Dictionary<GameObject,PoolablePrefabData>_activeList=new
Dictionary<GameObject,PoolablePrefabData>();
Queue<PoolablePrefabData>_inactiveList=newQueue<PoolablePrefabData>
();
}
ThedatastructurefortheactivelistshouldbeadictionaryinordertodoaquicklookupforthecorrespondingPoolablePrefabDatafromanygivenGameObjectreference.Thiswillbeusefulduringobjectdespawning.
Meanwhile,theinactivedatastructureisdefinedasaQueue,butitwillworkequallywellasaList,aStack,orreallyanydatastructurethatneedstoregularlyexpandorcontract,andwhereweonlyneedtopopitemsfromoneendofthelist,sinceitdoesnotmatterwhichobjectitis.Itonlymattersthatweretrieveoneofthem.AQueueisusefulinthiscasebecausewecanbothretrieveandremovetheobjectfromthedatastructureinasinglecall.
http://freepdf-books.com
![Page 347: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/347.jpg)
ObjectspawningLet’sdefinewhatitmeanstospawnaGameObjectinthecontextofourpoolingsystem:atsomepoint,PrefabPoolwillgetarequesttospawnaGameObjectfromagivenPrefab,ataparticularpositionandrotation.ThefirstthingweshouldcheckiswhetherornotwehaveanyinactiveinstancesofthePrefab.Ifso,thenwecanpopthenextavailableonefromtheQueueandrespawnit.Ifnot,thenweneedtoinstantiateanewGameObjectfromthePrefabusingGameObject.Instantiate().Atthismoment,weshouldalsocreateaPoolablePrefabDataobjecttostoretheGameObjectreference,andacquirethelistofallIPoolableComponentsthatareattachedtoit.
Eitherway,wecannowactivatetheGameObject,setitspositionandrotation,andcalltheSpawned()methodonallofitsIPoolableComponents.Oncetheobjecthasbeenrespawned,wecanaddittothelistofactiveobjectsandreturnittotherequestor.
HereisthedefinitionoftheSpawn()methodthatdefinesthisbehavior:
publicGameObjectSpawn(GameObjectprefab,Vector3position,Quaternion
rotation){
PoolablePrefabDatadata;
if(_inactiveList.Count>0){
data=_inactiveList.Dequeue();
}else{
//instantiateanewobject
GameObjectnewGO=GameObject.Instantiate(prefab,position,
rotation)asGameObject;
data=newPoolablePrefabData();
data.go=newGO;
data.poolableComponents=newGO.GetComponents<IPoolableComponent>
();
}
data.go.SetActive(true);
data.go.transform.position=position;
data.go.transform.rotation=rotation;
for(inti=0;i<data.poolableComponents.Length;++i){
data.poolableComponents[i].Spawned();
}
_activeList.Add(data.go,data);
returndata.go;
}
http://freepdf-books.com
![Page 348: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/348.jpg)
InstanceprespawningBecauseweareusingGameObject.Instantiate()wheneverthepoolhasrunoutofdespawnedinstances,thissystemdoesnotcompletelyridusofruntimeobjectinstantiationandhence,heapmemoryallocation.It’simportanttoprespawntheexpectednumberofinstancesthatwewillneedduringthelifetimeofthecurrentScene,sothatwedon’tneedtoinstantiatemoreduringruntime.
TipItwouldbewastefultoprespawn100explosionparticleeffects,ifthemostwewilleverexpecttoseeintheSceneatanygiventimeisthreeorfour.Conversely,spawningtoofewinstanceswillcauseexcessiveruntimememoryallocations,andthegoalofthissystemistopushthemajorityofallocationtothestartofaScene’slifetime.Weneedtobecarefulabouthowmanyinstanceswemaintaininmemorysothatwedon’twastemorememoryspacethannecessary.
Let’sdefineamethodinourPrefabPoolingSystemclassthatwecanusetoquicklyprespawnagivennumberofobjectsfromaPrefab.ThisessentiallyinvolvesspawningNobjects,andthenimmediatelydespawningthemall:
publicstaticvoidPrespawn(GameObjectprefab,intnumToSpawn){
List<GameObject>spawnedObjects=newList<GameObject>();
for(inti=0;i<numToSpawn;i++){
spawnedObjects.Add(Spawn(prefab));
}
for(inti=0;i<numToSpawn;i++){
Despawn(spawnedObjects[i]);
}
spawnedObjects.Clear();
}
WewouldusethismethodduringSceneinitialization,toprespawnacollectionofobjectstouseinthelevel.Forexample:
publicclassOrcPreSpawner:MonoBehaviour
[SerializeField]GameObject_orcPrefab;
[SerializeField]int_numToSpawn=20;
voidStart(){
PrefabPoolingSystem.Prespawn(_orcPrefab,_numToSpawn);
}
}
http://freepdf-books.com
![Page 349: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/349.jpg)
ObjectdespawningFinally,thereistheactofdespawningtheobjects.Asmentionedpreviously,thisprimarilyinvolvesdeactivatingtheobject,butwealsoneedtotakecareofvariousbookkeepingtasksandinvokingDespawned()onallofitsIPoolableComponentreferences.
HereisthemethoddefinitionforthePrefabPoolclass’sDespawn()method:
publicboolDespawn(GameObjectobjToDespawn){
if(!_activeList.ContainsKey(objToDespawn)){
Debug.LogError("ThisObjectisnotmanagedbythisobjectpool!");
returnfalse;
}
PoolablePrefabDatadata=_activeList[objToDespawn];
for(inti=0;i<data.poolableComponents.Length;++i){
data.poolableComponents[i].Despawned();
}
data.go.SetActive(false);
_activeList.Remove(objToDespawn);
_inactiveList.Enqueue(data);
returntrue;
}
Firstweverifytheobjectisbeingmanagedbythepool,andthenwegrabthecorrespondingPoolablePrefabDatainordertoaccessthelistofIPoolableComponentreferences.OnceDespawned()hasbeeninvokedonallofthem,wedeactivatetheobject,removeitfromtheactivelist,andpushitintotheinactivequeuesothatitcanberespawnedlater.
http://freepdf-books.com
![Page 350: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/350.jpg)
PrefabpooltestingThefollowingclassdefinitionallowsustoperformasimplehands-ontestwiththePrefabPoolingSystemclass.ItwillsupportthreePrefabs,andprespawnfiveinstancesduringapplicationinitialization.Wecanpressthe1,2,or3keystospawnaninstanceofeachtype,andthenpressQ,W,orEtodespawnarandominstanceofeachtype.
publicclassPoolTester:MonoBehaviour{
[SerializeField]GameObject_prefab1;
[SerializeField]GameObject_prefab2;
[SerializeField]GameObject_prefab3;
List<GameObject>_go1=newList<GameObject>();
List<GameObject>_go2=newList<GameObject>();
List<GameObject>_go3=newList<GameObject>();
voidStart(){
PrefabPoolSystem_AsSingleton.Prespawn(_prefab1,5);
PrefabPoolSystem_AsSingleton.Prespawn(_prefab2,5);
PrefabPoolSystem_AsSingleton.Prespawn(_prefab3,5);
}
voidUpdate(){
if(Input.GetKeyDown(KeyCode.Alpha1)){SpawnObject(_prefab1,
_go1);}
if(Input.GetKeyDown(KeyCode.Alpha2)){SpawnObject(_prefab2,
_go2);}
if(Input.GetKeyDown(KeyCode.Alpha3)){SpawnObject(_prefab3,
_go3);}
if(Input.GetKeyDown(KeyCode.Q)){DespawnRandomObject(_go1);}
if(Input.GetKeyDown(KeyCode.W)){DespawnRandomObject(_go2);}
if(Input.GetKeyDown(KeyCode.E)){DespawnRandomObject(_go3);}
}
voidSpawnObject(GameObjectprefab,List<GameObject>list){
GameObjectobj=PrefabPoolingSystem.Spawn(prefab,
Random.insideUnitSphere*8f,Quaternion.identity);
list.Add(obj);
}
voidDespawnRandomObject(List<GameObject>list){
if(list.Count==0){
//Nothingtodespawn
return;
}
inti=Random.Range(0,list.Count);
PrefabPoolingSystem.Despawn(list[i]);
list.RemoveAt(i);
}
}
OncewespawnmorethanfiveinstancesofanyofthePrefabs,itwillneedtoinstantiatea
http://freepdf-books.com
![Page 351: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/351.jpg)
newoneinmemory,costingussomememoryallocation.But,ifweobservetheMemoryAreaintheProfiler,whileweonlyspawnanddespawninstancesthatalreadyexist,thenwewillnoticethatabsolutelynonewallocationstakeplace.
http://freepdf-books.com
![Page 352: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/352.jpg)
PrefabpoolingandSceneloadingThereisonesubtlecaveattothissystemthathasnotyetbeenmentioned:thePrefabPoolingSystemclasswilloutlastScenelifetimesinceitisastaticclass.Thismeansthat,whenanewSceneisloaded,thepoolingsystem’sdictionarieswillattempttomaintainreferencestoanypooledinstancesfromthepreviousScene,butUnityforciblydestroystheseobjectsregardlessofthefactthatwearestillkeepingreferencestothem(unlesstheyweresettoDontDestroyOnLoad()!),andsothedictionarieswillbefullofnullreferences.ThiswouldcausesomeseriousproblemsforthenextScene.
WeshouldthereforecreateamethodinPrefabPoolingSystemthatresetsthepoolingsysteminpreparationforthislikelyevent.ThefollowingmethodshouldbecalledbeforeanewSceneisloaded,sothatitisreadyforanyearlycallstoPrespawn()inthenextScene:
publicstaticvoidReset(){
_prefabToPoolMap.Clear();
_goToPoolMap.Clear();
}
Notethat,ifwealsoinvokeagarbagecollectionduringScenetransitions,there’snoneedtoexplicitlyemptythePrefabPoolsthesedictionarieswerereferencing.SincetheseweretheonlyreferencestothePrefabPoolobjects,theywillbedeallocatedduringthenextgarbagecollection.Ifwearen’tinvokinggarbagecollectionbetweenScenes,thenthePrefabPoolandPooledPrefabDataobjectswillremaininmemoryuntilthattime.
http://freepdf-books.com
![Page 353: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/353.jpg)
PrefabpoolingsummaryWehavefinallysolvedtheproblemofruntimememoryallocationsforGameObjectsandPrefabsbut,asaquickreminder,weneedtobeawareofthefollowingcaveats:
Weneedtobecarefulaboutproperlyresettingimportantdatainrespawnedobjects(suchasRigidbodyvelocity)Wemustensurewedon’tprespawntoofew,ortoomany,instancesofaPrefabWeshouldbecarefuloftheorderofexecutionofSpawned()andDespawned()methodsonIPoolableComponentsWemustcallReset()onPrefabPoolingSystembeforeSceneloading
Thereareseveralotherfeatureswecouldimplement.Thesewillbeleftasacademicexercisesifwewishtoextendthissysteminthefuture:
AnyIPoolableComponentsaddedtotheGameObjectafterinitializationwillnotbeinvoked.WecouldfixthisbychangingPrefabPooltokeepacquiringIPoolableComponentseverytimeSpawned()andDespawned()areinvoked,atthecostofadditionaloverheadduringspawning/despawning.IPoolableComponentsattachedtochildrenofthePrefab’srootwillnotbecounted.ThiscouldbefixedbychangingPrefabPooltouseGetComponentsInChildren<T>,atthecostofadditionaloverheadifwe’reusingPrefabswithdeephierarchies.PrefabinstancesthatalreadyexistintheScenewillnotbemanagedbythepoolingsystem.WecouldcreateaComponentthatneedstobeattachedtosuchobjectsandthatnotifiesthePrefabPoolingSystemclassofitsexistenceandpassesthereferenceintothecorrespondingPrefabPool.WecouldimplementawayforIPoolableComponentstosetapriorityduringacquisition,anddirectlycontroltheorderofexecutionfortheirSpawned()andDespawned()methods.WecouldaddcountersthatkeeptrackofhowlongobjectshavebeensittingintheInactivelistrelativetototalScenelifetime,andprintoutthedataduringshutdown.Thiscouldtelluswhetherornotwe’represpawningtoomanyinstancesofagivenPrefab.ThissystemwillnotinteractkindlywithPrefabinstancesthatsetthemselvestoDontDestroyOnLoad().ItmightbewisetoaddaBooleantoeverySpawn()calltosaywhethertheobjectshouldpersistornot,andkeeptheminaseparatedatastructurethatisnotclearedoutduringReset().WecouldchangeSpawn()toacceptanargumentthatallowstherequestortopasscustomdatatotheSpawned()functionofIPoolableObjectforinitializationpurposes.ThiscoulduseasystemsimilartohowcustommessageobjectswerederivedfromtheBaseMessageclassforourMessagingSystembackinChapter2,ScriptingStrategies.
http://freepdf-books.com
![Page 354: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/354.jpg)
http://freepdf-books.com
![Page 355: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/355.jpg)
ThefutureofMonoandUnityAsweknow,UnitydoesnotusethelatestandgreatestMonoprojectcodefromhttp://www.mono-project.com,butaninternally-customizedversionwithsomeinternalbugfixes.
NoteTheactualMonotweaksmadebyUnityTechnologiescanbefoundinthefollowingGitHubrepository:
https://github.com/Unity-Technologies/mono/
AsanunfortunateconsequenceofhowvariouscomponentsoftheMonoFrameworkarelicensed,UnityTechnologieshasonlybeenabletoupdateMonoonaninfrequentbasis.TheoccasionsonwhichthistaskwereaccomplishedwaswiththereleaseofUnity4,whentheyupgradedtoMono2.6,andshortlyafterwardsversion2.6.5backinmid-2010,whichsupports.NET2.0/3.5features.But,atthetimeofpublication,thelatestversionofMono,version4.0,wasreleasedinMay2015,andsupports.NET4.5features.ThisputsUnity’simplementationabout5yearsbehindintermsofC#languageand.NETframeworkfeatures,whichhasdrawntheireofmanyUnitydevelopers.
UnityTechnologieshassuggestedtheremightbeaMonoupgradesometimeinthelifecycleofUnity5,butthelastofficialupdateonthissubjectwasbackinAugust2014.TheUnityroadmap(https://unity3d.com/unity/roadmap)placesitinthe“LongandUncertain”timeline,andUnityv5.2wasreleasedinearlySeptember2015,whichdidnotincludethisupgrade.So,itisdifficulttosaywhenMonowillbereceivingitsmuch-neededupgrade.UnityTechnologieshasalsobeenworkingwithMicrosofttobringreplacementstosomeMonoComponents(suchasupgradedversionsofthestatic,JIT,andAOTcompilers,aswellastheCLR).
NoteMicrosoft’sannouncementonthefutureof.NET:
http://blogs.msdn.com/b/dotnet/archive/2014/04/03/the-next-generation-of-net.aspx
Meanwhile,UnityTechnologieshasbeenworkingontheproblemoflong-termindependencefromthesethird-partydependenciesforawhile.WiththereleaseofUnity5theyunveiledanewapproachforscriptcodecompilation,whichstartedasawaytoprovideimprovedscriptingsupportforWebGL-basedUnityapplications,buthasalsobeenadoptedasthemainsolutiontothesewoes:IL2CPP.
NoteUnityTechnologies’IL2CPPannouncement:
http://blogs.unity3d.com/2014/05/20/the-future-of-scripting-in-unity/
IL2CPPisshorthandforIntermediateLanguageToC++,andcomeswithitsown.NETruntimethatcanberolledouttomultipleplatforms.ThebasicideaisthatC#scriptcode
http://freepdf-books.com
![Page 356: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/356.jpg)
willbeconvertedintoanintermediatelanguageandthenconvertedagaintoC++duringthebuildprocess.TheresultingC++willbepushedthroughoneofseveralavailableplatform-specificcompilerstosupportcross-platformcapability,takingawaytheburdenofhavingtocreateandmanagetheirowncompilers.
Thisprocesswillbemostlydisguisedfromtheuser,andnaturallytherewillbealossofcontrolasthecodeispushedthroughmultiple“codefilters”withvaryinglevelsofoptimizations.Itremainstobeseeniftheyallowsomehookstocontrolthecompilationprocessforadvanceddevelopers.TheEditorisstillexpectedtorunontheC#.NETruntimeforfasterdevelopmentiteration.
Thesuggestedbenefitsofthisapproachincludeperformanceenhancements(sinceevennear-nativecodegeneratedbytheJITcompilerstillpalesincomparisontostatically-compilednativeC++),fasterportingandfeaturedevelopmentfortheUnityEngine,andimprovedgarbagecollection.ThefirstplatformtogettheIL2CPPtreatmentinUnity5isWebGL,andwilleventuallybepushedtootherplatformsasthesystemmatures,andbecomesmorereliable.
NoteFormoreinformationonIL2CPPcheckoutthevariousblogpostsfromUnityTechnologiesonthesubject.Thefollowingpostcontainslotsofinformation,aswellasfurtherlinksonimportanttopics:
http://blogs.unity3d.com/2015/05/06/an-introduction-to-ilcpp-internals/
Whydoesn’tUnityTechnologiesjustprovideaC++APIforUnity?Onecanonlyspeculate,butit’saprettysafeassumptionthatUnitysupportsaverylargeuserbaseofdeveloperswhowouldbeuncomfortableworkinginC++directly.LosingtheaccessibilityofC#andUnityScriptwouldresultinaverydifferentproduct.Long-term,itwouldlikelysplitthecustomerbaseintotwocamps,whichrarelybodeswellsincewhicheveronebringsinthemostrevenuewillbecometheonethatissupportedtoagreaterdegree,leavingtheothertorot(asaninterestinganalogy,gamestypicallysufferfromthesameproblem,asexpansionsandmappackstendtosegregatethemultiplayeruserbase).
Inaddition,therearemany.NETlanguagesthatsharethesameintermediatecodeaftercompilation(CIL),andtheyhaveacommonbinaryinterface,whichmakesitordersofmagnitudeeasiertosupportcross-platformdevelopmentandmultiplelibrariesthanwithC++.Presumably,IL2CPPisacompromisefortheseconcerns.
So,tomakealongstoryshort,thereareagreatmanychangesgoingonwiththeunderlyingUnityEngineandit’stooearlytosaywhethertheIL2CPPapproachwillworksufficientlywellonallplatformstokeepfeatureparityandeaseofdeployment.Onethingisforsure;thenextcoupleofyearsofUnitydevelopmentwillbringsomeinterestingtransitions!
http://freepdf-books.com
![Page 357: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/357.jpg)
http://freepdf-books.com
![Page 358: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/358.jpg)
SummaryWe’vecoveredahumungousamountoftheoryandlanguageconceptsinthischapter,whichhavehopefullyshedsomelightonhowtheinternalsoftheUnityEngineandC#languagework.Thesetoolstrytheirbesttospareusfromtheburdenofcomplexmemorymanagement,butthereisstillawholehostofconcernsweneedtokeepinmindaswedevelopourgame.Betweenthecompilationprocesses,multiplememorydomains,thecomplexitiesofValuetypesversusReferencetypes,passingbyvalueversuspassingbyreference,boxing,objectpooling,andvariousquirkswithintheUnityAPI,wehavealotofthingstoworryabout.But,withenoughpractice,wewilllearntoovercomethemwithoutneedingtokeepreferringtogianttomessuchasthis!
Thischaptereffectivelyconcludesallofthetechniqueswecanbestowthatexplicitlyaimtoimproveapplicationperformance.Workflowoptimizationsarealwaysusefulthingstokeepinmind,however,astherearealotofneatlittlenuancestotheUnityEnginethataren’twellknownorclearlydocumented,andthatonlybecomeapparentthroughexperienceandcommunityinvolvement.Assuch,thenextchapterwillbefullofhintsandtipsforimprovinghowtomanageourprojectandScenesmoreeffectively,howtomakethemostoftheEditor,andhopefullysaveourselvesenoughdevelopmenttimetoactuallyimplementalloftheoptimizationtechniqueswe’vetalkedaboutthroughthisentirebook.
http://freepdf-books.com
![Page 359: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/359.jpg)
http://freepdf-books.com
![Page 360: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/360.jpg)
Chapter8.TacticalTipsandTricksTherearealotoflittlenuancestousingtheUnityEnginethatcanhelpimproveourprojectworkflow.However,quitealotoftheEditor’sfunctionalityisnotwelldocumented,wellknown,orjustnotsomethingwethinkaboutuntilafterthefactthatitcouldhavebeenappliedperfectlytosolveaparticularproblemwewerehaving6monthsago.
TheInternetiscrammedfullofblogsandforumpoststhattrytohelpotherUnitydeveloperslearnabouttheseusefulfeatures,buttheyonlytendtofocusonahandfuloftipsatatime.Theredon’tseemtobeanyonlineresourcesthatgrouptogethermanyoftheminoneplace.Asaresult,intermediateandadvancedusersprobablyhavebookmarkedmanagersburstingattheseamswithlinkstothesetipsthattheyrunintoatonepointoranother,butwhichsitandrotuntilitcomestimetodosomespringcleaning.
So,becausethisbookisprimarilyforintermediateandadvancedusers,itfeltlikeitwasworththrowinginashortchaptertobringtonsofthesetipsandtrickstogetherinonelocation.Itworksasareferencelistinthehopeofsavingusalotoffuturedevelopmenteffort.
http://freepdf-books.com
![Page 361: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/361.jpg)
EditorhotkeytipsTheEditorisrifewithhotkeysthatcanaidrapiddevelopment.It’sworthcheckingoutthedocumentation.Butlet’sbehonest,nobodyreadsthemanualuntiltheyneedsomethingfromit.Herearesomeofthemostuseful,yetlesser-knownhotkeysavailablewhenplayingwiththeUnityEditor.
NoteInallcases,theWindowshotkeyislisted.IftheOSXhotkeyrequiresadifferentsetofkeystrokes,thenitwillbeshowninparentheses.
http://freepdf-books.com
![Page 362: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/362.jpg)
GameObjectsGameObjectscanbeduplicatedbyselectingtheminthehierarchyandpressingCtrl+D(Cmd+D).
New,emptyGameObjectscanbecreatedusingCtrl+Shift+N(Cmd+Shift+N).
PressCtrl+Shift+A(Cmd+Shift+A)toquicklyopentheAddComponentmenu.Fromthere,youcantypeinthenameoftheComponentyouwishtoadd.
http://freepdf-books.com
![Page 363: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/363.jpg)
SceneViewPressingShift+Fordouble-tappingtheFkeywillfollowanobjectintheSceneView,whichcanbehelpfulfortrackinghigh-velocityobjectsorfiguringoutwhyobjectsmightbefallingoutofourScene.
HoldingAltandleft-clickdraggingwiththemousewillmaketheSceneViewcameraorbitthecurrentlyselectedobject(asopposedtolookingaroundit).HoldingAltandright-clickdraggingwillzoomthecamerain/out.
HoldingCtrlandleft-clickdraggingwillcausetheselectedobjecttosnaptothegridasitmoves.ThesamecanbedoneforrotationbyholdingCtrlasweadjusttherotationwidgetsaroundtheobject.SelectingEdit|SnapSettings…opensawindowwherewecaneditthegridthatobjectssnaptoonaper-axisbasis.
Wecanforceobjectstosnapbyvertex,holdingtheVkeyaswemovetheobjectaround.Theselectedobjectwillattachitselftothenearestvertex,tothecursorofthenearestobject.Thisisveryusefulforaligninglevelpiecesintoplace,suchasplatformsandothertile-basedsystems,withoutneedingtohand-adjustpositionvectors.
NoteAtonepoint,inUnityversions4.2to4.6,itwaspossibletoholdShiftwithaColliderobjectselectedtoreveallittlehooksthroughwhichwecouldadjusttheColliderthroughtheSceneView.ThiswasremovedinrecentversionsofUnityduetoconflictswithothercontrols.WemustusetheEditColliderbuttonwithintheCollidercomponenttoaccessthisfeaturegoingforward.
http://freepdf-books.com
![Page 364: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/364.jpg)
ArraysWecanduplicatearrayelementsthathavebeenexposedintheInspectorViewbyselectingthemandpressingCtrl+D(Cmd+D).Thiswillcopytheelementandinsertitintothearrayimmediatelyafterthecurrentselection.
Wecanremoveentriesfromanarrayofreferences(forexample,anarrayofGameObjects)bypressingShift+Delete(Cmd+Delete).Thiswillstripawaytheelementandcondensethearray.Notethatthefirstpresswillclearthereferencesettingittonull,butthesecondpresswillremovetheelement.Removingelementsinarraysofprimitivetypes(ints,floats,andsoforth)canbeaccomplishedbysimplypressingDeletewithouttheShiftkey(Cmd)modifier.
WecanusetheW,A,S,Dkeyswhileright-clickdraggingontheSceneViewtoflyaroundwiththecamera,inatypicalfirst-personcameracontrolstyle.TheQandEkeyscanbeusedtotranslatethecameraontheverticalaxis,respectively.
http://freepdf-books.com
![Page 365: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/365.jpg)
InterfaceWecanholdAltandclickonanyhierarchyarrow(thesmallgreyarrowtotheleftofanyparentobjectname)toexpandtheobject’sfullhierarchyandnotjustthenextlayer.ThisworksonGameObjectsintheHierarchyView,foldersandPrefabswithintheProjectView,listsintheInspectorView,andsoon.
WecansaveandrestoreselectionsfromobjectsintheHierarchyorProjectViewsintypicalRTSgamestyle!MaketheselectionandpressCtrl+Alt+<0-9>(Cmd+Alt+<0-9>)tosavetheselection.PressCtrl+Shift+<0-9>(Cmd+Shift+<0-9>)torestoreit.Thisisexceptionallyusefulifwefindourselvesselectingthesamehandfulofobjectsoverandoveragainwhilewemakeadjustments.
PressingShift+SpacebarwillexpandthecurrentwindowtofilltheentireEditorscreen.Pressingitagainwillshrinkthewindowandrestoreittoitspreviouslocation.
PressingCtrl+Shift+P(Cmd+Shift+P)willtogglethePausebuttonwhileinPlayMode.
http://freepdf-books.com
![Page 366: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/366.jpg)
OtherWecanquicklyaccessthedocumentationofanyUnitykeywordorclass,byhighlightingitinMonoDevelopandpressingCtrl+‘(Cmd+‘).ThiswillopenthedefaultbrowserandperformasearchontheUnitydocumentationforthegivenkeywordorclass.
TipNotethatuserswithEuropeankeyboardsmayalsoneedtoholddowntheShiftkey.
WiththerecentreleaseofVisualStudioToolsforUnity(VSTU),itispossibletoaccessthedocumentationinthesamewaythroughVisualStudiobypressingCtrl+Alt+M,followedbyCtrl+H(noequivalentOSXhotkey,obviously).
http://freepdf-books.com
![Page 367: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/367.jpg)
http://freepdf-books.com
![Page 368: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/368.jpg)
EditorinterfacetipsThefollowingcollectionoftipsrelatestotheEditoranditsinterfacecontrols.
http://freepdf-books.com
![Page 369: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/369.jpg)
GeneralWecanprioritizewhichScriptswillhavetheirUpdateandFixedUpdatemethodscalledbeforeothers,bynavigatingtoEdit|ProjectSettings|ScriptExecutionOrder.Withtheexceptionofsometime-sensitivesystems,suchasaudioprocessing,ifwefindourselvestryingtosolvecomplexproblemsusingthisfeature,itimpliesthatwe’vegotsomefragileandtightcouplingbetweenourComponents.Fromasoftwaredesignperspective,thiscanbeawarningsignthatwemightneedtoapproachtheproblemfromanotherangle.However,itcanbehelpfultohaveparticularobjectsgettheirUpdate()andLateUpdate()functionscalledbeforeotherobjects,inordertodosomebookkeeping.
IntegratingUnityprojectswithaSourceControlsolutioncanbealittletricky.Thefirststepistoforcetheprojecttogenerate.metafilesforassets;ifwedon’tdothis,thenanyonepullingdataintotheirlocalUnityprojectmustregeneratetheirownmetadatafiles.Thiscaneasilycauseconflicts,soitisessentialthateveryoneusesthesameversions.VisiblemetadatafilescanbeenabledbynavigatingtoEdit|ProjectSettings|Editor|VersionControl|Mode|VisibleMetaFiles.Allofthe.metafileswillnowbevisiblewithinthefilestructureandavailableforuploadintoSourceControl.
ItcanalsobehelpfultoconvertcertainassetdataintoaText-onlyformat,ratherthanbinarydata,toallowmanualeditingofdatafiles.Thisturnsmanydatafilesintothemuchmorehuman-readableYAMLformat.Forinstance,ifwe’reusingScriptableObjectstostorecustomdata,wecanuseatexteditortosearchandeditthesefileswithouthavingtodoitallthroughtheUnityEditorandserializationsystem.Thiscansavealotoftime,especiallywhenhuntingforaparticulardatavalueorwhenmultieditingacrossdifferentderivedtypes.ThisoptioncanbeenabledbynavigatingtoEdit|ProjectSettings|Editor|AssetSerialization|Mode|ForceText.
TheEditorhasalogfile,whichcanbeaccessedbyopeningtheConsolewindow(wherelogmessagesareprintedoutto),clickingonthe“hamburgericon”(madefromthreehorizontallines)atthetop-right,andselectingOpenEditorLog.Ifwerecentlybuiltourproject,itwillcontainabreakdownofcompressedfilesizesofallassetsthatwerepackedintotheexecutableandorderedbysize.Thisisanextremelyhelpfulwayoffiguringoutwhichassetsareconsumingthemajorityofourapplicationfootprint(hint:it’salmostalwaysTexturefiles),andwhichfilesaretakingupmorespacethanwewouldexpect.
http://freepdf-books.com
![Page 370: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/370.jpg)
AdditionalwindowscanbeaddedtotheEditorbyright-clickingonthetitleofanexistingwindowandselectingAddTab.Thisalsoallowsustoaddduplicatewindows,suchashavingmorethanoneInspectorViewopenatatime:
Havingduplicateviewscanbekindofredundant,unlessweusethe“lockicon”tolockthegivenviewtoitscurrentselection.Whenweselectanobject,allInspectorViewswillupdatetoshowtheobject’sdata,exceptforanylockedInspectorViews,whichcontinuetoshowthedataoftheobjecttheywerelockedto.
Commontricksthatmakeuseofwindowlockingincludethefollowing:
UsingtwoofthesameView(Inspector,Animation,andsoforth)tocomparetwoobjectsside-by-sideoreasilycopydatafromonetoanother
http://freepdf-books.com
![Page 371: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/371.jpg)
UsingaduplicateProjectViewtomovelargedatasetsaroundTestingwhathappenstoanydependentobjectsifanobjectistweakedduringruntimeSelectingmultipleobjectsintheProjectView,thendragging-and-droppingthemintoaserializedarrayintheInspectorViewwithoutlosingtheoriginalselection
http://freepdf-books.com
![Page 372: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/372.jpg)
TheInspectorViewWecanentercalculationsintonumericinspectorfields.Forexample,typing4*128intoanintfieldwillresolvethevalueto512,sparingusfromhavingtopulloutacalculatorordothemathinourhead.
Arrayelementscanbeduplicatedanddeletedfromalist(inthesamefashionasthehotkeysmentionedpreviously)byright-clickingontherootelementandselectingDuplicateArrayElementorDeleteArrayElement.
AComponent’scontextmenucanbeaccessedthroughboththesmallcogiconintheupper-rightorbyright-clickingonthenameoftheComponent.EveryComponent’scontextmenucontainsaResetoption,whichresetsallvaluesbacktotheirdefault,sparingusfromhavingtoresetvaluesmanually.ThisisusefulwhenworkingwithTransformComponents,asthisoptionwillsettheobject’spositionandrotationto(0,0,0)anditsscaleto(1,1,1).
It’scommonlyknownthat,ifaGameObjectwasspawnedfromaPrefab,thentheentireobjectcanberevertedbacktoitsinitialPrefabstateusingtheRevertbuttonatthetopoftheInspectorView.However,it’slesswellknownthatindividualvaluescanberevertedbyright-clickingonthenameofthevalueandselectingRevertValuetoPrefab.Thisrestorestheselectedvalue,leavingtherestuntouched.
TheInspectorViewhasadebugmodethatcanbeaccessedbyclickingonthehamburgericonnexttothelockiconandselectingDebug.ThiswilldisableallcustomInspectordrawingandrevealallrawdatawithinthegivenGameObjectanditscomponents,evenprivatedatafields.Privatefieldsaregrayed-outandcannotbemodifiedthroughtheInspectorView,butthisgivesusausefulwayofexaminingprivatedataandotherhiddenvaluesduringPlayMode.TheDebugviewalsorevealsinternalObjectIDs,whichcanbeusefulifwe’redoing“interesting”thingswithUnity’sserializationsystemandwanttoresolveconflicts.
IfwehaveanarrayofdataelementsserializedintheInspectorView,thentheyaretypicallylabeledElement<N>where<N>isthearrayindex.Thiscanmakeittrickytofindaspecificelementifourarrayelementsareaseriesofserializedclassesorstructs,whichtendtohavemultiplechildrenthemselves.However,iftheveryfirstfieldintheobjectisastring,thentheelementswillbenamedafterthevalueofthestringfield.
Whenameshobjectisselected,thePreviewwindowatthebottomoftheInspectorViewisoftenfairlysmall,makingithardtoseedetailsinthemeshandhowitwilllookwhenit
http://freepdf-books.com
![Page 373: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/373.jpg)
appearsinourScene.But,ifweright-clickonthetopbarofthePreviewwindow,itwillbedetachedandenlarged,makingitmucheasiertoseeourmesh.Wedon’thavetoworryaboutsettingthedetachedwindowbacktoitsoriginalhomebecause,ifthedetachedwindowisclosed,thenthePreviewwindowwillreturntothebottomoftheInspectorView.
http://freepdf-books.com
![Page 374: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/374.jpg)
TheProjectViewTheProjectView’ssearchbarallowsustofilterforobjectsofaparticulartypebyclickingonthesmallicontotherightofthesearchbar.Thisprovidesalistofdifferenttypeswecanfilterby,revealingallobjectsofthattypewithintheentireproject.However,selectingtheseoptionssimplyfillsthesearchbarwithastringofthet:<type>format,whichappliestheappropriatefilter.
Thus,wecansimplytypetheequivalentstringsintothesearchbarforthesakeofspeed.Forinstance,typingt:prefabwillfilterforallPrefabs,nomatterwheretheycanbefoundinthehierarchy;t:texturewillrevealtextures,t:scenewillrevealScenes,andsoon.Addingmultiplesearchfiltersinthesearchbarwillincludeobjectsofalltypes(itdoesnotrevealobjectswhichonlysatisfybothfilters).Thesefiltersaremodifiersinadditiontoname-basedfiltering,soaddingaplaintextstringwillcauseaname-basedsearchthroughthefilteredobjects.Forexample,t:texturenormalmapwillfindalltexturefilesthatincludethewordnormalmapintheirname.
Ifwe’remakinguseofAssetBundlesandthebuilt-inlabelingsystem,theProjectView’ssearchbaralsoallowsustohuntdownbundledobjectsbytheirlabelusingl:<labeltype>.
IfaMonoBehaviourscriptcontainsserializedreferences(using[SerializeField]orpublic)toUnityAssets,suchasMeshesandTextures,thenwecanassigndefaultvaluesdirectlyintothescriptitself.SelectthescriptfileintheProjectViewandtheInspectorViewshouldcontainafieldfortheassetforustodrag-and-dropthedefaultassignmentinto.
http://freepdf-books.com
![Page 375: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/375.jpg)
Bydefault,theProjectViewsplitsfilesandfoldersintotwocolumnsandtreatsthemseparately.IfweprefertheProjectViewtohaveatypicalhierarchyfolderandfilestructure,thenwecansetittoOneColumnLayoutinitscontextmenu(thehamburgericonatthetopright).ThiscanbeagreatspacesaverinsomeEditorlayouts.
Right-clickingonanyobjectintheProjectViewandselectingSelectDependencieswillrevealallobjectsuponwhichthisassetreliesinordertoexist,suchasTextures,Meshes,MonoBehaviourscriptfiles,andsoon.ForScenefiles,itwilllistallentitiesreferencedwithinthatScene.Thisishelpfulifwe’retryingtoperformsomeassetcleanup.
http://freepdf-books.com
![Page 376: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/376.jpg)
TheHierarchyViewAlesser-knownfeatureoftheHierarchyViewistheabilitytoperformcomponent-basedfilteringwithinthecurrentlyactiveScene.Confusingly,itusesthesamesyntaxasperformingtype-basedfilteringintheProjectViewandcanthereforebeaccomplishedbytypingt:<componentname>.Forexample,typingt:lightintotheHierarchyViewsearchbarwillrevealallobjectsintheScenethatcontainaLightcomponent.
Upper-orlower-casecharactersareunimportant,butthestringmustmatchthefullcomponentnameinorderforthesearchtocomplete.Componentsthatderivefromthegiventypewillalsoberevealed,sotypingt:rendererwillrevealallobjectswithderivedcomponentssuchasMeshRenderers,SkinnedMeshRenderers,andsoon.
http://freepdf-books.com
![Page 377: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/377.jpg)
TheSceneandGameViewsTheSceneViewcameraisnotvisiblefromtheGameView,butitisgenerallyaloteasiertomovearoundandplacethroughtheuseofthehotkeysmentionedpreviously.TheEditorallowsustoaligntheselectedobjecttothesamepositionandrotationoftheScenecamerabynavigatingtoGameObject|AlignwithView(Ctrl+Shift+F/Cmd+Shift+F).ThismeansthatwecanusethecameracontrolstoplacetheScenecamerawherewewouldlikeourobjecttobe,andplacetheobjecttherebyaligningittothecamera.
Similarly,wecanaligntheSceneviewtotheselectedobjectbynavigatingtotheGameObject|AlignViewtoSelectedoption.Thisisusefulforcheckingifthegivenobjectispointingintherightdirection.
Wecanperformsimilarcomponent-basedfilteringontheSceneView,aswecanwiththeHierarchyView,usingthet:<component>syntaxwithinitssearchbar.
AttheverytoprightoftheUnityEditorisadropdownlabeledLayers.ThiscontainsaLayer-basedfilteringandlockingsystemfortheSceneView.Togglingonthe“eye”iconwillshow/hideallobjectsofthatLayerwithintheSceneView.Togglingthelockiconwillalloworpreventobjectsofthegivenlayerfrombeingselected.Thisishelpfulforthingssuchaspreventingsomeonefromaccidentallyselectingandmovingbackgroundobjectsthathavealreadybeensituatedintheperfectlocation.
AcommonlyknownandusefulfeatureoftheEditoristhatGameObjectscanbegivenspecialiconsorlabelstomakethemeasiertofindintheSceneView.Thisisparticularlyhelpfulforobjectswithnorendererbutthatwewishtofindeasily.Forinstance,objectssuchasLightsandCamerashavebuilt-iniconsthatidentifytheminourSceneViewmoreeasily.
However,thesamegizmoscanberevealedwithintheGameViewbyclickingontheGizmosbuttonatthetoprightoftheGameView.Thedropdownforthisoptiondetermineswhatgizmoswillbevisiblewhenthisoptionisenabled.
http://freepdf-books.com
![Page 378: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/378.jpg)
PlayModeSincePlayModechangesarenotautomaticallysaved,itiswisetomodifythetintcolorappliedduringPlayModetomakeitblatantlyobviouswhichmodewe’recurrentworkingwith.ThisvaluecanbesetbynavigatingtoEdit|Preferences|Colors|Playmodetint.
ChangescanbesavedfromPlayModebysimplyusingtheclipboard.Ifwe’retweakinganobjectinPlayModeandwe’rehappywithitssettings,thenwecancopytheobjectintotheclipboardusingCtrl+C(Cmd+C),andpasteitbackintotheSceneoncePlayModeendswithCtrl+V(Cmd+V).Allsettingsontheobjectatthetimeofthecopywillbekept.ThesamecanbedonewithindividualvaluesorentirecomponentsusingtheCopyComponentandPasteComponentoptionsinthecomponent’scontextmenu.However,theclipboardcanonlycontaindataforoneobject,component,orvalue,atatime.
Anotherapproach,whichallowsustosavethedataofmultipleobjectsduringPlayMode,istocreatePrefabsfromthembydragginganddroppingthemintotheProjectWindowatruntime,oncewe’rehappywiththesettings.IftheoriginalobjectwasderivedfromaPrefab,andwewishtoupdateitacrossallinstances,thenweonlyneedtooverwritetheoldPrefabwiththenewonewecreatedbydragginganddroppingthecopyontopoftheoriginal.NotethatthisalsoworksduringPlayModeruntime,butitcanbedangeroussincethereisnodialogpop-uptoconfirmtheoverwrite.BeverycarefulnottooverwritethewrongPrefab.
WecanusetheFrameSkipbutton(thebuttontotherightofthePausebuttonintheEditor)toiterateoneframeatatime.Thiscanbeusefulforwatchingframe-by-framephysicsorgameplaybehavior.KeepinmindthatthiscausesbothoneFixedUpdateandoneUpdatetobecalledeachstep,inequalcounts,whichmaynotexactlyreflectactualruntimebehaviorwherewetendtohaveunequalcallstothesemethods.
IfthePausebuttonisenabledwhenPlayModebegins,thenthegamewillbepausedjustaftertheveryfirstframe,givingusachancetoobserveanyanomaliesthatoccurredfrominitializationofourScene.
http://freepdf-books.com
![Page 379: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/379.jpg)
http://freepdf-books.com
![Page 380: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/380.jpg)
ScriptingtipsThefollowingtipsareusefulfeaturestoknowwhenscripting.
http://freepdf-books.com
![Page 381: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/381.jpg)
GeneralWecanmodifyvarioustemplatesofnewScript,Shader,andComputeShaderfiles.ThiscanbehelpfultoremovetheemptyUpdatestubswhich,aswelearned,cancauseunnecessaryruntimeoverhead.Thesefilescanbefoundinthefollowinglocations:
Windows:<Unityinstall>\Editor\Data\Resources\ScriptTemplates\OSX:/Applications/Unity/Editor/Data/Resources/ScriptTemplates/
TherecentreleaseofUnityVersion5.1introducedtheAssertclassandallowsforassert-baseddebugging,whichsomedevelopersaremorecomfortablewithasopposedtoexception-baseddebugging.ChecktheUnitydocumentationformoreinformationonAsserts:http://docs.unity3d.com/ScriptReference/Assertions.Assert.html
CallingDebug.Break()isfunctionallyequivalenttopausingtheEditorduringPlayMode,whichcanbeusefulforcatchingawkwardgraphicalbehavior,orasamoreconvenientalternativetotheabsurdhotkeyrequiredtopausetheScene(Ctrl+Shift+P).
http://freepdf-books.com
![Page 382: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/382.jpg)
AttributesAttributesareveryusefulmeta-leveltagsthatcanbegiventoalmostanytargetinC#.Theyaremostcommonlyusedonmemberdata(fields)andclasses,allowingustoflagthemwithspecialpropertiessothattheycanbeprocesseddifferently.IntermediateandadvancedUnitydeveloperswillfinditworthwhiletoreadtheC#documentationonattributesandusetheirimaginationtocomeupwiththeirownattributesthathelpacceleratetheirworkflow.TherearequiteafewattributesbuiltintotheUnityenginethatcanbeexceptionallyusefulwhenusedintherightplace.
NoteAdvanceduserswillnotethatattributescanalsobegiventoenums,delegates,methods,parameters,events,modules,andevenassemblies.
VariableattributesPublicvariablesarefairlydangerousthingstoaddtoourcomponents,asanythingcancomealongandchangethevalueatruntime,makingithardtotracebugs,aswellasrequiringspecialhandholdingtopreventthevariablefrombeinggivenaninvalidvalue.However,publicvariablesareusuallythefirstwaythatUnitydeveloperslearntoexposevariablesintheInspectorView.Insomecases,thepublicvariableisabsolutelyintendedtobepublic,butwedon’twishittobeseenintheInspector.Insuchacase,the[HideInInspector]attributecanbeusedtohidethevariablefromtheInspector,whenevernecessary.
However,thepreferredapproachistomakeourvariablesprivateorprotectedandallowEditor-baseddevelopmentbyexposingvaluesthroughthe[SerializeField]attribute.ThisattributeallowsprivateandprotectedvariablestoberevealedintheInspectorfordesignerstomanipulate,withoutriskingothercomponentsaccidentallychangingthevariableatruntime.
The[Range]attributecanbeaddedtoanintegerorfloating-pointfieldtoconvertitintoasliderintheInspectorView.Wecangiveminimumandmaximumvalues,limitingtherangethatthevaluecancontain.
Normally,ifavariableisrenamed,evenifwedoarefactorthroughourIDE(whetheritsMonoDeveloporVisualStudio)thenthevaluesarelostassoonasUnityrecompilestheMonoBehaviourandmakestheappropriatechangestoanyinstancesofthecomponent.However,the[FormerlySerializedAs]attributeisincrediblyhelpfulifwewishtorenameavariablethathasbeenpreviouslyserialized,asitwillcopythedatafromthevariablenamedwithintheattributeintothegivenvariableduringcompilationtime.Nomorelostdataduetorenamingstuff!
Notethatitisnotsafetoremovethe[FormerlySerializedAs]attributeaftertheconversioniscompleted,unlessthevariablehasbeenmanuallychangedandresavedsincecompletion.The“.prefab”datafilewillstillcontaintheoldvariablename,andsoitstillneedsthe[FormerlySerializedField]attributetofigureoutwheretoplacethedatathenexttimethefileisloaded(forexample,whentheEditorisclosedandreopened).Thus,
http://freepdf-books.com
![Page 383: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/383.jpg)
thisisahelpfulattribute,butextendedusedoestendtoclutterupourcodebasealot.
ClassattributesThe[SelectionBase]attributewillmarkanyGameObjectthecomponentisattachedtoastherootofselectionfortheSceneView.Thisisespeciallyusefulifwehavemeshesthatarechildrenofotherobjects,aswemightwanttheparentobjecttobeselectedwiththefirstclick,insteadoftheobjectwiththeMeshRenderercomponent.
Wecanusethe[RequireComponent]attributetoforcedesignerstoattachvitalcomponentstothesameGameObjectiftheyattempttoattachthiscomponent.Thisensuresanydependenciesthatourcodebasereliesonwillbesatisfiedbydesigners,withouthavingtowriteoutawholebunchofdocumentationforthem.
The[ExecuteInEditMode]attributewillforcetheobject’sUpdate(),OnGUI(),andOnRenderObject()methodstobecalledevenduringEditMode.However,therearecaveats:
TheUpdate()methodisonlycalledifsomethingchangesintheSceneOnGUI()isonlycalledduringGameViewevents,notforotherviewssuchastheSceneViewOnRenderObject()iscalledduringanyrepainteventfortheSceneandGameViews
However,thisgivessuchobjectsadifferentsetofeventhooksandentrypointscomparedtotypicalEditorscripts,sothisattributestillhasitsuses.
http://freepdf-books.com
![Page 384: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/384.jpg)
LoggingWecanaddrichtexttagstodebugstrings.Tagssuchas<size>,<b>(bold),<i>(italics),and<color>allworkondebugstrings.Thiscanbehelpfulfordifferentiatingthedifferentkindsoflogmessagesandhighlightingspecificelements.
Debug.Log("<color=red>[ERROR]</color>Thisisa<i>very</i><size=14>
<b>specific</b></size>kindoflogmessage");
TheMonoBehaviourclasshasaprint()methodforconvenience,whichdoesthesamethingasDebug.Log().
Itcanhelptocreateacustomloggerclass,whichautomaticallyappends\n\ntotheendofeverylogmessage.ThiswillpushandhideawaytheunnecessaryUnityEngine.Debug:Log(Object)clutterthattendstofilltheConsolewindow.
http://freepdf-books.com
![Page 385: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/385.jpg)
UsefullinksUnitytechnologiesprovidemanyusefultutorialsontheusageofvariousscriptingfeatures,whichareprimarilytargetedatbeginnerandintermediate-leveldevelopers.Thetutorialscanbefoundathttps://unity3d.com/learn/tutorials/topics/scripting.
There’sahelpfulpostonUnityAnswers,whichprovidesareferencelistthatcoversmanyofthedifferentscriptingandcompilationerrorswemightrunacrossduringdevelopment,whichcanbefoundathttp://answers.unity3d.com/questions/723845/what-are-the-c-error-messages.html.
ScriptableObjectsareveryusefulobjectsandanexcellentwayofstoringgamedatainaformthatdoesnotneedtobeinstantiatedatruntime.Theyworklikeanyotherclassinthattheycancontainmethodsandvariables,canbeserialized,allowpolymorphism,andsoon.Theonlytrickypartistheycanonlybecreatedthroughscripting,andmustbeloadedintomemoryatanytimeusingResources.Load().ButthisallowsustocontrolwhichScriptableObjectsarepresentinmemoryatanygiventime,givingusmorecontroloverruntimememoryconsumption.ExplainingthenuancesofScriptableObjectsherewouldtaketoomuchspace,butUnitytechnologieshaveprovidedagoodintroductoryexaminationofScriptableObjectsinthefollowingtutorialvideo:
https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects
NoteNotethat,despitethecategoryoftheScriptableObjectvideo,it’sgenerallyconsideredmoreofanintermediate-leveltopic.BeginnerswouldbebestservedbyfocusingonbecomingcomfortablewithPrefabs,beforeturningthingsontheirheadthroughScriptableObjectsandtheimportantserializationtopicsthatneedtobeunderstood.
NestedCoroutinesareanotherinterestingandusefulareaofscriptingthatisnotwelldocumented.But,thefollowingthird-partyblogpost,whichcoversalotoftheinterestingdetails,shouldbeconsideredwhenworkingwithNestedCoroutines:
http://www.zingweb.com/blog/2013/02/05/unity-coroutine-wrapper
WecanfigureoutwhenaparticularfeaturewasaddedtotheUnityAPIbycheckingtheAPIhistorypageathttp://docs.unity3d.com/ScriptReference/40_history.html.
http://freepdf-books.com
![Page 386: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/386.jpg)
http://freepdf-books.com
![Page 387: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/387.jpg)
Customeditors/menustipsWecansetcustomhotkeysforMenuItems.Forexample,wecanmaketheKkeytriggerourMenuitemmethod,bydefiningtheMenuItemattributeasfollows:
[MenuItem("MyMenu/MenuItem_k")]
WecanalsoincludemodifierkeyssuchasCtrl(Cmd),Shift,andAltusingthe%,#,and&characters,respectively.
MenuItemsalsohavetwooverloads,whichallowsustosettwoadditionalparameters:aBooleanthatdetermineswhetherthemenuitemrequiresavalidationmethod,andanintegerthatdeterminesthemenuitem’spriorityinthehierarchy.
CheckthedocumentationforMenuItemsforacompletelistofavailablehotkeymodifiers,specialkeys,andhowtocreatevalidationmethods:
http://docs.unity3d.com/ScriptReference/MenuItem.html
Itispossibleto“ping”anobjectintheHierarchy,similartowhathappenswhenweclickonaGameObjectreferenceintheInspectorView,bycallingEditorGUIUtility.PingObject().
TheoriginalimplementationoftheEditorclass,andthewaythatmostpeoplelearnedhowtowriteEditorscripts,originallyinvolvedwritingalllogicandcontentdrawinginthesameclass.However,PropertyDrawersareaneffectivewayofdelegatingInspectordrawingtoadifferentclassfromthemainEditorclass.Thiseffectivelyseparatesinputandvalidationbehaviorfromdisplaybehavior,allowingmorefine-tunedcontrolofrenderingonaper-fieldbasisandmoreeffectivereuseofcode.WecanevenusePropertyDrawerstooverridedefaultUnitydrawingforbuilt-inobjects,suchasVectorsandQuaternions.
PropertyDrawersmakeuseofSerializedPropertiestoaccomplishserializationofindividualfields,andtheyshouldbepreferredwhenwritingeditorscripts,sincetheymakeuseofbuilt-inundo,redo,andmultieditfunctionality.Datavalidationcanbealittleproblematic,andthebestsolutionistouseOnValidate()callsonsetterpropertiesforfields.AsessionatUnite2013byUnityTechnologiesdeveloperTimCooper,whichexplainsthebenefitsandpitfallsofvariousserializationandvalidationapproachesingreatdetailathttps://www.youtube.com/watch?v=Ozc_hXzp_KU.
WecanaddentriestoComponentcontextmenusandeventhecontextmenusofindividualfieldswiththe[ContextMenu]and[ContextMenuItem]attributes.ThisallowsaneasywaytocustomizeInspectorbehaviorforourComponentswithoutneedingtowritebroadEditorclassesorcustomInspectors.
AdvancedusersmayfinditusefultostorecustomdatawithinUnitymetadatafilesthroughtheAssetImporter.userDatavariable.TherearealsoamultitudeofopportunitiestomakeuseofReflectionoftheUnitycodebase.RyanHipple’ssessionatUnite2014outlinesahugenumberofneatlittlehacksandtricksoneachievewithReflectionintheUnityEditor:
http://freepdf-books.com
![Page 388: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/388.jpg)
https://www.youtube.com/watch?v=SyR4OYZpVqQ
AnundocumentedfeaturewasintroducedinUnityv4.5,ReorderableLists.TheseallowustohaveanInspectorViewofagenericList<T>,whichcanbeeasilyreorderedbydragginganddroppingtheelementsaround.However,thisfeatureappearstobeunfinished,asitrequiresacustomEditorclasstomakeuseofthemproperly.ThefollowingpostonUnityAnswersexplainshowtouseReorderableListsfairlysuccinctly:
http://answers.unity3d.com/questions/826062/re-orderable-object-lists-in-inspector.html
http://freepdf-books.com
![Page 389: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/389.jpg)
http://freepdf-books.com
![Page 390: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/390.jpg)
ExternaltipsThefollowingtipsandtricksrelatetotopicsoutsidetheUnityEditoritselfthatcanhelpUnitydevelopmentworkflowenormously.
GooglingUnity-relatedproblemsorconcernscangoalotfasterifwestartthesearchwith“site:unity3d.com“.
IftheUnityEditorcrashes,forwhateverreason,thenwecanpotentiallyrestoreourScenebyrenamingthefollowingfiletoincludethe.unityextension(forScenefiles),andcopyingitintoourAssetsfolder:
\<projectfolder>\Temp\_EditModeScene
Ifwe’redevelopingonWindows,thenthere’sverylittlereasonnottouseVisualStudioatthispoint.MonoDevelophasbeendraggedalongkickingandscreamingformanyyears,andmanydevelopershavebeenswitchingovertothemorefeature-richVisualStudioCommunityeditionformostoftheirdevelopmentworkflowneeds,particularlywithincrediblyhelpfulpluginssuchasResharper.
Forsomedevelopers,theonlyreasontobootupMonoDevelophasbeenforruntimedebuggingofcode,butwiththerecentreleaseofVisualStudioToolsforUnity(VSTU),VisualStudionowoffersbetterintegrationwiththeUnityEditor.ItevenallowsourC#codetoberuntime-debuggedthroughVisualStudioitself.Unlesswehaveparticularhangupsabouttheinterfaceorthefactthatit’smadebythebig,badMicrosoft,weshouldwanttogiveVisualStudioCommunityatryasitaccelerateourscriptcodedevelopmentinwayswehadn’texpected.
CheckoutthefollowingvideoformoreinformationonVisualStudioanditsintegrationwithUnitythroughVSTU:
https://channel9.msdn.com/Events/Visual-Studio/Visual-Studio-2015-Final-Release-Event/Building-Unity-games-in-Visual-Studio
Thereisagreatresourceforgameprogrammingpatterns(orrather,typicalprogrammingpatternsexplainedinawaythatispertinenttogamedevelopment)anditiscompletelyfreeandavailableonline:
http://gameprogrammingpatterns.com/contents.html
KeepaneyeonanysessionvideosthatcomefromUniteconferences,whenevertheyhappen(orbetteryet,trytoattendthem).There’susuallyacoupleofpanelsateachconferenceheldbyexperienceddeveloperssharinglotsofcoolandinterestingthingsthey’vebeenabletoaccomplishwiththeEngineandEditor.Inadditiontothis,makesuretokeepinvolvedintheUnitycommunity,eitherthroughtheforumsonunity3d.com,Twitter,reddit,StackOverflowandUnityAnswers,oratwhateversocialgatheringplacespopoutofthewoodworkinthecomingyears.
Everysingletipthatwasincludedinthisbookstartedoutasanideaortidbitofknowledgethatsomeonesharedsomewhereatsomepoint.So,thebestwaytokeepup-to-dateonthe
http://freepdf-books.com
![Page 391: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/391.jpg)
besttips,tricks,andtechniquesistokeepourfingersonthepulseofwhereUnityisheadingbystayinginvolvedinitscommunity.
http://freepdf-books.com
![Page 392: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/392.jpg)
OthertipsFinally,thefollowingsectioncontainstipsthatdidn’tquitefitintoothercategories.
It’salwaysagoodideatoorganizeourScenesusingemptyGameObjectsandnamethemsomethingsensible.Theonlydrawbacktothismethodisthattheemptyobject’sTransformisincludedduringpositionorrotationchangesandgetsincludedduringrecalculations.Properobjectreferencing,Transformchangecaching,and/oruseoflocalPosition/localRotationsolvestheproblemadequately.Inalmostallcases,thebenefitstoworkflowfromSceneorganizationaresignificantlymorevaluablethansuchtrivialperformancelosses.
AnimatorOverrideControllerswereintroducedwaybackinUnityv4.3,buttendtobeforgottenorrarelymentioned.TheyareanalternativetostandardAnimationControllersthatallowustoreferenceanexistingAnimationController,andthenoverridespecificstatestousedifferentanimationfiles.Thisallowsformuchfasterworkflowssincewedon’tneedtoduplicateandtweakAnimationControllersmultipletimes;weonlyneedtochangeahandfulofanimationstates.
WhenUnity5islaunched,itautomaticallyopenstheProjectWizard,allowingustoopenarecentproject.However,ifwepreferthedefaultbehaviorfromUnity4,whichistoautomaticallyopenthepreviousproject,wecaneditthisbehaviorbynavigatingtoEdit|Preferences|General|LoadPreviousProjectonstartup.NotethatthissettinghasadifferentnameunderUnity4andworksintheoppositefashion.YoucanseethisbynavigatingtoEdit|Preferences|General|AlwaysShowProjectWizard.NotethatiftheProjectWizardisenabled,wecanalsoopenmultipleinstancesofUnityEditorsimultaneously.
TheamazingcustomizabilityoftheUnityEditoranditsever-growingfeaturesetmeansthereareabsolutelytonsoflittleopportunitiestoimproveworkflowsandmorearebeingdiscoveredorinventedeverysingleday.TheAssetStoremarketplaceisabsolutelyrifewithassets,whichtrytosolvesomekindofproblemthatmoderndevelopersarehavingtroublewith,whichmakesitagreatplacetobrowseifwe’relookingforideasor,ifwe’rewilling,dropsomemoneytosaveusatonofhassle.Becausetheseassetstendtoselltoabroadaudience,thistendstokeeppriceslow,andwecanpickupsomeamazinglyusefultoolsandscriptsforsurprisinglylittlecost.Inalmostallcases,itwouldtakeusasignificantnumberofhourstodevelopthesamesolutionourselves.Ifweconsiderourtimeasvaluable,thenscanningtheAssetStoreonoccasioncanbeaverycost-effectiveapproachtodevelopment.
http://freepdf-books.com
![Page 393: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/393.jpg)
http://freepdf-books.com
![Page 394: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/394.jpg)
SummaryThisbringsustothebook’sconclusion,andhopefullyyouenjoyedtheride.Toreiterateperhapsthemostimportanttipinthisbook,alwaysmakesuretoverifythesourceoftheperformancebottleneckviaprofilingbeforemakingasinglechange.Thelastthingwewanttowastetimeonischasingghostsinthecodebase,whenfiveminutesofprofilertestingcansaveusanentiredayofwork.Also,inalotofcases,thesolutionrequiresacost-benefittinganalysistodetermineifwe’renotsacrificingtoomuchinanyotherareaattheriskofaddingfurtherbottlenecks.Makesuretohaveareasonableunderstandingoftherootcauseofthebottleneck,toavoidputtingotherperformancemetricsatrisk.
Performanceenhancementcanbealotoffunsince,duetothecomplexityofmoderncomputerhardware,smalltweakscanyieldbigrewards.Therearemanytechniquesthatcanbeimplementedtoimproveapplicationperformanceorspeedupourworkflows.Someofthesearehardtofullyrealizewithouttheexperienceandskillsnecessarytospendareasonableamountoftimeimplementingthem.Inmostcasesthefixesarerelativelysimple,oncewefindthesourceoftheproblem.So,goforthanduseyourrepositoryofknowledgetomakeyourgamesthebesttheycanbe!
http://freepdf-books.com
![Page 395: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/395.jpg)
IndexA
Ahead-Of-Time(AOT)/ThecompilationprocessAndroidDebugBridge(ADB)tool/RemoteconnectiontoanAndroiddeviceanimationfiles
about/MeshandanimationfilesAPIhistorypage
URL/Usefullinksapproaches,performanceanalysis
about/Bestapproachestoperformanceanalysisscriptpresence,verifying/Verifyingscriptpresencescriptcount,verifying/Verifyingscriptcountongoingcodechanges,minimizing/Minimizingongoingcodechangesinternaldistractions,minimizing/Minimizinginternaldistractionsexternaldistractions,minimizing/Minimizingexternaldistractions
artefacts/Manageresolutiondownscalingexternallyattributes
variableattributes/Variableattributesclassattributes/Classattributes
audioabout/Audiofiles,loading/Loadingaudiofilesprofiling/Profilingaudioformats,encoding/Encodingformatsandqualitylevelsqualitylevels,encoding/Encodingformatsandqualitylevelsperformanceenhancements/Audioperformanceenhancements
AudioClips/TheAudioAreaaudiofiles
loading/Loadingaudiofilesadditionalloadingoptions/Additionalloadingoptions
AudioMixersURL/ApplyFiltereffectsthroughMixergroupstoreduceduplication
audioperformanceenhancementsabout/AudioperformanceenhancementsactiveAudioSourcecount,minimizing/MinimizeactiveAudioSourcecountAudioClipreferences,minimizing/MinimizeAudioClipreferencesforce,enablingtoMonofor3Dsounds/EnableForcetoMonofor3Dsoundslowerfrequencies,resampling/Resampletolowerfrequenciesencodingformats,considering/Considerallencodingformatsstreaming,preventing/Bewareofstreamingfiltereffects,applying/ApplyFiltereffectsthroughMixergroupstoreduceduplication
http://freepdf-books.com
![Page 396: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/396.jpg)
WWW.audioClip,using/Use“WWW.audioClip”responsiblyAudioModulefiles,consideringforbackgroundmusic/ConsiderAudioModulefilesforbackgroundmusic
AudioSources/TheAudioArea
http://freepdf-books.com
![Page 397: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/397.jpg)
Bbackendbottlenecks
about/Backendbottlenecksfillrate/Fillratememorybandwidth/MemorybandwidthVRAMlimits/VRAMlimits
boxing/Boxingbruteforcetesting/Bruteforcetesting
http://freepdf-books.com
![Page 398: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/398.jpg)
Ccachecomponent
references/CacheComponentreferencesobtaining,withfastestmethod/ObtainingComponentsusingthefastestmethod
caveats,StaticBatchingabout/StaticBatchingcaveatsEditModedebugging/EditModedebuggingofStaticBatchingstaticmeshesinstantiationatruntime,avoiding/Avoidinginstantiatingstaticmeshesatruntimerendering/Visibilityandrenderingvisibility/Visibilityandrendering
CgstandardlibraryfunctionsURL/UseGPU-optimizedhelperfunctions
Closures/Closurescodesegments,targetedprofiling
about/TargetedprofilingofcodesegmentsProfilerscriptcontrol/ProfilerscriptcontrolcustomCPUProfiling/CustomCPUProfiling
CollisionMatrix/TheCollisionMatrixCommandBuffer
URL/MultithreadedrenderingCommonIntermediateLanguage(CIL)/TheMonoplatformCommonLanguageRuntime(CLR)/TheMonoplatformcompilationprocess,Monoplatform
about/ThecompilationprocessmanualJITcompilation/ManualJITcompilation
complexMeshCollidersavoiding/AvoidcomplexMeshColliderssimplerprimitives,using/UsesimplerprimitivessimplerMeshColliders,using/UsesimplerMeshCollidersragdolls,optimizing/OptimizingragdollsJointsandcolliders,reducing/ReduceJointsandCollidersinter-ragdollcollisions,avoiding/Avoidinter-ragdollcollisionsinactiveragdolls,disabling/Disableorremoveinactiveragdollsinactiveragdolls,removing/Disableorremoveinactiveragdolls
controls,UnityProfilerwindowabout/Controls,CPUAreaAddProfiler/ControlsRecord/ControlsDeepProfile/ControlsProfileEditor/ControlsActiveProfiler/ControlsClear/Controls
http://freepdf-books.com
![Page 399: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/399.jpg)
FrameSelection/ControlsTimelineView/ControlsCPUArea/CPUAreaGPUArea/TheGPUAreaRenderingArea/TheRenderingAreaMemoryArea/TheMemoryAreaMemoryArea,simplemode/TheMemoryAreaMemoryArea,detailedmode/TheMemoryAreaAudioArea/TheAudioAreaPhysics3D/2DArea/ThePhysics3D/2DArea
coroutineabout/SavingProfilerdataURL/SavingProfilerdatausing/Update,Coroutines,andInvokeRepeating
Coroutines/CoroutinesCPU-boundapplication
about/CPU-boundmultithreadedrendering/MultithreadedrenderingGPUSkinning/GPUSkinning
CustomEditors/Menustips/Customeditors/menustips
http://freepdf-books.com
![Page 400: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/400.jpg)
D2DColliders
circle/CollidertypesPolygon/Collidertypesbox/Collidertypes
3DCollidersMeshColliders/CollidertypesCapsule/CollidertypesCylinder/CollidertypesBox/Collidertypes
DeferredShadingURL/DeferredShading
Dispose()method/CustomCPUProfilingdistance-squared
considering,overdistance/Considerusingdistance-squaredoverdistanceDrawCall
about/DrawCallsRenderState,modifying/DrawCalls
DynamicBatchingabout/DynamicBatchingrequirements,URL/DynamicBatchingvertexattributes/Vertexattributesuniformscaling/Uniformscalingsummary/DynamicBatchingsummaryapplying/DynamicBatchingsummary
DynamicCollidersabout/StaticandDynamicColliders
http://freepdf-books.com
![Page 401: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/401.jpg)
EEditor
hotkeytips/Editorhotkeytipsabout/Editorhotkeytipsinterfacetips/Editorinterfacetips
emptycallbackdeclarationsremoving/Removingemptycallbackdeclarations
ExecutionOrderURL/SavingProfilerdata
externaltipsabout/Externaltipsothertips/Othertips
http://freepdf-books.com
![Page 402: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/402.jpg)
Ffillrate,backendbottlenecks
about/Fillrateoverdraw/OverdrawOcclusionCulling/OcclusionCullingshaderoptimization/ShaderoptimizationShadersintendedformobileplatforms,using/ConsiderusingShadersintendedformobileplatforms
Find()methodavoiding,atruntime/AvoidingtheFind()andSendMessage()methodsatruntime
FirstInFirstOut(FIFO)queue/DrawCallsFixedUpdate()method/MaximumAllowedTimestepFixedUpdateTimestep/Physicsandtimeforeachloops/TheforeachloopsForwardRendering
URL/ForwardRenderingfragmentShader/ProfilingrenderingissuesFrameDebugger/TheFrameDebuggerfront-endbottlenecks
about/FrontendbottlenecksLevelOfDetail(LOD)/LevelOfDetailGPUSkinning,disabling/DisableGPUSkinningtessellation,reducing/Reducetessellation
http://freepdf-books.com
![Page 403: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/403.jpg)
GGameObjectnullreferencecheck
performing/FasterGameObjectnullreferencechecksgameprogrammingpatterns
URL/Externaltipsgarbagecollection,managedmemory
about/Garbagecollectionmemoryfragmentation/Memoryfragmentationatruntime/GarbagecollectionatruntimethreadedGarbagecollection/Threadedgarbagecollectiontactics/Garbagecollectiontactics
GarbageCollectormainthread/Threadedgarbagecollectionfinalizerthread/Threadedgarbagecollection
globalmessagingsystemabout/Aglobalmessagingsystemgloballyaccessibleobject/Agloballyaccessibleobjectregistration/Registrationmessageprocessing/Messageprocessingimplementing/Implementingthemessagingsystemmessage,queuing/Messagequeuingandprocessingmessage,processing/Messagequeuingandprocessingcustommessage,implementing/Implementingacustommessagemessageregistration/Messageregistrationmessage,sending/Messagesendingmessagecleanup/Messagecleanupwrappingup/Wrappingupthemessagingsystem
GPUProfiling/GPUprofilinggreedymethods/CPUArea
http://freepdf-books.com
![Page 404: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/404.jpg)
Hheap/Managedmemoryhotkeytips,Editor
about/EditorhotkeytipsGameObjects/GameObjectsSceneView/SceneViewarrays/Arraysinterface/InterfaceUnitykeyword,accessing/Other
http://freepdf-books.com
![Page 405: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/405.jpg)
IimmutableReferencetypes
strings/StringsareimmutableReferencetypesabout/StringsareimmutableReferencetypesstringconcatenation/Stringconcatenation
inter-objectcommunicationissuestaticclassapproach/StaticclassesSingletonComponents/SingletonComponentsreferences,assigningtopre-existingobjects/Assigningreferencestopre-existingobjectsglobalmessagingsystem/Aglobalmessagingsystem
interfacetips,Editorabout/Editorinterfacetipsgeneral/GeneralInspectorView/TheInspectorViewProjectView/TheProjectViewHierarchyView/TheHierarchyViewSceneView/TheSceneandGameViewsGameView/TheSceneandGameViewsPlayMode/PlayMode
IntermediateLanguageToC++(IL2CPP)about/ThefutureofMonoandUnityURL/ThefutureofMonoandUnity
InvokeRepeatingusing/Update,Coroutines,andInvokeRepeating
IsAliveproperty/Messagecleanupissue
focusingon/Focusingontheissue
http://freepdf-books.com
![Page 406: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/406.jpg)
JJust-In-Time(JIT)/Thecompilationprocess
http://freepdf-books.com
![Page 407: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/407.jpg)
LLevelOfDetail(LOD)
about/LevelOfDetailURL/LevelOfDetail
LightingandShadowingabout/LightingandShadowingURL/LightingandShadowingForwardRendering/ForwardRenderingDeferredShading/DeferredShadingVertexLitShading(legacy)/VertexLitShading(legacy)real-timeShadows/Real-timeShadows
lightingoptimizationabout/LightingoptimizationappropriateShadingMode,using/UsetheappropriateShadingModeCullingMasks,using/UseCullingMaskslightmapping,using/UseBakedLightmapsshadows,optimizing/OptimizeShadows
http://freepdf-books.com
![Page 408: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/408.jpg)
MManagedDomain/UnitymemorydomainsManagedHeap/Managedmemorymassvalues
URL/MassMaterials
about/MaterialsandShadersMaximumAllowedTimestep/MaximumAllowedTimestep
adjusting/AdjusttheMaximumAllowedTimestepmeaninglessdata(noise)
reducing/Reducingnoisememorybandwidth,backendbottlenecks
about/Memorybandwidthlesstexturedata,using/UselesstexturedataGPUTextureCompressionformats,testing/TestdifferentGPUTextureCompressionformatstexturesampling,minimizing/Minimizetexturesamplingassetsorganization,forreducingtextureswaps/Organizeassetstoreducetextureswaps
memoryusageoptimizationabout/MemoryusageoptimizationUnitymemorydomains/Unitymemorydomainsvaluetypes/ValuetypesandReferencetypesreferencetypes/ValuetypesandReferencetypespassingbyvalue/Passbyvalueandpassbyreferencedatalayout/TheimportanceofdatalayoutUnityAPI/TheUnityAPIforeachloops/TheforeachloopsCoroutines/CoroutinesClosures/Closures.NETlibraryfunctions/.NETlibraryfunctionstemporaryworkbuffers/Temporaryworkbuffersobjectpooling/Objectpooling
meshabout/Meshandanimationfiles
MeshColliderconcave/Collidertypesconvex/Collidertypes
mobilegraphicsoptimizationabout/OptimizinggraphicsformobileDrawCalls,minimizing/MinimizeDrawCallsMaterialCount,minimizing/MinimizetheMaterialcounttexturesize,minimizing/MinimizetexturesizeandMaterialcount
http://freepdf-books.com
![Page 409: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/409.jpg)
power-of-2,creating/Maketexturessquareandpowerof2Texturessquare,creating/Maketexturessquareandpowerof2lowestpossibleprecisionformats,usinginShaders/UsethelowestpossibleprecisionformatsinShadersAlphaTesting,allowing/AvoidAlphaTesting
Monoabout/TheMonoplatformfuture/ThefutureofMonoandUnityURL/ThefutureofMonoandUnity
MonoBehaviourUnitydocumentationURL/Removingemptycallbackdeclarations
Monoplatformabout/TheMonoplatformcompilationprocess/Thecompilationprocess
http://freepdf-books.com
![Page 410: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/410.jpg)
N.NET
URL/ThefutureofMonoandUnity.NETlibraryfunctions/.NETlibraryfunctionsnameproperty
retrieving,avoiding/AvoidretrievingstringpropertiesfromGameObjectsNativeDomain/UnitymemorydomainsNestedCoroutines
URL/Usefullinks
http://freepdf-books.com
![Page 411: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/411.jpg)
OOnGUI()method/LoadingProfilerdataOperatingSystem(OS)/TheMonoplatformOrderofExecution
URL/Physicsandtimeoverdraw/Fillrate
http://freepdf-books.com
![Page 412: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/412.jpg)
Ppassbyreference/Passbyvalueandpassbyreferencepassingbyvalue/Passbyvalueandpassbyreferenceperformance-enhancingtechniques
polygoncount,reducing/Reducingpolygoncountnecessarydata,importing/Import/calculateonlywhat’sneedednecessarydata,calculating/Import/calculateonlywhat’sneededbakedanimations,considering/ConsiderbakedanimationsOptimizeMeshesoption/LetUnityoptimizemeshesmeshes,combining/Combinemeshes
performanceanalysisapproaches/Bestapproachestoperformanceanalysis
PhysicsEngineinternals/Physicsandtimeabout/PhysicsEngineinternalstime/Physicsandtimephysics/PhysicsandtimeFixedUpdateloop/TheFixedUpdateloopMaximumAllowedTimestep/MaximumAllowedTimestepphysicsupdates/Physicsupdatesandruntimechangesruntimechanges/PhysicsupdatesandruntimechangesDynamicColliders/StaticandDynamicCollidersStaticColliders/StaticandDynamicColliderscollisiondetection/CollisiondetectionCollidertypes/CollidertypesCollisionMatrix/TheCollisionMatrixRigidbodyactivestate/RigidbodyactiveandsleepingstatesRigidbodysleepingstates/Rigidbodyactiveandsleepingstatesraycasting/Rayandobjectcastingobjectcasting/Rayandobjectcasting
physicsperformanceoptimizationsabout/Physicsperformanceoptimizationsscenesetup/ScenesetupStaticColliders,using/UseStaticCollidersappropriatelyCollisionMatrix,optimizing/OptimizetheCollisionMatrixdiscretecollisiondetection,preferring/PreferdiscretecollisiondetectionFixedUpdatefrequency,modifying/ModifytheFixedUpdatefrequencyMaximumAllowedTimestep,adjusting/AdjusttheMaximumAllowedTimestepcastandbounding-volumechecks,minimizing/Minimizecastandbounding-volumecheckscomplexMeshColliders,avoiding/AvoidcomplexMeshCollidersphysicsobjects,allowingtosleep/LetphysicsobjectssleepSolverIterationCount,modifying/ModifySolverIterationCount
http://freepdf-books.com
![Page 413: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/413.jpg)
ragdolls,optimizing/Optimizingragdollsphysics,using/Knowwhentousephysicsupgrading,toUnity5/ConsiderupgradingtoUnity5
polygoncountreducing/ReducingpolygoncountTweakMeshCompression/TweakingMeshCompressionRead-WriteEnabledflag,using/UseRead-WriteEnabledappropriately
prefabpoolingabout/Prefabpooling,PrefabpoolsPoolableComponent/PoolableComponentssystemrequirements/ThePrefabpoolingsystemobjectspawning/Objectspawninginstanceprespawning/Instanceprespawningobjectdespawning/Objectdespawningtesting/Prefabpooltestingandsceneloading/PrefabpoolingandSceneloadingsummary/Prefabpoolingsummary
ProceduralMaterialsabout/ProceduralMaterialsURL/ProceduralMaterials
Profiler.enableBinaryLogmethod/SavingandloadingProfilerdataProfiler.enabledmethod/SavingandloadingProfilerdataProfiler.logFilemethod/SavingandloadingProfilerdataProfilingandAnalysis
about/FinalthoughtsonProfilingandAnalysis
http://freepdf-books.com
![Page 414: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/414.jpg)
RReferencetypes
about/ValuetypesandReferencetypesarrays/ArraysareReferencetypes
reflection/ManualJITcompilationrenderingissues
profiling/Profilingrenderingissuesrenderingissues,profiling
GPUProfiling/GPUprofilingFrameDebugger/TheFrameDebuggerbruteforcetesting/BruteforcetestingCPU-bound/CPU-bound
ReorderableListsabout/Customeditors/menustipsURL/Customeditors/menustips
rigidbodyproperty/ObtainingComponentsusingthefastestmethodRuntimeHelpers.PrepareMethod()method/ManualJITcompilation
http://freepdf-books.com
![Page 415: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/415.jpg)
Sscenesetup
about/Scenesetupscaling/Scalingpositioning/Positioningmassvalues/Mass
ScriptableObjectsURL/Usefullinks
scriptingtipsabout/Scriptingtipsgeneral/Generalattributes/Attributeslogging/Loggingusefullinks/Usefullinks
SendMessage()methodavoiding,atruntime/AvoidingtheFind()andSendMessage()methodsatruntime
Shaderabout/MaterialsandShaders
Shaders,intendedformobileplatformsusing/ConsiderusingShadersintendedformobileplatformssmalldatatypes,using/Usesmalldatatypeschangingprecision,avoiding/Avoidchangingprecisionwhileswizzlingswizzling/AvoidchangingprecisionwhileswizzlingGPU-optimizedhelperfunctions,using/UseGPU-optimizedhelperfunctionsunnecessaryfeatures,disabling/Disableunnecessaryfeaturesunnecessaryinputdata,removing/Removeunnecessaryinputdatanecessaryvariables,exposing/Onlyexposenecessaryvariablesmathematicalcomplexity,reducing/Reducemathematicalcomplexity,Reducetexturelookupsconditionalstatements,avoiding/Avoidconditionalstatementsdatadependencies,reducing/ReducedatadependenciesSurfaceShaders/SurfaceShadersShader-basedLOD,using/UseShader-basedLOD
ShadowCascadesfeatureURL/OptimizeShadows
skinning/GPUSkinningSparseTexturing
about/SparseTexturesURL/SparseTextures
sphericalharmonics/ForwardRenderingstack/ManagedmemoryStaticBatching
http://freepdf-books.com
![Page 416: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/416.jpg)
about/StaticBatchingrequirements/StaticBatchingStaticflag/TheStaticflagmemoryrequirements/MemoryrequirementsMaterialreferences/Materialreferencescaveats/StaticBatchingcaveatssummary/StaticBatchingsummary
StaticCollidersabout/StaticandDynamicCollidersusing/UseStaticCollidersappropriately
http://freepdf-books.com
![Page 417: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/417.jpg)
Ttagproperty
retrieving,avoiding/AvoidretrievingstringpropertiesfromGameObjectstemporaryworkbuffers/TemporaryworkbuffersTexture/Texturefilestexturefiles
about/Texturefilescompressionformats/Compressionformatsperformanceenhancements/Textureperformanceenhancements
textureperformanceenhancementsabout/Textureperformanceenhancementsfilesize,reducing/ReduceTexturefilesizeMipMaps,using/UseMipMapswiselyresolutiondownscaling,managing/ManageresolutiondownscalingexternallyAnisotropicFilteringlevels,adjusting/AdjustAnisotropicFilteringlevelsatlasing,considering/ConsiderAtlasingcompressionratesfornon-squaretextures,adjusting/Adjustcompressionratesfornon-squareTexturesSparseTexturing/SparseTexturesProceduralMaterials/ProceduralMaterials
theMSDNC#ProgrammingGuideURL/Registration
TotalAllocatedblock/ThreadedgarbagecollectionTransformchanges
caching/ConsidercachingTransformchanges
http://freepdf-books.com
![Page 418: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/418.jpg)
UUnity
URL/SavingProfilerdata,ThefutureofMonoandUnityfuture/ThefutureofMonoandUnity
Unity3D/TheUnityProfilerUnity5.0/TheUnityProfilerUnityAPI/TheUnityAPIUnitydocumentation
URL/ConsiderAtlasingUnityEditor
profiling/Editorprofilingreflection,URL/Customeditors/menustips
UnityEditor;about/TheUnityProfilerUnitymemorydomains
about/Unitymemorydomainsnativememory/Nativememorymanagedmemory/Managedmemory
UnityProfilerabout/TheUnityProfiler,UnderstandingtheProfilerlaunching/LaunchingtheProfilerUnityEditor/EditororstandaloneinstancesStandaloneInstances/EditororstandaloneinstancesUnityWebplayerconnection,connecting/TheUnityWebplayerconnectionconnecting,toiOSdevice/RemoteconnectiontoaniOSdeviceconnecting,toAndroiddevice/RemoteconnectiontoanAndroiddevicewindow/TheProfilerwindow
UnityProfilerdatasaving/SavingandloadingProfilerdata,SavingProfilerdataloading/SavingandloadingProfilerdata,LoadingProfilerdata
UnityProfilerwindowabout/TheProfilerwindowcontrols/Controls
UnityroadmapURL/ThefutureofMonoandUnity
UnityWebplayer/LaunchingtheProfilerUnloadAudioData()method/Additionalloadingoptionsunusedscriptsandobjects
disabling/Disablingunusedscriptsandobjectsdisabling,byvisibility/Disablingobjectsbyvisibilitydisabling,bydistance/Disablingobjectsbydistance
http://freepdf-books.com
![Page 419: Unity 5 Game Optimization - smactech.in · There are further alternatives that we can explore, such as making use of Unity’s built-in bridge between script code and the Inspector](https://reader031.fdocuments.in/reader031/viewer/2022022104/5bc7407d09d3f201518d3060/html5/thumbnails/419.jpg)
Vvaluetypes
about/ValuetypesandReferencetypesstructs/StructsareValuetypes
VerticalSync(VSync)/MinimizinginternaldistractionsVisualStudio
URL/ExternaltipsVisualStudioToolsforUnity(VSTU)/OtherVRAMlimits,backendbottlenecks
about/VRAMlimitstexturepreloading/Texturepreloadingtexturethrashing/Texturethrashing
http://freepdf-books.com