iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
自我挑戰組

老菜雞挑戰30天學爆Unity&C#會成功嗎?...系列 第 8

【Day8】老菜雞學下樓梯遊戲之生成、移動階梯-Unity Instantiate&GetComponent&Destroy應用

  • 分享至 

  • xImage
  •  

前言

昨天學到如何管理重複性高的物件(Ex.遊戲中的階梯)—用Prefab,而今天就是要寫出如何生成階梯&如何移動階梯的程式碼。


如何移動階梯

  • 如果想要讓這些階梯都可以往上移動,就要幫這些階梯新增一個往上移動的功能。
  • 首先創建一個C#檔案(命名為Floor)→在Update裡寫使物件移動的function→存檔
[SerializeField] float moveSpeed = 2f; 

Void Update()
{ 
transform.Translate(0,moveSpeed*Time.deltaTime,0); 
//由於現在是要使階梯往上移動,所以就是要設定y軸的移動量
}  

→將該檔案掛到物件(Normal&Nails階梯)上→點開Overrides→點Apply All
https://ithelp.ithome.com.tw/upload/images/20220919/20152411guFA0qbgeJ.jpg

https://ithelp.ithome.com.tw/upload/images/20220919/20152411TJKbjrgCHL.jpg
執行結果

但現在有個問題是...目前建立的階梯往上移動後就沒了,所以接著要來寫出如何不斷生成物件的程式碼~

如何自動生成物件

  • 首先創建一個空物件(命名為FloorManager)來管理、生成這些階梯→把Normal&Nails階梯這些物件都拉進來這個FloorManager裡。

    這些物件就是FloorManager物件的子物件,它們之間有父子關係。
    接著就可以幫這個FloorManager新增生成階梯的功能...

  • 首先創建一個C#檔案(命名為FloorManager)→而這個檔案不需要用到預設的Start及Update方法故可以將它們刪除→創建生成階梯的方法(因這個方法會在其他地方用到,故要將之設定成public)→創建陣列FloorPrefabs(該陣列是存放我們現在的階梯有哪些)→存檔。

[SerializeField]  GameObject[] FloorPrefabs; 

public void SpawnFloor()
{ 
} 

→將該檔案掛到物件(FloorManager)上→可以看到右欄顯示出FloorPrefabs→將它點開並新增Normal、Nails的Prefabs(只要將Normal、Nails的Prefabs拉過來)。
https://ithelp.ithome.com.tw/upload/images/20220919/20152411fHniv6x002.jpg


之後就可以來寫這個方法的內容了囉!

  • 由於我們是希望能從Normal及Nalis這兩種階梯,隨機挑選一種生成,也就是從陣列裡面隨機挑選一個值,故可以用Random.Range函式來達到隨機的效果,再將之放進一個變數裡面。
int r = Random.Range(0,FloorPrefabs.Length);
//隨機從0到這個陣列長度之間挑選一個數字存進r
  • 接著就可以創建階梯了,用Instantiate函式來幫我們創建物件,
Instantiate(FloorPrefabs[r],transform); 
  • 第一個參數是放想創建的東西(floorPrefabs陣列裡面的第r個值),因為我們希望創建出來的階梯能直接在FloorManager的底下(就是它的子物件),所以可以在後面加上transform這個參數。

  • 何時要讓階梯生成?
    由於階梯會一直往上跑,即使跑出我們的遊戲視窗仍不斷往上跑,故我們只要讓階梯跑出遊戲視窗的上方就將之刪掉,同時下面視窗再生成階梯

  • 如何判斷階梯跑出視窗?
    看圖可以發現中心點距離上方視窗有五格的距離,所以就可以設定如果階梯超過y座標為6時就要被刪除,而刪除物件可以用Destroy這個方法。
    https://ithelp.ithome.com.tw/upload/images/20220920/20152411ugfUznnB0Y.jpg

    在Floor.cs這邊要做一個判斷及刪除階梯。

if(transform.position.y > 6f)
        {
             Destroy(gameObject);
        }
  • 如何生成階梯?
    呼叫FloorManager裡的生成階梯方法,可以寫成
transform.parent.GetComponent<FloorManager>().SpawnFloor();

transform.parent代表FloorManager這個物件,因為這些階梯這些階梯,都是 FloorManager的子物件,反之,這些階梯的父物件就是FloorManager。為取得這個物件底下的FloorManager(Script)才能去呼叫它裡面的方法所以要寫.GetComponent().SpawnFloor();代表取得父物件(FloorManager)的Component(名稱為FloorManager)的SpawnFloor方法
是不是聽起來很饒口呢!/images/emoticon/emoticon06.gif

  • 接著要設定階梯生成的位置於是要用到...
floor.transform.position = new Vector3(Random.Range(-3.8f,3.8f),-6f,0f);

成果~~

附上FloorManager&Floor的程式碼~~

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FloorManager : MonoBehaviour
{
   [SerializeField] GameObject[] FloorPrefabs; 

    public void SpawnFloor()
    { 
        int r = Random.Range(0,FloorPrefabs.Length);
       GameObject floor = Instantiate(FloorPrefabs[r],transform); 
       floor.transform.position = new Vector3(Random.Range(-3.8f,3.8f),-6f,0f);
    } 
    
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Floor : MonoBehaviour
{
    [SerializeField] float moveSpeed = 2f; 
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(0,moveSpeed*Time.deltaTime,0); 
        if(transform.position.y > 6f)
        {
             Destroy(gameObject); 
             transform.parent.GetComponent<FloorManager>().SpawnFloor();
        }
}
}

心得

今天學到的內容比前幾天稍微複雜,需要用到較多function,但所幸大部分都是Unity內建就有的~

  • 參考網址:https://www.youtube.com/watch?v=nPW6tKeapsM&ab_channel=GrandmaCan-%E6%88%91%E9%98%BF%E5%AC%A4%E9%83%BD%E6%9C%83
  • 音效、圖片 : 遊戲素材
    (素材由安德斯提供,感謝大大/images/emoticon/emoticon41.gif)

上一篇
【Day7】老菜雞學下樓梯遊戲之Unity樣板(Prefab)介紹&應用
下一篇
【Day9】老菜雞學下樓梯遊戲之Unity GetComponent&Enable Component
系列文
老菜雞挑戰30天學爆Unity&C#會成功嗎?...30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言