A*及射線檢測運用-激光與子彈

A*及射線檢測運用-激光與子彈:

DEMO

DEMO 影片

github連結

(一) 概要

在開發這款遊戲前,我心想要製作一款射擊類遊戲,因此我研究了有關於射線的內容。此外,由於射擊類遊戲,我在地圖上新增了一些地形。因為這個原因,像是無限繼承中的簡單敵人AI就沒辦法做到追蹤玩家,而是會被地形卡住。所以,我搜尋了有關於敵人AI尋路的功能,最後決定使用A*來實作。

同樣的,為了使遊戲具有可玩性,我依舊添加了無限波數的系統。只是這次我想在強化方式上,做出一些改變,從隨機的強化,進入到有規則、有策略性的強化。以及加入更多RPG元素。

因此,我選擇了升級系統,透過擊敗敵人來獲得經驗值,從而升級。升級後,獲得技能點,進行天賦加點。透過這樣的方式來強化玩家。

不同於上一款遊戲的部分則是,我將Buff系統安裝到了敵人的身上,在每次敵人生成時,隨機給予特定數量的特定Buff,以此提升遊戲的隨機性,以及挑戰性。其中包含:普通武器免疫、能量武器免疫、巨大化等。

至於這款遊戲的核心,槍戰系統。我採用子彈數的方式來實現,總共有數種不同的槍可供使用,這些槍都有子彈數限制,子彈則可透過擊殺敵人隨機掉落。用意除了限制玩家的火力外,也是想使遊戲更有難度。可是不同於普通槍戰遊戲的點是,我添加了使用能量的武器,這種武器的能量用光後會自動回復。以及次元武器,這種武器消耗的是儲備的次數,但也會隨著時間回復。

(二) 遊戲玩法

透過WASD移動腳色,鼠標瞄準,鼠標左鍵射擊、鼠標右鍵手刀。並透過E、R、T、Y、G、H可進行武器切換,按下P鍵可暫停遊戲。

在天賦樹頁面,可以將現有天賦點進行分配,只是目前只有啟動武器的幾個天賦,以及一些強化而已。

敵人則有危險度分級,從低到高分別是:白、綠、藍、紅、金、黑,分別代表敵人身上持有的Buff數量,從零到五。

(三) 子彈功能實裝

在這款遊戲中,我實裝了無限繼承中提到的追蹤彈功能。此外,也設計了四種不同的槍械,透過調整子彈的發射時間,以及速度、顏色、傷害等,分成了四種:步槍、加特林(機槍)、散彈槍、狙擊槍。

以及作為次元武器的次元跳躍,只要鎖定某個定點後,便能在數秒後,出現在那個位置。可以透過連續使用,做到花式操作的感覺。只是因為這個功能而出現了能出現在牆中以及場地外的BUG。目前暫時未處理。

(圖二十五)遊戲畫面以及武器欄

實際的代碼部分,則可在底下的路徑中找到。
槍械設計相關代碼:
(Ray Game\Assets\Scripts\Weapon.cs)

(四) 射線檢測_激光

在開發之前,我便決定要學習的功能其實是射線檢測。不論是作為平台類遊戲中,玩家跳躍時是否落到地面的判斷,或是檢測玩家是否接觸到可拾取物體的判斷。都能用射線檢測完成。

透過教學影片,我簡單的了解了有關射線檢測的內容。在教學影片中,將射線檢測放置在怪物身上,並讓怪物在定點來回移動。因為我覺得這樣的話難度太低,所以改造了一下,將怪物的激光實時對準玩家的所在地,並讓怪物追蹤玩家。

(圖二十六)怪物激光效果

1.	private void Detect()  
2.	    {  
3.	        RaycastHit2D hitInfo = Physics2D.Raycast(firePoint.position, target.position - this.transform.GetChild(0).position, maxDist); //獲取射線命中物  
4.	             
5.	        if(hitInfo.collider != null && shoot == true) //開啟射擊模式,且目標不為空  
6.	        {  
7.	            if(hitInfo.collider.tag == "Wall")  
8.	            {  
9.	                //Debug.DrawLine(firePoint.position, hitInfo.point, Color.green);  
10.	  
11.	                lineRenderer.SetPosition(1, hitInfo.point);  
12.	                lineRenderer.colorGradient = greenColor;  
13.	            }  
14.	            if (hitInfo.collider.tag == "Player")  
15.	            {  
16.	                //Debug.DrawLine(firePoint.position, hitInfo.point, Color.red);  
17.	  
18.	                lineRenderer.SetPosition(1, hitInfo.point);  
19.	                lineRenderer.colorGradient = redColor;  
20.	  
21.	                GameObject.Find("Player").SendMessage("Hurt"); //命中玩家  
22.	            }  
23.	  
24.	            //Instantiate(hitEffect, hitInfo.point, Quaternion.identity); //生成爆炸效果  
25.	            lineRenderer.SetPosition(0, firePoint.position);  
26.	        }  
27.	    }

(圖二十七)射線檢測部分代碼(Ray Game\Assets\Scripts\FireElement.cs)

在完成怪物部分的激光後,我開始嘗試在玩家身上增加激光武器,但不知道為何,機光束總是不能鎖定在玩家和鼠標之間,有時會偏移,有時會隨機旋轉。當時,我查了許多教學,只能大概知道是座標(世界座標或本地座標)轉換之間的問題,卻沒辦法解決這個問題。最後只能放棄。

(五) 敵人AI升級_A*尋路

我這次將敵人的AI升級,其原因是場地上出現了障礙物,因此簡單的追蹤玩家無法成功。在查找一些資料後,我選擇使用A*提供的尋路功能,能透過簡單的設定,完成地圖的配置,使敵人依著設定,走在沒有障礙物的路上,並朝著玩家前進。

(圖二十八)A*底下的地圖設定

(六) 存檔機制

在無限繼承中提到過PlayerPrefs的儲存方式,但在這款遊戲中,我使用了其他的存檔方式。最一開始我嘗試著使用的是JSON的序列化方式,但因為存在BUG始終無法解決,我最終改用二進制的方式儲存。

從實作來看,二進制和JSON的實作較為相似,但XML有明顯的不同,至於PlayerPrefs則完全不一樣。值得一提的是,因為我的天賦樹是透過scriptableObject來儲存,因此當我想在遊戲中,儲存升級後的技能點,並在天賦樹介面同步時,會出現問題。在查詢完相關資料後,似乎是因為沒有激活的原因。於是在存檔機制上,我後來設計為不同的場景使用不同的存檔區塊。

在修正過程中,其實也有犯過蠢,比如說在數據改變時,重新儲存一次檔案。只是在那個時候,遊戲中的數據已經被初始化了,導致那份存檔除了修改過的數據外,其他全都是初始化的結果。當時卡了蠻久的。

存檔機制實作:
(Ray Game\Assets\Scripts\PlayerUI.cs)

(七) 天賦樹系統

最後,是這款遊戲的核心之一,天賦樹系統,主要的設計是根據教學影片得來的,從建立scriptableObject做到在Unity中便可以直接設計天賦,簡單化天賦的管理相當於將資料庫實體化。

如果在製作無限繼承時,我便知道這個功能的話,我應該不會在程式碼中建立資料庫,而是改用scriptableObject來做。過程的確是較輕鬆,不論是資料處理還是應用,都能透過圖形化來處理。唯一的問題就是在存檔機制中提到的,未激活導致兩個場景之中,無法直接調用變數。

天賦模板:
(Ray Game\Assets\Scripts\SkillData.cs)

天賦樹系統:
(Ray Game\Assets\Scripts\SkillManager.cs)

(圖二十九)天賦樹系統


A*及射線檢測運用-激光與子彈
https://z-hwa.github.io/webHome/[object Object]/Game-develope/A-及射線檢測運用-激光與子彈/
作者
crown tako
發布於
2021年10月11日
許可協議