0% found this document useful (0 votes)
5K views6 pages

46 Tips & Tricks For 2D Mobile Performance in Unity

This document provides 46 tips for optimizing 2D mobile game performance in Unity. Some key tips include using Unity's built-in physics engine instead of a separate 2D engine, keeping object scales and masses realistic, batching sprites from the same texture together, using sprite sheets to reduce draw calls, choosing optimized mobile shaders, and reducing texture sizes and compression to improve load times. Proper use of physics, sprites, textures, and memory management are emphasized to improve frame rates on mobile devices.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5K views6 pages

46 Tips & Tricks For 2D Mobile Performance in Unity

This document provides 46 tips for optimizing 2D mobile game performance in Unity. Some key tips include using Unity's built-in physics engine instead of a separate 2D engine, keeping object scales and masses realistic, batching sprites from the same texture together, using sprite sheets to reduce draw calls, choosing optimized mobile shaders, and reducing texture sizes and compression to improve load times. Proper use of physics, sprites, textures, and memory management are emphasized to improve frame rates on mobile devices.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

46Tips&Tricksfor2DmobilePerformanceinUnity.

Unitysabeast.Imalwaysimpressedathowversatileandperformantitcanbe.Butlikeanybeastit
requiresalittlebitoftaming(andinsomecasessomeverycounterintuitivetrickery,butthatswhere
thismetaphorfallsapart).IvehadabitofastrugglegettingTruckTosstoplaysmoothlyonmy3GS,
butheresanicebiglistoftipstohelpyouonyourway.
IfthisisyourfirstjumpintotheworldofUnity,myfirsttip(thisonesafreebie)istostoptryingtouse
itlikeotherlanguagesandenvironments.YouwillbeusingGameObjects,youwillbeaddingmultiple
scriptcomponents,andyouwillhavetothinkdifferently.WhenIfirststarted,myapproachwasto
largelyignoreprefabs(orusethemlikeFlashsdisplaylist)andgetacopyofBox2Drunning.Painful
asitistodeviate,getreadytoputinsomework!
Withoutfurtherado,letsgetstarted:Physics:
Usethebuiltinphysics.
Itmightseemlikeawasteofcyclestohaveafully3Dphysicsenginerunningtheshowfora2D
game,butbearinmindthattheNvidiaPhysXenginewillberunninginUnitysnativecore.Were
talkingaboutahyperoptimisedenginemaintainedbylargeprofessionalteams,andnotahobbyist
2Dengine.FreezeZpositionandX/Yrotationforthat2Dfeel.
Trytousea1/1scale.
BythisImean,1unit=1meter.Youcanuselargerorsmallerscales,butyourelikelytoencounter
someweirdnesswhenitcomestocollisions,andthespeedatwhichobjectsfall.Remember,agrand
pianowithoutairresistancewillfallasfastasadeadbabybutifeverythingislarge,itwillseemslow.
Youcanfiddlewithgravity,butagain,yourerunningtheriskofmessingwithcollisions.Iliketousea
1/32scalecomparedtomyspriteswithacamsizeof160.
GetyourobjectMassright.
Justlikewithscale,ifyouhaveagrandpianoweighing2gmoradeadbabyweighing500kgthings
aregoingtogetunpredictable.Trytokeepitrealisticish.
Meshcolliderscanbeslowcomparedtoprimitivebox/spherecolliders.
Whileaspheremayhavemanymorevertsthansayacube,theuniformdistancefromthecentre
wouldmakeitmassivelyeasiertocalculatethanlotsofindividualtriangles.
Youcansimulatemorecomplexshapesbycombiningprimitivecolliders.

IfyouhaveaparentobjectwithsayaBoxColliderandRigidbodycomponent,youcanaddchild
objectswithjustaBoxCollider.Theentireobjectwillcollidelikeonesolidmultipartobject.
Continuingfromtheabove
Ratherthanhavingseveraloftheselinkedtogether,youcanaddmorechildobjectswithRigidBodies
andColliders,anduseJointstoconnectthemtotheparentobject.Youcouldbuildacompoundcar
forexamplewithaparentbodytomovetheentirething.
Multiplebasicjointsarenotsupportedononegameobject
butmultipleconfigurablejointsare.Ratherthanhavinganetworkofjointedobjectsyoucouldfor
examplehaveaspringandasliderfromwheeltoaxlecuttingdownonasuspensionobjectin
between.
ObjectswithacolliderbutnoRigidBodyareconsideredstatic.
Movingtheseisexpensive,soifyourecreatingthemwithcode,addthecolliderandphysicsmaterial
(tothecollider)afterpositioning.
Whileitsconsideredgoodpracticetokeepyoursolveriterationsconstant
youmightfinditbeneficialtousethefullamountonlyevery2ndupdate.I.e.8,4,8,4,8,4.Ifthis
alleviatessomeoftheprocessorloadthesolverforexamplemaynothavetoskipiterations,andwill
actuallyprovideamoreconsistentsimulation.Isaiditwasgoingtobecounterintuitive.
WhiletheuseofInterpolationandExtrapolationonRigidBodiesisdiscouragedenmasse..
insomecasesyoumightfindthatturningtheseon,andreducingtheoverallsolveriterations
providesabettersimulation.Fiddle.
Loweryourtimestep!
Ifyoureaimingforanunrealistic60FPSandthephoneisconstantlystruggling,yourebestjustto
settleforalowerframerateandgiveitsomebreathingroom.Iliketousea0.03fixedtimestepwitha
maximumofabout0.05.Again,itcanbeslightlycounterintuitivedecreasingtimestepstogethigher
framerates,butgiveitashot.
Timescalescaling.
Thiscouldhelp,dependingonthefeelyouregoingfor.Itsimplysimulatesmoretimepassing
betweeneachiteration.Settingthistoohighwillobviouslymesswithcollisions,especiallyifanobject
hastraveledsay,amileinoneframe,itsnotgoingtohitadamnthing.
Sprites&TexturesMyengineusesahybridsystemofSpriteManager2/EZGUIandRageSplinefor
sprites,butIveused2DToolkitandmuchofthefollowingstillapplies.
Easyonthefillrate!
Itmightseemobviousbutifyouhavea6464image,withonlythetopleft3232filled,thatsstilla
6464sprite.Trimyourtransparentimageswherepossible.Lotsoflibrarieswilldothisautomatically.
Hidespritesyourenotusing.
Makeareferencetothemandsetthemactive=falseTheywontbedrawnwhenoffscreenanyway,

butsomethinghastodeterminewhetherornottheyrevisibleandchancesareyouknowbest,
especiallywhenonespritemaybefullyhiddenbehindanotherandisstilldrawn.
Batchingisyourfriend.Butnotalways.
Ifyouhave40collectablecoinsinyourlevel,allusingthesamespritethenbatchingwillusetheone
texturesourcemultipletimesonagiantmesh,savingondrawcalls.Drawcalls=time.Insomevery
rarecasesthebatchcalculationscanbeahinderance,dependingonhowyourgamessetup,butif
thatsthecase,chancesareyouredoinitwrong.
ResizeyourspritesQuad(thespriteitself)ratherthanitstransform.
IfyouhavesayaspritecomponentonaGameObject,thenresizetheGameObjectstransform,
youregoingtobreakbatchingonthatsprite.Insteadconsiderthenextpoint.WithSM2forexample,
youdjustsettheSprite/PackedSpritesWidthandHeightpropertiesintheinspector.
Ifyouhavea6464sprite,ona6pxwidecube
thenitsgoingtolooklikeasmallversionofyourimage,butuponzoomingin,youllseethatthefull
6464spritehasbeenUVmappedtothecubeinperfectdetail.RememberwhatIsaidaboutfillrate.
Unlessyourezoominginandout,youmightnotwanttousesuchalargetexture.
UseaSpriteSheet/Atlaswherepossible.
Thisoneoughttogohigher,butwhatthehell.Aspritesheetwillallowyoutousecommonlygrouped
itemslikeyourcharacter,coins,platforms,etcinasingleimage/texture.Why?Lessdrawcalls!The
samepartofatexturecanbeUVmappedtodifferentpartsofa3Dshapemultipletimes.I.e.ifyou
weremodellingaredandwhitestripycandycane,youddrawonewhiteandoneredline,thenapply
themmultipletimes.Thisisasimilarconcept.
Usetherightshaders!
Theresnopointusinglitshadersifyouvenolighting,andtheresnopointusingatransparent
shaderonasolidsquaresprite.YoucanfinddedicatedmobileshadersintheUnityStore,by
googlinganddoingalittlecopypastaviaMonoDeveloporusingthosethatcomewithSM2/Unity.As
of3.5Ibelievethedefaultshadersdoaprettydecentjob.Comingfromvariousotherbackgroundsit
mightbeeasytounderestimatetheimportanceoftheseevenina2Denvironment.
Doyoureallyneedantialiasing/filteringonyoursprites?
Besuretocheckonyourtargetdevice.Somethingswilllookprettyhorrificscaleduponyour
monitor,butabsolutelyfineonthosetinyhighdensityscreens.Giveitashot,andremembertoapply
changestoyourSpriteAtlaswherepossible.
Easyonthecompression!
DXT(DirectX)compressionwilldoafantasticjobonyourPC,withhardwaredecoding,butmobile
deviceslackthishardwaredecoderandwillhavetodoitinsoftware.I.e.Slowly.GenerallyIOS
deviceswillsupporthardwarePVRTCcompressionandAndroidsETC,andkeepinmindwhatIsaid
inthelastpoint.DXTmightbefinegiventhatitoffersbetterclarityduringsaylevelloads,butyou
certainlydontwanttobedecompressingthemduringgameplay.

DoyouneedMipMaps?
Mipmapsarescaleddownversionsofatexturestoredwithinthecompressedtextureitself.So
dependingonhowfarawayyouare,alowerrescopycanbeused.Obviouslythistakesmore
memoryandmoredecompressiontime.Youprobablydontneedemfora2Dgame.
Conversely
ratherthanusinggiantspritesonanonretinadisplayandtinyspritesonaretinadisplay,itmight
beworthyourwhilemakingasmallandlargeversionoftexturesandusingeachaccordingly.
Read/Writeenabledtexturesgenerateasecondcopy.
Secondcopyneedsmorememory.Inmostcases,youcanjustleavethisturnedoff.
Tintingaspritewillbreakbatching
andcreateanewcopyofthesourcetextureinmemory.Avoidwherepossible,ortrytopremake
anycolorsyoullneed!E.g.ifallyourNumbersinatextspritesheetaretobered..doitinphotoshop.
Loading,SavingandObjectAccess:DoyoureallyneedtorecreateyourGUIforeachlevel?
Youcanhideitandhaveitpersistwhenloadingdifferentscenes,reducingloadingtime.
GameObject.Instantiate()isslow!
Onecommontechnique(whichprovedabsolutelyvitalinTruckToss)istocreateapoolofobjects
duringloading.E.g.4ofeachenemytype.Whenanobjectsnolongerneeded,disableitandshove
itbackinthepoolinsteadofrecreatingit.Soyoudhaveafunctionalongthelinesof
MakePrefab(path/to/prefab)whichwillonlyonlycallResources.Load()providedtherearenonein
thepool.Resources.Load()isevenslower!
Thisfunctiondoesnotcache,andinvolvesreadingfromthedevicesHDorequivalent.Ideallyyou
wantahybridpoolsystemifyouredoingalotofloading\unloading.I.e.yourstandardpoolsystem
whichpreloadsobjects,butwhentheinstantiatefunctioniscalled,itkeepsadifferentcopyina
differentlist.Wheneverinstantiatescalledandtherearentenoughinthepoolbuttheresacopyin
thesparelist,InstantiatefromthatratherthandoingaResources.Loadfreshagain.Thisisa
balancingactofmemoryuseandprocessoruse,sotargetitforyourdevice.GameObject.Find()
andGetCompoenent()..
areslow(Yousawthatonecoming,right?).Ifyouregoingtobeusinganobjectorcomponent
repeatedly,thenitmakessensetocreateareferencetoitinalocalvariableratherthanlookingitup
repeatedly.Reflectivefunctionscanbenoticeablyslower.
Reflectionistheabilityforalanguage\codetolookwithinitselfandgetmethodnames\types\scope
etcandpotentiallyalterthem.I.e.callingafunctionbystringname,orusingdelegates.Trytoavoid
thiskindaofbehaviourforperformancecriticalcode.Thegarbagecollectorissloweryet.
Ithastoscantreesofobjectslookingfororphanedclassesandobjects,andislandsofobjectswith
referencesonlytoeachother,determinehowlongtheyvebeenthatway,andthenfreeupthe
memory.Sureyoucancallitmanually,butthatsgenerallymoreofahinttoitthanacommand,and
shouldntgenerallybeusedduringgameplay.Usingtoomuchmemory
willcauseIOSdevicestocrash\quitandyourappwontbeacceptedtotheappstore.Thats
actuallysecondarytothepointthatwhenmemoryslow,yourgamewillslowdowndramatically,

especiallyduringgarbagecollectionsandwhenyouretryingtoinstantiatenewobjects.

Sounds:
SetyourBGmusictodecompressonload.
Anythingyoullbeusingalotshouldprobablybedecompressedonloadratherthanstreamingfrom
thedisk(whichisslowandcanbeespeciallytroublesomeonAndroid.)Thisisanothertradeoff
situationhowever,giventhatdecompressioncantaketimeandmemory.Balanceit!
Infrequentlyusedclips
..maybeleftcompressedinmemory,especiallyiftherearelotsofthem.
Forcetomono?
Yesyes!Unlessyoureallywantstereoandyouvegotsomebitchinmusicorsoundeffects,youll
saveyourselfsomespaceonthisone.Rememberthephonehasamonospeaker
Hardwaredecodingisfaster.
Well,thatsageneralisation,butfasterisbetter.
UI:
UnitysUIsystemisslow.
Wherepossibletrytouseapluginorspritepackagethatrenderstomeshesin3Dspace.
OnGUIisslow!
Eveninablanksceneyoucanseeitspike.Trytohavenomorethanoneoftheseinyourcode,and
centralisebranchesoutfromit.Itsfairlyeasilydone.
TrytokeepyourUIanimationsinFixedTimestep()functions.
Thiswaytheyllstayconsistentacrossmultipledevicesandframerates.Youmightbenefitfrom
havingallofyourgamelogicforeveryclassbranchoutformasinglebasecalltoFixedTimeStep()
DoesyourUIhavetoupdate*every*frame?
Youmightgainamassiveperformanceboostbydeferringittoevery2ndorthirdframe.Withtruck
toss,thegamerunsmuchsmootherwiththeentiretyofthegamelogicrunningoneverysecond
FixedUpdate.Iknow,right?
MoarCameras!
Ifyourgamedoesalotofscaling\zooming,thenwhyhavetoscaletheUIandriskbreaking
batching?AddanothercamerafortheUI,andsetUIobjectslayerstothatofthecamera.Again,it
soundslikealotofextrablitting,butcouldpotentiallyspeedyourgameupwithverylittleinthewayof
changes.
BuildOptions:
Disabletheaccelerometer!
InolderUnities,thatwasdonevia#definekaccelerometer_frequency0intheAppControlerclassvia

XCode.NowadaysyoucandisableitfromwithinUnityitself,andcanfreeup23FPS.
InsomecasesOpenGLES1.0or2.0
willofferbetterperformanceonyourdevice.ThisseemstovarybetweendevicesandAndroid\iOS.
Tryonasmanydevicesasyoucan.
Stripthingsdown!
Whenyourgamesrunningniceandstable,switchcompatibilitytothe.NET2.0subset,Stripping
LeveltomicromscorlibandScriptCallOptimisationtoFastbutnoExceptions.Thiswillgeneratea
smallerbinarywithlessredundantcodeanddebugsymbols.Isuccessfullynavigatedthatone
withoutastripperreference.Jugs.
TargetiOS5wherepossible.
Therereallyisnodiscerniblespeeddifference.However,makesureyourXCodeprojectssettings
match,oruploadingtoiTunesmightfail.Perhapsitsworthexportinganotherproject.
BonusContentBuildingFaster!:
SymlinkUnityLibraries
fromthebuildsettingswherepossible,thiswillsavecopyingmorefilesovertoxCode,by
effectivelycreatingashortcut.Muchloveforsymlinks.
SetyourDebugInformationFormat
FromwithinXcode(BuildSettings)toSTABS,otherwisehavefunwatchingDWARFtakingages.
Stabs..dwarfLols
SometimesusingBuildfor
withinXCodewillbuildandrunfaster.Deletethepreviousversiononyourdeviceandgiveitashot.
Ihavenoideawhythisisso,butyourewelcome.
BonusContent2Fasterphysicsmodelling:ThisisafunlittletechniqueIusetoconvertedge
chainstosolidblocks!Createafakeedgechain,whereeachlinkbetween2pointsisactuallya
stretchedout,rotatedcubeparentedtosomething,formingtheoutlineofshapeofyourchoice
(cloud\star\car\whatever).Hitplay,andwhilethegameisrunning,dragyourchainbackintothe
editortomakeaprefab.Younowhaveagroupofparentedobjectsyoucanfillinandmakesolid.
Thisletsyouuseyourowncodetogeneratephysicsshapes.
Andfinally,
Breakeveryrule.Inthespiritofhackingawayatthings,youmustfiddleandseewhatsgoingon.If
somethingseemslikeasillyideaatfirst,youmightjustnothavethoughtaboutitfromallangles.
Letmeknowifyouveanythinginterestingtoadd.Happyhacking!

You might also like