Unity3D – Game Engine – Script Lifecycle Flowchart
My website: http://www.lucedigitale.com
Ref: http://docs.unity3d.com/Manual/ExecutionOrder.html
Unity 3D – CSharp – Event Functions – Inizialization – Update – GUI – Mouse – Physics
To create videogames Unity3D give us special functions to manage special operations as variable inizialization, updating, physic management.
using UnityEngine; using System.Collections; public class MyScript : MonoBehaviour { // Initialization Events // ****************************************** void Awake () { // first inizialization Debug.Log("Awake called."); } void Start () { // second inizialization Debug.Log("Start called."); } // Regular Update Events // ****************************************** void FixedUpdate () { // frame indipendent update // use this function to drive physic Debug.Log("FixedUpdate time :" + Time.deltaTime); } void Update () { // update at every frame Debug.Log("Update time :" + Time.deltaTime); } void LateUpdate () { // update at the end of the frame rendering Debug.Log("Late Update"); } // GUI Events // ****************************************** void OnGUI() { // draw here labels, buttons and other Graphic User Interface elements GUI.Label(labelRect, "Game Over"); } // Mouse Events // ****************************************** void OnMouseOver() { // do something if mouse is over } void OnMouseDown() { // do something if mouse is down } // Physics Events // ****************************************** void OnCollisionEnter(otherObj: Collision) { // do stuff if there is a collision } void OnTriggerEnter(Collider other) { // do stuff if there is an object that overlap the trigger } } // END MyScript
My website: http://www.lucedigitale.com
Ref: http://docs.unity3d.com/Manual/EventFunctions.html
Unity3D – C# – Basic Syntax
First you need call basic namespace and nest all the code inside a class with the name of your script, see the example below.
Project Window> RMB> Create> C#> name it ‘MyFirstScript’> double click to open ‘MonoDevelop’ editor
// call basic namespace of Unity3D using UnityEngine; using System.Collections; // MonoBehaviour is the base class every script derives from // class nameofmyscript : derived from MonoBehaviour public class MyFirstScript : MonoBehaviour { // Unity3D exclusive function - Use this for initialization void Start () { }// END Start() // Unity3D exclusive function - Update is called once per frame void Update () { }// END Update() }// END of class MyFirstScript
// call basic namespace of Unity3D using UnityEngine; using System.Collections; // MonoBehaviour is the base class every script derives from // scope class nameofmyscript : derived from MonoBehaviour public class MyFirstScript : MonoBehaviour { // declare variables // scope type nameofvariable = value public int myInt = 5; // you can setup it inside inspector private int myInt2 = 6; // you can't setup it inside inspector // Unity3D exclusive function - Use this for initialization - void because it has no type void Start () { myInt = MultiplyByTwo(myInt); Debug.Log (myInt); }// END Start() // Your custom fuction // scope type functionname (type variable) public int MultiplyByTwo (int number) { int ret; ret = number * 2; return ret; } // Unity3D exclusive function - Update is called once per frame - void because it has no type void Update () { }// END Update() }// END of class MyFirstScript
Unity3D – Object Pooling – Bullets – CSharp
Object Pooling è una tecnica per ridurre i calcoli della CPU.
Questo sistema di programmazione consiste nel creare un gruppo di oggetti, storarli inattivi all’interno di una lista, per poi attivarli e posizionarli direttamente nell’area di gioco.
La generazione di tutti gli oggetti comporta un consumo di RAM iniziale elevato, che comunque è molto meno costoso in termini di prestazioni del dover ogni volta istanziare e distruggere i singoli eggetti.
Applicare questa tecnica ha senso se utilizziamo a video nello stesso tempo almeno diverse centinaia di oggetti o stiamo sviluppando su piattaforma mobile dove la potenza di calcolo della CPU non è elevata.
Creiamo una scena con:
(parent) Spaceship
– (child) Bullet
All’oggetto ‘Bullet’ applichiamo:
BulletScript.cs
using UnityEngine; using System.Collections; public class BulletScript : MonoBehaviour { public float speed = 5; // Use this for initialization void Start () { } // Update is called once per frame void Update () { // simple move the object transform.Translate (0, speed * Time.deltaTime, 0); } }// END MonoBehaviour
Questo script semplicemente muove l’oggetto
BulletDestroyScript.cs
using UnityEngine; using System.Collections; public class BulletDestroyScript : MonoBehaviour { // This function is called when the object becomes enabled and active. // It is a part of MonoBehaviour.OnEnable() void OnEnable() { Invoke ("Destroy", 2f); // call the function after 2 second } void Destroy() { gameObject.SetActive (false); // deactivate the object } // This function is called when the behaviour becomes disabled () or inactive. // It is a part of MonoBehaviour.OnDisable() void OnDisable() { CancelInvoke(); } }// END MonoBehaviour
Questo script disattiva l’oggetto dopo 2 secondi per ottimizzare il rendering
All’oggetto ‘Spaceship’ applichiamo:
BulletFireScript.cs
using UnityEngine; using System.Collections; using System.Collections.Generic; // to add Lists public class BulletFireScript : MonoBehaviour { public float fireTime = .1f; // attiva un oggetto bullet ogni xxx secondi public GameObject bullet; // Assign in Inspector public int pooledAmount = 20; // numero di oggetto instanziati, se insufficienti aumentarli public List<GameObject> bullets; // Use this for initialization void Start () { // crea una lista di oggetti inattivi bullets = new List<GameObject> (); for (int i = 0; i < pooledAmount; i++) { GameObject obj = (GameObject)Instantiate(bullet); obj.SetActive (false); // inattivi, verranno attivati dalla funzione Fire() bullets.Add (obj); // aggiungi l'oggetto alla lista Debug.Log(bullets.Count); } InvokeRepeating ("Fire", fireTime, fireTime); // richiama la funzione Fire() }// END Start void Fire() { // posiziona e attiva tutti gli aoggetti della lista bullets for (int i=0; i < bullets.Count; i++)// scorre tutti gli oggetti della scena { if (!bullets[i].activeInHierarchy)// se un oggetto nella scena non è attivo { bullets[i].transform.position = transform.position;// posiziona bullets[i].transform.rotation = transform.rotation;// rotazione bullets[i].SetActive(true);// attiva break; }// END if } }// END Fire }// END MonoBehaviour
Assegniamo in Inspector l’oggetto ‘Bullet’ alla variabile ‘bullet’
Questo script:
1. Crea una lista
2. Start () -> Instanzia 20 oggetti, li disattiva e li inserisce nella lista
3. Fire() -> posiziona gli oggetti e li attiva
Avviate il gioco, osservate Hierarchy e Inspector per BulletFireScript.cs per comprenderne il funzionamento
Si può notare dal codice di tutti gli script che – Destroy (gameObject) – NON è mai stata utilizzata, perchè i 20 oggetti bullet vengono continuamente riciclati attivandoli e disattivandoli di continuo.
Unity3D – Object Pooling
What is a pool?
In computer science, a pool (piscina) is a set of initialised resources that are kept ready to use, rather than allocated and destroyed on demand.
A client of the pool will request an object from the pool and perform operations on the returned object. When the client has finished with an object (or resource), it returns it to the pool rather than destroying it.
What is object pooling?
In games you need to manage a lot gameobjects at one time (bullets, enemies etc…), and istantiate and destroy every object can slow down your game performance.
To improve performance and save CPU time the best way is create a pool of gameobjects and request gameobjects from the pool.
For example you can have an gameObject off screen named “enemies” which holds all the enemies, and a master script to manage it:
enemies (Empty Game Object) -> master script ‘Enemy.js’
|
|—-enemy
|
|—-enemy
|
|—-enemy
Another example is reuse bullets:
Slower performance:
1. Awake(), do nothing
2. Update()
a- Instantiate bullet in its start position
b- Move along the way
c- Move bullet in its final position
d- Destroy bullet
Object Pooling. best performance:
1. Awake(), create a pool off screen
2. Update ()
a- Get gameobject bullet from the pool
b- SetActive -> true, Move bullet in its start position
c- Move along the way
d- Move bullet in its final position
e- SetActive -> false
f- Reuse from point b- and so on…
In terms of performance for real scenarios, if you use only 10-50 gameobjects at one time the benefits of object pooling are irrelevant.
In Unity3D you will need object pooling when you have thousands of gameObjects at one time or if you develop for slower mobile devices.
References:
http://answers.unity3d.com/questions/321762/how-to-assign-variable-to-a-prefabs-child.html
http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/object-pooling