Tutorial Unity - Fire Spread - IMedia9 - Creative Networks

Breaking

Saturday 6 September 2014

Tutorial Unity - Fire Spread

Halo agan-agan, sobat Unity semuanya? Apa kabar? Gimana? Udah pada nge-Like fans page Kiky Si Kancil kan? Terima kasih buat yang udah, buat yang belum, Like atuh euy, da bageur, hehehe. Oke, hari ini gue mau ngasih sebuah tutorial special buat agan Apriyandi. Dia lagi mau punya sebuah kasus fire spreading atau api yang menyebar di antara titik-titik objek tertentu. Pertanyaannya bisa dilihat di sini: http://unity3dindo.forumid.net/t123-ask-algoritma-yg-pas-buat-api-apa-ya#596

Nah, terus terang kasus ini sangat sulit. Gue sendiri mesti mikir berkali-kali untuk nyari algoritma yang tepat. Dan hasilnya, gue nyerah. Serius. Gue nyerah. Akhirnya, gue lebih fokus ke masalah gimana caranya efek penyebaran api itu bisa dilihat secara visual dengan keren. Gue pun bikin sebuah algoritma sederhana yang skemanya bisa agan lihat di sini.


Intinya sederhana ada. Gue cari SELURUH gameobject di dalam Scene yang memiliki TAG tertentu (hasilnya berupa array gameobject), terus gue tentuin dari array itu INDEX mana yang akan jadi TITIK PUSAT api. Dari Index itulah gue cari semua jarak ke gameobject, dan gue URUT berdasarkan index terdekat. Begitu tombol di klik, api menyala di titik api terus merambat ke seluruh game object lain berdasarkan jarak terdekatnya. Pusing ? Sama! Gue juga yang bikinnya pusing. Nah, daripada pusing-pusing gimana kalau agan ajakin temen agan untuk nge-Like Kiky Si Kancil juga? *eaaaa, geje lagi!*

Daripada pusing, kita coba bikin ajalah ya? Oke, pertama-tama bikin dulu project Unity. Udah pada tahu bikinnya kan?


Habis itu impor Package Particle dengan cara klik kanan di Panel Assets, Impoert Package -> Particle.

Habis itu bikin sebuah script C# dengan cara klik kanan di Panel Assets, Create -> C# Script. Kasih nama Identification. Script ini berguna buat nyimpen Index dan Distance setiap GameObject ke GameObjet yang akan dijadikan titik api. 


Agan ketik deh Script di bawah ini:
1:  using UnityEngine;  
2:  using System.Collections;  
3:  public class Identification : MonoBehaviour {  
4:       public int Index;  
5:       public float Distance;  
6:       // Use this for initialization  
7:       void Start () {  
8:       }  
9:       // Update is called once per frame  
10:       void Update () {  
11:       }  
12:  }  

Habis itu agan bikin lagi satu script, namanya Create Fire. Caranya sama. Script ini untuk jadi trigger api sekaligus itung-itungannya.


Agan ketik deh Script di bawah ini:
1:  using UnityEngine;  
2:  using System.Collections;  
3:  public class CreateFire : MonoBehaviour {  
4:       public GameObject FireSource;  
5:       public string TargetTag;  
6:       public int TargetStartIndex;  
7:       GameObject[] AllGameObject;  
8:       // Use this for initialization  
9:       void Start () {  
10:            GetAllGameDistance(TargetTag,TargetStartIndex);  
11:            SortingByDistance();  
12:       }  
13:       // Update is called once per frame  
14:       void Update () {  
15:       }  
16:       void GetAllGameDistance (string aTag, int aFirstObject) {  
17:            AllGameObject = GameObject.FindGameObjectsWithTag(aTag);  
18:            for (int i=0; i<AllGameObject.Length; i++){  
19:                 AllGameObject[i].AddComponent<Identification>();  
20:            }  
21:            AllGameObject[aFirstObject].GetComponent<Identification>().Index = 0;  
22:            AllGameObject[aFirstObject].GetComponent<Identification>().Distance = 0;  
23:            for (int i=0; i<AllGameObject.Length; i++){  
24:                 AllGameObject[i].GetComponent<Identification>().Index = i;  
25:                 AllGameObject[i].GetComponent<Identification>().Distance = Vector3.Distance(AllGameObject[i].transform.position, AllGameObject[aFirstObject].transform.position);  
26:            }  
27:            Debug.Log(AllGameObject[aFirstObject].GetComponent<Identification>().name);  
28:       }  
29:       void SortingByDistance() {  
30:            int Maximal = AllGameObject.Length;  
31:            for (int i=0; i<AllGameObject.Length-1; i++){  
32:                 int Imax = 0;  
33:                 for (int j=1; j<Maximal; j++){  
34:                      if (AllGameObject[j].GetComponent<Identification>().Distance > AllGameObject[Imax].GetComponent<Identification>().Distance){  
35:                           Imax = j;  
36:                      }  
37:                 }  
38:                 int Temp = AllGameObject[Maximal-1].GetComponent<Identification>().Index;  
39:                 AllGameObject[Maximal-1].GetComponent<Identification>().Index = Imax;  
40:                 AllGameObject[Imax].GetComponent<Identification>().Index = Temp;  
41:                 Maximal--;  
42:            }  
43:       }  
44:       IEnumerator StartFlameFrom (string aTag, int aIndex) {  
45:            AllGameObject = GameObject.FindGameObjectsWithTag(aTag);       
46:            for (int i=0; i<AllGameObject.Length; i++){  
47:                 for (int j=0; j<AllGameObject.Length; j++){  
48:                      if (i == AllGameObject[j].GetComponent<Identification>().Index){  
49:                           GameObject temp = (GameObject) Instantiate(FireSource, AllGameObject[j].transform.position, AllGameObject[j].transform.rotation);  
50:                           yield return new WaitForSeconds(1);  
51:                      }  
52:                 }  
53:            }  
54:       }  
55:       void OnGUI(){  
56:            if (GUI.Button(new Rect(10,10,50,50), "Fire!")){  
57:                 StartCoroutine(StartFlameFrom(TargetTag, TargetStartIndex));  
58:            }  
59:       }  
60:  }  

Habis itu agan bikin Cube, caranya klik menu GameObject ->3D Object -> Cube. Oh ya, gue pake Unity 4.6 jadi menunya rada beda. Untuk yang pake Unity 4.5 ke bawah, menunya kalao nggak salah GameObject -> Create Other -> Cube.
Bikin Cube sebanyak yang agan mau, tapi inget yang penting setiap Cube harus DIKASIH TAG: KOTAK. Cara ngasih Tag ke Object tuh lihat di gambar. Kalao Tag Kotaknya belum ada ya, Add Tag aja dulu. Tag ini penting agar kita bisa ngedapetin semua GameObject dalam scene tapi difilter ostosmastis berdasarkan Tag.
 Tuh gue bikin Cube banyak tuh. Nah, habis itu agan pasang deh Script CreateFire ke Main Camera. Caranya Drag aja langsung sampai script CreateFire jadi Componentnya si Main Camera. Nah, habis itu isi deh Fire Source nya dengan Particle Fire1. Lihat di gambar deh. Bisa di drag atau di browse (klik yang tombol bulet kecil)


 Terus untuk property (public variabel)  Target Tag, isi dengan "Kotak" pan tadi kita bikin Tag nya kotak. Sedangkan untuk Index bisa diisi 0. Artinya api bakalan muncul di index ke 0 baru nyebar ke gameobject yang lain. Kalau Index bisa diisi 3, berarti api bakalan muncul duluan di index ke 3 baru nyebar ke gameobject yang lain. Suka-suka agan ajalah.

Kalau sudah semuanya, silahkan di tes. Agan bisa bereksperimen dengan jenis partikel dan indeksnya. Termasuk delay dari berapa lama api lainnya ngerembet. Itu ada di bagian script yang ada WaitForSeconds(1) - artinya api ngerambat per satu detik.


Nah, sekali lagi gue tekankan kalau cara ini nggak menganut algoritma apa pun. Script ini murni ditujukan untuk menghasilkan sebuah special effect yang keren. Kalau ada agan-agan punya algoritma yang lebih baik - dan lebih sederhana, monggo bisa share di forum.


Gitu deh. Mudah-mudahan tutorial ini bisa sedikit ngebantu agan Apriyandi. Ngomong-ngomong script yang agan kasih kemarin itu mumet euy. Saya nyerah mempelajarinya. Jadi saya bikinin script simpel ini dan juga skemanya supaya algoritma mudah dipahami. Makasih banyak buat yang udah pada mampir di blog geje saya. Kiky Si Kancil? Gokil!

No comments:

Post a Comment