<!-- css 字體設定 --> <style> .reveal { font-size: 24px; } </style> # 虛擬實境4-2 <!--放入主題照片 統一 =480x320 --> ![](https://i.imgur.com/1GFtpOm.png =480x320) [原始課程 link](https://learn.unity.com/tutorial/lesson-plan-4-2-follow-the-player?uv=2018.4&projectId=5cf96846edbc2a2bcde6d0fc#) ###### tags: `虛擬實境AA` ---- ## 課程目標 - 賦予物件物理特性:`bouncy` - 使敵人能自動追蹤玩家的位置 - 在平台上自動生成敵人 - 學習使用更高等的函式或變數,讓整體程式碼變專業且好看 ---- ## 新增一個敵人 ---- ![](https://i.imgur.com/LB21tWX.png =840x) 在`Hierarchy`點擊右鍵 選取`3D Object` 點擊`Sphere` :warning:並將球體拉離開玩家 好進行編輯的部分 ---- ![](https://i.imgur.com/BGeZp5A.png =840x) 將新物件名稱修改為`Enemy` ---- ![](https://i.imgur.com/dAN3POk.png =840x) 在`Inspector` `Transform`找到`Scale` 將XYZ都更改為`1.5` ---- ![](https://i.imgur.com/3DIB83L.png =840x) 在`Project` `Assets` `Texture` 隨機找一個與玩家物件不同的外觀款式 將其拖移至上方的`Enemy` ---- ![](https://i.imgur.com/xbIGm8R.png =840x) 將`Enemy`的`Position`的Y軸更改為`0.15` ---- ![](https://i.imgur.com/OGMOHIJ.png =840x) 為了對抗玩家 我們也必須將敵人球體變為實體 因此在`Enemy` `Inspector` 拉到最下方 點擊`Add Component` 並搜尋`Rigidbody` (由於上一篇ppt已有介紹 若有不清楚的地方 請自行回顧上一篇:blush::blush::blush:) ---- ## 建立物理特性 ---- ![](https://i.imgur.com/mmOmBqw.png =840x) 在`Project` `Assets`點擊右鍵 點選`Create` 選取`Folder`建立一個新的資料夾 ---- ![](https://i.imgur.com/V3WKzbg.png =840x) 將此資料夾命名為`Physical Materials` ---- ![](https://i.imgur.com/lZUuB1B.png =840x) 在`Physical Materials`資料夾點擊右鍵 點選`Create` 選取`Physical Material` ---- ![](https://i.imgur.com/6VpIGcB.png =840x) 將檔名更改為`Bouncy` ---- ![](https://i.imgur.com/Nd8WchD.png =840x) 將`Bouncy`拖移至上方的`player` ---- ![](https://i.imgur.com/qzuPw17.png =840x) 同樣的也拖移至`Enemy` ---- ![](https://i.imgur.com/Uj6CyZa.png =840x) **(P)如何知道`player`跟`Enemy`都有`Physical Material`?(P)** 點擊`player`或`Enemy`並在右方的`Inspector`找到`Sphere Collider` 裡面的`Material`中 如果有成功加入會顯示`Bouncy` ---- ![](https://i.imgur.com/n8pkAVo.png =840x) 點擊`Bouncy`並更改`Bounciness`為`1` `Bounce Combine`更改為`Multiply`並測試看看會有甚麼改變 ---- ## 使敵人能自動追蹤玩家 ---- ![](https://i.imgur.com/dZFtc9Q.png =840x) 在`Project` `Assets` `Scripts`點擊右鍵 點選`Create` 點擊建立`C# Scripts` 將檔案取名為`Enemy`後 並拖移`Enemy.cs`到`Hierarachy`的`Enemy`中 並雙擊打開 ---- ![](https://i.imgur.com/S9tg7xJ.png =640x) 在`public class(){}`中打上 ```csharp public float speed = 3.0f;//給予速度變數一個數值 private Rigidbody enemyRb;//建立enemy實體變數 private GameObject player;//建立player物件變數 ``` 在`void Start(){}`中打上 ```csharp enemyRb = GetComponent<Rigidbody>();//拿取enemy實體變數數據 player = GameObject.Find("player");//在所有的GameObject中尋找player,並拿去player的數據 ``` 在`void Update(){}`打上 ```csharp enemyRb.AddForce((player.transform.position - transform.position)* speed);//給予enemy一個往player位置的力 ``` ---- ## 程式碼debug ---- (P)在程式碼寫完後 我們可以按下撥放鍵遊玩 其中會發現 如果敵人離玩家很遠 那麼力的公式將會因為距離而不斷累加 造成敵人撞到玩家時會產生太大的力而將玩家彈飛 所以以下對於程式碼的修改 目的是為了不讓敵人的速度持續累加造成力量過大(P) ---- ![](https://i.imgur.com/69NiO8h.png =840x) 在`void Update(){}`更改為 ```csharp enemyRb.AddForce((player.transform.position - transform.position).normalized * speed); ``` ---- ## 使視野朝向前方 ---- 在`void Update()`打上 ```csharp= Vector3 lookDirection = (player.transform.position - transform.position).normalized; //並將enemyRb.AddForce((player.transform.position - transform.position).normalized * speed); 修改為 enemyRb.AddForce(lookDirection * speed); ``` ---- ## 在平台中的隨機位置生成敵人 ---- ![](https://i.imgur.com/Ty5gvtu.png =840x) 在`Project` `Assets`點擊右鍵 點選`Create` 點擊`Folder` 並取名為`Prefabs` ---- ![](https://i.imgur.com/xLxuFyz.png =840x) 將`Hierarchy` 中的`enemy`拖移至下方剛建立的資料夾`Prefabs`中 ---- ![](https://i.imgur.com/xQmIKSf.png =840x) 將`Hierarchy` 中的`enemy` 刪除 ---- ![](https://i.imgur.com/V1VQqwh.png =840x) 在`Hierarchy` 中點擊右鍵 點選`Create Empty` ---- ![](https://i.imgur.com/fmfPpgA.png =840x) 將新的`GameObject` 取名為`Spawn Manager` ---- ![](https://i.imgur.com/YNfnZDV.png =840x) 在`Project` `Assets` `Scripts`點擊右鍵 建立一個新的`C# Scripts` ---- ![](https://i.imgur.com/A2zjMO2.png =840x) 取名為`SpawnManager` ---- ![](https://i.imgur.com/W0PmiYS.png =840x) 將剛剛建立好的`SpawnManager`拖移至上方的`Spawn Manager` ---- ![](https://i.imgur.com/Lb65oEX.png =640x) 打開`Project` `Assets` `Scripts`中的`SpawnManager` 在`public class`中打上 ```csharp public GameObject enemyPrefab;//建立enemy prefab變數 ``` 在`void Start(){}`中打上 ```csharp Instantiate(enemyPrefab, new Vector3(0,0,6), enemyPrefab.transform.rotation);//將敵人建立在指定的XYZ上 ``` ---- ![](https://i.imgur.com/2IAfWyi.png =840x) 點擊`Hierarchy`的`Spawn Manager` 在右方的`Inspector` 將`Project` `Prefabs`中的`Enemy`拖移至`Enemy Prefab` ---- (p)此時多次測試遊戲會發現敵人只會重生在同一個點 所以必須修改程式碼 使讓它出現在隨機的位置(p) ---- ![](https://i.imgur.com/Af3wGVi.png =840x) 在`void Start`中打上 ```csharp float spawnPosX = Random.Range(-9,9); float spawnPosZ = Random.Range(-9,9);//經過測量發現平台大小大約落在9x9的範圍中 Vector3 randomPos = new Vector3(spawnPosX, 0, spawnPosZ);//在此範圍產生隨機一個地方並給予其一個變數儲存位置 Instantiate(enemyPrefab, randomPos, enemyPrefab.transform.rotation); ``` ---- ![](https://i.imgur.com/HwzX59g.png =840x) (p)試著讓程式碼變得更專業、好看(p) 在`public class`中打上 ```csharp private float spawnRange = 9;//將void Start裡重複的9改成不被更改的變數 ``` 在`void Start`中打上 ```csharp float spawnPosX = Random.Range(-spawnRange, spawnRange); float spawnPosZ = Random.Range(-spawnRange, spawnRange);//將spawnRange代入原本寫9的地方 ``` ---- ## 利用自定義的函式使程式碼變得好看 ---- ![](https://i.imgur.com/G3MuYh0.png =640x) 在`void Start`中打上 ```csharp //GenerateSpawnPosition()是等等會寫在最下面的函式 Instantiate(enemyPrefab, GenerateSpawnPosition(), enemyPrefab.transform.rotation); ``` 在`public class`中的最下面建立一個`GenerateSpawnPosition()`函式 ```csharp private Vector3 GenerateSpawnPosition() { float spawnPosX = Random.Range(-spawnRange, spawnRange); float spawnPosZ = Random.Range(-spawnRange, spawnRange); Vector3 randomPos = new Vector3(spawnPosX, 0, spawnPosZ); return randomPos; } ``` ---- 可以前往下一小節了
{"metaMigratedAt":"2023-06-15T14:32:27.394Z","metaMigratedFrom":"YAML","title":"虛擬實境4-2","breaks":true,"contributors":"[{\"id\":\"06326c0f-824e-4964-b604-fd9b52334bb2\",\"add\":6363,\"del\":626}]"}
    472 views