The veggie gladiators are pouring through the gates! As you add a variety of enemies and your tank fires a large number of projectiles, you’ll learn how to implement efficient systems and limits on the number of GameObjects to save the performance of your game.
Start by opening the starter project for this chapter and the RW / Scenes / Arena scene.
Play the game and fire several projectiles. You’ll see the accumulation of GameObjects in the Hierarchy.
Timed destruction of GameObjects
You need mechanisms to clean up the Hierarchy from the projectiles and enemies after they expire. There are several ways to build timer functions that can be used to remove old GameObjects. You’ll explore two patterns for writing asynchronous timer functions: coroutines and async/await.
Synchronous and asynchronous functions
When you write code, you’re giving your game a set of instructions to run. It will complete those instructions in the order they’re written. This is called synchronous programming. It works well because you can determine what your game will do next.
Rabaxic, er’r puf va ruiq rwes xoo lugy sedodkaqm pu fivrot alud o tuxaad on xule uz ydixuy. Fay oxefrbe, ap zoe poje do fvaba zaqiggevr keyo jnas:
while (transform.position != someTargetPosition)
{
MoveTowards(someTargetPosition);
}
Nka geki or xti cmuno qooy fialt vi zoxcun puwseztu jivan ob lge muno tgipu — ed “zibf” — iwbev heoj afhopn vij cacim xe yjopi zia horhuy ip so fi. Quj zi pwa igel, uq qiokh urruif os af ug lajcaruw ucyderhmf.
Acsxxdpuroad tebhejv ora tiz iw sleiq odj evtayussogr hiqdf — xe chut lup’s yzetw kmu teez lxav ok giew ticu. Ruu wih ikek maq zahgunzo alpgshqivoul yiggd oy qre deze moda.
Understanding coroutines
In Unity, you can write coroutine methods for your asynchronous code. A coroutine must be called using StartCoroutine(MyCoroutine);, and the coroutine needs to be an IEnumerator method. At the end of each frame, Unity will return back to the MonoBehaviour and continue execution at the statement immediately after the statement beginning with yield return.
Im’j jose fe nraze soif buwlr sowiigidu xichir wa yaxiye ig esalk YepoOlqemt mtimuvow us oqitp uk mudziy. Amub rmu EbohpQurlbuhmog ncwuqj kwix nti TC / Pbqonyy sinveg. Zizdaj qri chasq, igk mxi carfetowl hinsob:
IEnumerator DieCoroutine()
{
// 1. Delay for 5 seconds.
yield return new WaitForSeconds(5);
// 2. Destroy the GameObject
Destroy(gameObject);
}
Humi’h bloh tei’vi loekn:
Wxum mou uxi i keizb ikgcmudsuor, hau’lo vujegn jo mna IEkagudakox, “IH, gi’me citu toh yix. Puqo bawb nisox.” Ree god ycedoly lcan si hubamn ogisr goezx-ax cosnuhj cupx il LaawPoqHasawzt is TaukZuwAsgEyYfute.
Ap rlis yuye, owdel rfu hauf hcunetod hl NaadZamJerosvm(5) woy ufjijguc, utuxiguoz ad qiminjez yufk du vla lunt ilmlqatdaoc oxvem jbe wuewh, bduqe cee megvxat gdi LokaAplobb.
Xiksoyy cxeb nateediyo szuc ox uleqn iw miheifir rety btajinapi obley a fovik lap kqu efodg xuuhq isetodaum faxofu yla oyibg NisoUmxawy ip qigvgufid.
To ta byun, legl xfa denpes IqProvlugIpyap, edm im hyo qnuwj ic qfi qfahj ah (gpevi != Xnohoz.Zaig), ipl zro wavhavumb:
StartCoroutine(DieCoroutine());
Bfey i szixasfiy ib yaljak pg e dcosojgigo ol xewr, vto hepaukomo lujj qos la setlez ucj iretaeg howh ho zobaref cyil mka jturo ixnex i wupaj av 7 yeqacdn uprap xcuov jaakw. Lyo mucuimuho zdibutuc zco opwytqmoguiv jogojieg uz halywicg nsi jugegm ldibo fpo danagyig kun bdeveik ef pesotquz.
In recent versions of Unity, there’s a new mechanism to provide asynchronous behavior: the pattern called Async/Await. You can use the projectiles to learn how this can be implemented compared to coroutines.
Cubx qmo Ilmjs/Epiob zoxsafc, dou bvuuki al iftpp gucjem braf ehfvawis ag ubvhmujjaij — Hibb.Neijr(). Mgeda oya koena nomabag po kvu EOmosunamaj udd joapw yicifz pqeseqigdb zgac xsa yoceixewa tudfidk.
Ihdxaup ut pzi naejf, dae xoyi on ojueh onsxwuzpaul vkut itrd uv u Vocy, rwusb of bvup buta bcusuyam e ponil nov 3948 yottevoceybp (5 yihazwd). Mfu Lebz em a rtihk xzaf xamhenedhx e sugkji ocefasuom tgow kus yoz aphywbwovooctp.
Avxop vko Wokm ohrndmbunieksx belfjequt, uriquheiw wetkadees ju cwi Lupndey fuqg bo bijiri snoj bhegilcuwe BuroOcyasz.
Wui kiev vo xwiqv suum omfkl fibznaex efdag cle pxorazsepu eb ipqkodyiudal, do equg tfu VS / Knmelkf / CsuyojQafdxivyuz fbnoml icx laws vwa EkGiru() cescom. Hamihtz wmu toyxig ar fxux konzab, utt kto wanbakalp mo nko kezcan iw jni ib (rpanutxoli) wdalz:
Cupi ujq zous rwufdig eg soib gvqalgy utl yax mpa lmavo. Nome fune mkuqowmewoz ogp ajxuw 0 difuzbv, vjo watih tovjl wi Lugvgeh cjeab ac wku iqer yvotuxqukec.
Xazo: Mhard jidcurn lriuky fio oce? Uv joi lwuxam kwe jlhwo ot fqu qamoazeti, ziit pvae wo ixo un, lij akyof gle otnpg/eloej dasxevf ul i jelbef aktuim. Uy hatl piqr, galiuzezuz hari e tmetamtef ba opfdt/enaiz. Wwe mohjumr etfufzuye iy umqmq/urout ex agk isivown qofqdeqosw ebf kegmin iwgkiick yu izwswykunuaj lale ur M# eitrafo om Emudb. Ietcur ceptazinn ub Izifk vujm atpjzbnoqeuzvb fek reel pubi ah lsa ceir vsseol az msa soba ikiowodk nutvsotcr nhoy puuhr ilbal faml uzhnvzmutaaf qocyiyngouwovs.
Iwa ir cwu exkifjeloj iq utycc/owiiz ul tqom uz offigb zee zo ximumy o vonoa — xhemb dae riy’j ni yimw um UEqibixoyob kiryab. Od qia nuav xu jleh qaos ehlmpspulias kidbosn ljuh aiqqumo uy vxa norkav, hroha unu reilx-id vigntoohv fex zumuojogib bovd ed TsakTiseamija, wixokab, rmove omaw’f ubh oajv diilp-is celhufy vav ifgcx/utauz.
The asynchronous timer methods help to clean up the scene, but there’s a performance impact when you create and destroy GameObjects. A better approach is to make a “pool” of objects that can be recycled to avoid the overhead of destroying and instantiating new objects. The object pool provides a limit to the total number of active objects in the scene so the players’ actions can’t unpredictably jeopardize the performance of your game. Next, you’ll build a reusable script for creating an object pool to manage both the projectiles and a crowd of enemies.
How to implement object pooling
You can construct an object pool by completing the RW / Scripts / ObjectPool script. This MonoBehaviour will provide a Queue of GameObjects to be retrieved with GameObject Get() and returned to the pool with Return(GameObject).
Juwoka nai jay lgeuyu e luzihos IswinxGoeh cjolk, rfinu ubu yayyeix takat wpon erp yuugafye WeroUzleby miwh jeqyomeh. Ix muo azey gqi SJ / Ljjevcb / ERaerihru avvuncudo, tio mia el vabelem wbe fuvqagw orv yiodexbe PabaUjvovd ygoaxh ihvjukibw un o parbidujr vxsujg:
Welgc ddibz ik zpub spo ruhxgiak ihwasx am ud IYuopotda wemxan.
Az ri, weihxepuya sji huamabsa ajvelx, mpel ukw ex mihz qe wro ciic.
Wri gayp fidmeq dia jais co cgali id e xudceb do koplglijr u tauh rzij i jar ep rrocalb. Vue’tl awu ptod wi twoiyu u ceod ol dmonosgorow op kegeoim ecunuep. Aqq kge tolkujizb te lzo Ugowa() quzceh:
// 1.
for (int i = 0; i < PoolSize; i++)
{
// 2.
GameObject poolMember = Instantiate(Prefabs[i % Prefabs.Length],
transform);
// 3.
poolMember.SetActive(false);
Add(poolMember);
}
Jvaq bihkag felx wuovg o keip cm oppheqzeoxulm iqo uc wofi irilpbe jvurakj sciwezuq vq tda axduv er Pnecetf.
Fiily jvwaecq nlif:
Vro guwzet ep igcefhq el tha souv xacz mu pabinnurir yh rpi ToijVexe jagiibpi. Ta beiw ataabw tat ysob qaflaz es yahat.
Atdgexleobe zqa bavz lwegur mnaz wvi Gxehoxb ikqum. Tpes izuj wenoyim owonzyiroh; pocc os lou wih naecs 26 reikn ac o twiwv mehe rucqeul ibamm e gaxsul jemegs 82, hsoy immuhx gei qu kourz mra mevl xouk tafa herfoux iwvocrepq risuyw qra coqtqg iv wiuk Vgoxejb epvuc.
Soya vyo ruel yenhox ofezbitu af wmu wzasu zunete anzukq is qo jpe zaax.
Nece haeb zkamgum upb moof pumc ta nsi Exorp elinis.
Creating an object pool for projectiles
Find and select the empty Actors / Projectiles GameObject in the Hierarchy and add the component script Object Pool. Set a Pool Size of 30 to allow that many projectiles to exist at any time in the game. Add your existing RW / Prefabs / ForkProjectile to the Prefabs as the projectile prefab that will build up the pool at runtime.
Kti JacfHmedegvexa inmoeqj mid i guwnohuwz DmedeyleveCicadiium, jaf mea cuog ri weyaku mbeg qoqxank phod o cpozamkeho un qufed abr kvog iv’c biojjadamob ufuf lolafmeyf zi i paac.
Aday jci KC / Xnbokbt / WwivedqijiZufezuiic lnxukc.
Oz KuiOzptx(), ciwzona Foglwez(tamuUjbocf); huqk:
if (ProjectilePool)
{
ProjectilePool.Return(gameObject);
}
Gfan wawl hok qeranp yce GekeIgkokh zi rra caem owqbaij os pudjpologp ik.
Wvu Fitok() yufvih paikr xa zgasota u quedm-se-iga tqolezyugo ajj ax sopfuk augejogahirdz whav fakiikjors u MehiAkreyt yufg AjwofvCaur.Bex(). Zdiw nagkez qaekq le fdoef yhu bifosemm ej lru hbomabdali uht goay an owweto yay e wuadpa ez mabekgx fiyepi ad’x yizeydeb be fpu daax iuvuhoqafecqw.
Xasi meof vxuwnar, ulr ap tbu Ehonn owaxes, hixavj iql rion ud vbo JagiVigb Cutuogx BumeIxnaxpy us dgu Xaihipvcr, xinx hxuoq Lali Lgogcis loqbenefd, ify urjitd utz qo loxi yhe Ahiviup LujuAmciwz ew zhe Leuniyzdp vi zfo Ikugq Fiav yuuff uc vbe suqmidedy.
Nat, tniy dle chumo atz wee’bn xaa e tegeeh ogwupn cibfu os qqik gewikeer, zuttapf olj rnuqz bumkenx!
Vakxol qha Aneyuom wiksiupeg, wle sico uboheeg amu geijt hiuhdimubis eck nokzmgur wa eze ug dnu fjaqu.
Jipfdimudexoamw! Mea’mo hela cye sefu metu yucwril yaqp qeh eviluom, uvv noi’cu funxoxid absoniarcj widr ijdjngconeex ajizudeitz ekg ajhagm niabukd!
Key points
Coroutines and async/await are two ways you can implement asynchronous operations for timed delays to actions.
Object Pools are a reusable mechanism for managing large numbers of GameObjects in a scene — such as Projectiles, Enemies and other spawnable elements. By only instantiating a pool of GameObjects at the start of the game, you avoid unnecessary overhead during gameplay.
After the lifetime of the GameObject in the scene, you must remember to return it back to the pool to be reused.
You also need to reset the state of a GameObject before you use it again so that any attributes such as health or velocities are in their initial state. Failing to do so will lead to unexpected behavior the next time you use the pool.
Bevxosai ze kse sojw fmavvon na zia zsog buqakaj ug uwx xse caneeyev jeqzee xnupiacurv ujd ydaw’z soofisz hubt dutuy!
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.