# Day 18 | FPS滅火AR遊戲開發Part3 - 火焰生成 ###### tags: `Unity` `AR手遊` 昨天的文章中已介紹火焰粒子的製作,那麼今天的文章將會說明如何在AR世界中產生火焰! ## 火焰產生器 在場景中,創建一個Empty GameObject,添加新的火焰產生器script,宣告物件變數,放入上一篇文章製作的火焰Prefab。 ``` public Gameobject FlamePrefab; ``` 遊戲機制為計時到固定時間後,產生火焰,在限時內滅火一定數量即可通關。主要的框架如下: ``` void Update() { if(產生 == true){ Fire();//產生火焰function; }else{ nextFireTime();計時下一次產生火焰funtion; } } ``` 因為產生器的機制與計時有關,所以放在Update()函式當中。 ### 火焰產生器計時,時間一到就升火 nextFireTime() 在產生器的class當中宣告計時變數。 ``` privae float generateTime = 0f; ``` 在計時的函式nextFireTime()中,如果計時超過了2.5秒,就呼叫產生函式Fire(),產生一朱火焰;如果還沒到產生時間,就讓generateTime持續增加Time.deltaTime,繼續計時。 ``` nextFireTime() { if(generateTime>2.5f) { Fire(); //產生火焰 }else{ generateTime += Time.deltaTime; } } ``` ### 隨機地點生成 在Fire()函式當中,產生火焰之前要先隨機選擇要產生的點: * 宣告int變數,儲存使用Random.Range函式生成的數值 * 宣告Vector2變數,用來儲存之後要產生的Position * 利用switch選擇Position * 使用ViewportToScreenPoint * Viewport:相對於相機是標準化的。相機的左下角是 (0,0);右上角是 (1,1); z 位置以相機的世界單位為單位。 * ScreenPoint:以像素為單位定義。屏幕左下角是(0,0);右上角是(pixelWidth , pixelHeight)。z 位置以相機的世界單位為單位。 * 生成的火焰希望分別是三個位置,固定的y值。 ``` int Randomnum; Vector2 screenPosition; Randomnum = Random.Range(0, 3); switch (Ramdonnum) { case 0: screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.25f, 0.4f)); break; case 1: screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.5f, 0.4f)); break; case 2: screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.75f, 0.4f)); break; } ``` ### 射線、平面管理器 * 在ARSessionOrigin中掛上AR PlaneManager及AR RaycaseManager兩個元件 * 將AR Default Plane製成Prefab,放入AR PlaneManager的Plane Prefab中(不喜歡預設的Plane可以針對Mesh的部分做更改) ![](https://i.imgur.com/cJsoqdz.png) ### 射線、平面碰撞 在產生器的class當中宣告ARRaycastManager,在Unity將ARSessionOrigin放入。 ``` public ARRaycastManager raycastManager; ``` * 宣告撞擊List,儲存射線撞擊物體的訊息。 * 使用Raycast,從螢幕座標的一個點向可追蹤類型投射光線。 * 如果有撞擊發生,取得撞擊的第一個位置作為產生火焰的位置。 ``` List<ARRaycastHit> hits = new List<ARRaycastHit>(); raycastManager.Raycast(screenPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.Planes); if (hits.Count > 0) { GameObject.Instantiate(FlamePrefab, hits[0].pose.position, hits[0].pose.rotation); } ``` --- 今天的文章利用 Raycasy Hit搭配Plane偵測,順利的讓火焰在AR世界中產生了,下一篇就會撰寫滅火的部分,那就明天見~