Try   HackMD

總而言之大概整理一下Unity常用的一些或許需要的知識之類的

有關Unity的一些很基本的東西(目前大部分coding為主),因為作者很菜所以可能會有錯誤,如果有發現歡迎修正

Monobehavior底下的那些

Properties

  • gameObject
    被當前script掛載的GameObject
    ​​​​void Start()
    ​​​​{
    ​​​​    Destroy(gameObject);
    ​​​​}
    

Methods

  • void Start()
    在一開始會被執行的部分放這,用來初始化

    ​​​​void Start()
    ​​​​{
    ​​​​    rb2d = gameObject.GetComponent<Rigidbody2D>();
    ​​​​}
    
  • void Updata()
    這東西每一禎會呼叫一次,用它來處理需要一直做的事

    ​​​​void Update()
    ​​​​{
    ​​​​    transform.position += Vector3.Left * speed;
    ​​​​}
    
  • void FixedUpdate()
    每隔一段固定時間就會呼叫一次,官方推薦用來處理物理相關的部分
    而這個間隔定義在Edit->ProjectSetting->time裡的Fixedtimestep

    ​​​​void FixedUpdate()
    ​​​​{
    ​​​​    rb2d.AddForce(Vector3.left);
    ​​​​}
    
  • void LateUpdate()
    在所有Update之後被執行的函式,這裡的所有不限於當前腳本本身,包含其他遊戲中的物件

    ​​​​void LateUpdate()
    ​​​​{
    ​​​​    Vector3 newPosition = transform.position;
    ​​​​    newPosition.z = -10;
    ​​​​    Camera.main.transform.position = newPosition;
    ​​​​}
    

另外,在同一個腳本底下三種Update是可以並存的

GameObject

properties

  • tag
    在Inspector底下可以設置的那個tag,是個string

  • transform
    掛在物件底下的Transform,根據官方文件,因為它並非單純的呼叫一個變數,最好避免在程式中大量呼叫,以免造成較大的負擔。

    Little known fact: all of the component accessors in MonoBehaviour, things like transform, renderer, and audio, are equivalent to their GetComponent(Transform) counterparts, and they are actually a bit slow.

    所以當你在程式中需要時常存取此類物件時,較好的方式是建立一個快照(cache)

    • 較慢的寫法
      ​​​​​​​​void Update()
      ​​​​​​​​{
      ​​​​​​​​    float step = speed * Time.deltaTime;
      ​​​​​​​​    Transform target = GameObject.FindWithTag("Player").transform;
      ​​​​​​​​    transform.position = Vector3.MoveTowards(transform.position, target, step);
      ​​​​​​​​}
      
      
    • 較有效率的寫法
      ​​​​​​​​private Transform mTransform;
      ​​​​​​​​private Transform target;
      ​​​​​​​​
      ​​​​​​​​void Start()
      ​​​​​​​​{
      ​​​​​​​​    mTransform = transform;
      ​​​​​​​​    target = GameObject.FindWithTag("Player").transform;
      ​​​​​​​​}
      ​​​​​​​​
      ​​​​​​​​void Update()
      ​​​​​​​​{
      ​​​​​​​​    float step = speed * Time.deltaTime;
      ​​​​​​​​    mTransform.position = Vector3.MoveTowards(mTransform.position, target, step);
      ​​​​​​​​}
      

Methods

  • GetComponent
    非常常見的一個函式,用來取得掛在GameObject底下的Component
    有三種型式:

    ​​​​Transform self = gameObject.GetComponent<Transform>();
    ​​​​Rigidbody2D rb2d = gameObject.GetComponent(typeof(Rigidbody2D)) as Rigidbody2D;
    ​​​​Animator anim = gameObject.GetComponent("Animator") as Animator;
    

    三種結果都是一樣的,然而因為第一種寫起來比較短,所以我比較喜歡

  • Destroy
    摧毀一個"東西",在這裡可能是一個GameObject、Component或是其他繼承自UnityEngine.Object的Class,並且可以設定延遲,預設為零

    ​​​​void Start()
    ​​​​{
    ​​​​    //destroy the game object after 10.086 seconds.
    ​​​​    Destroy(gameObject, 10.086f);
    ​​​​}
    ​​​​
    ​​​​void Update()
    ​​​​{
    ​​​​    if(Input.GetKeyDown(KeyCode.D))
    ​​​​    {
    ​​​​        //destroy the game object Immediately.
    ​​​​        Destroy(gameObject);
    ​​​​    }
    ​​​​}
    ​​​​
    
  • Instantiate
    創建一個東西,可以產生的東西跟Destroy可以接受的型態一樣,並且可以在產生時指定位置及旋轉量,並且回傳此實例

    ​​​​public Rigidbody2D circle;
    ​​​​
    ​​​​void Update()
    ​​​​{
    ​​​​    if(Input.GetMouseButtonDown(0))
    ​​​​    {
    ​​​​        Vector3 spawnPosition = Camara.main.ScreenToWorldPoint(Input.mousepPsition);
    ​​​​        Rigidbody2D clone = Instantiate(circle, spawnPosition, Quaternion.identity);
    ​​​​    }
    ​​​​}
    

Vector3

Vectoe3在Unity裡面算是一個蠻常用到的型別,裡面存著x y z三個數,型別為float,通常拿來表示一個座標或向量

  • 建構子(constructor)

    ​​​​//initialize a vector3 with (x, y, z) = (10, 10, 10)
    ​​​​Vector3 v1 = new Vector3(10, 10, 10);
    ​​​​//default z is 0
    ​​​​Vector3 v2 = new Vector3(10, 10);
    
  • operator +
    將兩個Vector3相加,相應的值會相加,就如同向量的加法一樣

    ​​​​Vector3 result = new Vector(1, 2, 3) + new Vector3(4, 5, 6);
    ​​​​//the result should be (5, 7, 9)
    
  • operator *
    一個向量乘上一個數字

    ​​​​Vector3 result = new Vector3(1, 1, 1) * 55688;
    ​​​​//result => (55688, 55688, 55688)
    
  • static properties
    一些預先定義好的向量,以下列舉幾個,詳細的請查官方文件

    • Vector3.zero => Vector3(0, 0, 0)
    • Vector3.one => Vector3(1, 1, 1)
    • Vector3.left => Vector3(1, 0, 0)
    • Vector3.up => Vector3(0, 0, 1)

Transform

Transform是Unity裡面最常見的一個component(大概),儲存了物件的座標(position)、旋轉量(rotation)、縮放量(scale)等等

Properties

  • position
    一個Vector3,紀錄了當前物件的座標,不能直接改動回傳的Vector3裡的內容(見範例)

    ​​​​//correct!
    ​​​​transform.position += (Vector3.left * speed);
    ​​​​//bubu~desuwa! you can't only modify the x!
    ​​​​transform.position.x += speed;
    
  • rotation
    一個Quaternion,因為旋轉較複雜,先跳過,待日後補上。

Methods

  • void Rotate(Vector3 eulers)
    按照z x y的順序旋轉物件,大部分時候沒什麼問題。
    ​​​​transfrom.Rotate(Vector3.left * Time.deltaTime);
    

Rigidbody2D

剛體是Unity裡面做物理運算時不可或缺的component,裡面包含了物理運算所需的各種資訊

Properties

  • bodyType
    影響剛體物理性質的一個值,通常在inspector裡面修改,官方建議不要在遊戲執行期間去修改他,會造成較大的效能開銷
    bodyType共有三種:

    • RigidbodyType2D.Dynamic
      預設值,總之就是很正常,沒啥特別的
    • RigidbodyType2D.Kinematic
      中文翻譯貌似叫"動力學"之類的,其不受各種力的影響,所以像是放在半空中或是使用AddForce之類的都不會影響它,但可以透過設置velocity來使它移動
      另外,它的效能開銷比Dynamic要來的低
    • RigidbodyType2D.Static
      總之就是不會動,撞它也不會,給它速度也不行
      當然,效能開銷最低的一種
  • velocity
    如同字面上的意思,就是速度,在Rigidbody2D下是個Vector2,而在Rigidbody下是Vecotr3

    ​​​​Rigidbody2D rb2d = gameObject.GetComponent<Rigidbody2D>();
    ​​​​rb2d.velocity = Vector2.left * 10;
    

Methods

  • void AddForce(Vector2 force)
    總之就是施一個力,跟force一樣的力,可以拿來作人物移動之類的
    ​​​​//jump!
    ​​​​rb2d.AddForce(Vector2.up * power);
    

Collider2D

除了剛體,還需要碰撞器才能產生碰撞,另外碰撞又分成兩種:

  • 碰撞(Collision)
    總之就是碰撞,沒什麼特別的,撞到之後該發生什麼就會發生什麼,不清楚的可以自己撞看看
  • 觸發(Trigger)
    觸發比較特別,當相撞兩方至少其中一邊的collider底下的Is Trigger有被勾選便會發生,它會使得當前碰撞造成的物理影響失效,可以用來製造地形啥的
    舉例來講,像是踏進冰鳥的R會扣血,但還是可以走過去,並不會被擋住

Functions

Collider相關的函式可以分成三類:Enter、Stay、Exit,他們被呼叫的時機就如同字面上的意思,看以下範例:

void OnCollisionEnter2D(Collision2D other)
{
    if(other.collider.tag == "Enemy")
    {
        this.Damaged();
    }
}

這就是一個簡單的碰撞判定,判斷撞到的是不是敵人,是的話就扣血
如果是Trigger的話,要把上面的Collision換成Trigger,另外還有參數,Trigger的參數型別是Collider2D,跟碰撞並不一樣

Animator

Animator是Unity裡面控制動畫的一個Component,內容表示為一個狀態機,並且可以攜帶參數,目前Unity支援的參數型別有int、float、bool跟trigger
trigger本身的作用就像是一個按鈕,按下去之後會彈回來,用來取代某些時候bool設定為true後需要馬上改成false的場合,詳見範例

State

Transition

Methods

  • 參數相關
    控制Animator大部分時候就是透過調整它的參數,可以透過Animator底下的函式完成,get系列只接受一個參數,Animator參數的名字,或是它的id,需要注意的是沒有GetTrigger,set的話除了名字,後面還要傳入要修改的值,當然Trigger是例外,它只需要一個參數,它的名字
    ​​​​Animator anim;
    ​​​​
    ​​​​void Start()
    ​​​​{
    ​​​​    anim = gameObject.GetComponent<Animator>();
    ​​​​}
    ​​​​
    ​​​​void Update()
    ​​​​{
    ​​​​    if(Input.GetKey(KeyCode.Space))
    ​​​​    {
    ​​​​        anim.SetTrigger("Jump");
    ​​​​    }
    ​​​​}
    

參考連結

Unity scripting reference
Unity碰撞器(Collider)与触发器(Trigger)
Unity性能优化——Rigidbody2D详解