碰撞器可以讓物體碰撞停下、設定障礙物;也可以達成撿金幣、攻擊...這類物件偵測事件。
如何偵測兩個物件接觸?
碰撞器在物件身上建立一個碰裝偵測範圍,可以去碰撞其他帶有碰撞器的物件。
並且規定主動方(移動的物件)必須帶有Rigidbody,碰撞時才有因應的物理系統。
※且不可兩邊的rigidbody都使用Kinematic運動學(忽略物理)
添加碰撞元件
Add Component元件 → 形狀 Collider 2D
方盒碰撞器;橢圓碰撞器;圓形碰撞器;複合碰撞器;邊界碰撞器;多邊形碰撞器;瓦片地圖碰撞器
依照物件選擇適合的碰撞器即可。
以BoxCollider2D為例
Edit Collider 碰撞範圍編輯,可以手動調整碰撞範圍
Material 材質,可以下載不同模式的碰撞效果(例如彈跳皮球或冰塊材質的運動),也可以是空值。
Is Trigger 觸發器,打開的話不會與其他物體碰撞,取消物理系統,會被穿越,碰到可以觸發事件。
Enter函式是兩個物件碰撞瞬間,執行一次函式
Exit函式是兩個物件分開瞬間,執行一次函式
Stay函式是兩個物件保持接觸,不斷執行函式
基本寫法:
void OnCollisionEnter2D(Collision2D coll) //傳入碰撞對象,coll(自己取)
{
//碰撞成立之後想幹嘛就寫在這裡
}
OnCollisionEnter2D
OnCollisionExit2D
OnCollisionStay2D
官方腳本:
using UnityEngine;
public class Example : MonoBehaviour
{
//Enter函式是兩個物件碰撞瞬間,執行一次函式
void OnCollisionEnter2D(Collision2D coll) //傳入碰撞對象 取名coll
{
if (coll.gameObject.tag == "Enemy") //這個對象的tag如果是敵人
{
coll.gameObject.SendMessage("ApplyDamage", 10);
//傳參數10給這個物件,gameObject.SendMessage()之後會花一天了解他~
}
//Exit函式是兩個物件分開瞬間,執行一次函式
int bumpCount;
void OnCollisionExit2D(Collision2D coll)
{
if (coll.gameObject.tag == "DodgemCar")
{
bumpCount++;
}
}
//Stay函式是兩個物件保持接觸,不斷執行函式
float rechargeRate = 10.0f;
float batteryLevel;
void OnCollisionStay2D(Collision2D coll)
{
if (coll.gameObject.tag == "RechargePoint")
{
batteryLevel = Mathf.Min(batteryLevel + rechargeRate * Time.deltaTime, 100.0f);
//Mathf.Min(值,值,...) 回傳最小值。
}
}
}
用法基本上跟OnCollision一樣,差在會不會穿越。
OnTriggerEnter2D
OnCollisionExit2D
OnCollisionStay2D
實例:跟OnCollision一樣,OnTriggerEnter2D不太一樣,寫隱形碰撞器(在下面)
using UnityEngine;
public class Example : MonoBehaviour
{
//Exit函式是兩個物件分開瞬間,執行一次函式
int bumpCount;
void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.tag == "DodgemCar")
{
bumpCount++;
}
}
//Stay函式是兩個物件保持接觸,不斷執行函式
float rechargeRate = 10.0f;
float batteryLevel;
void OnCollisionStay2D(Collision2D collision)
{
if (collision.gameObject.tag == "RechargePoint")
{
batteryLevel = Mathf.Min(batteryLevel + rechargeRate * Time.deltaTime, 100.0f);
}
}
}
腳本一,掛載在物件一
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Create GameObject1 that falls under gravity. It will pass through
// Example2 and cause a collision. GameObject1 is moved back to
// the start position and it will again start to fall under gravity.
//創建一個會自由落體的物件1,穿過物件2時會造成事件,然後物件1回到原點再一次自由落體
public class Example1 : MonoBehaviour
{
void Awake()
{
SpriteRenderer sr; //建立sprite渲染(遊戲對象)
sr = gameObject.AddComponent<SpriteRenderer>() as SpriteRenderer;
sr.color = new Color(0.9f, 0.9f, 0.1f, 1.0f);//設定顏色RGBA
BoxCollider2D bc; //建立碰撞器
bc = gameObject.AddComponent<BoxCollider2D>() as BoxCollider2D;
bc.size = new Vector2(1.0f, 1.0f);//碰撞器範圍
Rigidbody2D rb; //建立剛體
rb = gameObject.AddComponent<Rigidbody2D>() as Rigidbody2D;
rb.gravityScale = 1.0f; //設重力大小
// A square in the Resources folder is used.
//使用Resources資料夾內的square圖片
gameObject.GetComponent<SpriteRenderer>().sprite = Resources.Load<Sprite>("square");
// GameObject1 starts 3 units in the Up direction.
//物件1起始於Y軸上第三格
gameObject.transform.position = new Vector3(0.0f, 3.0f, 0.0f);
gameObject.transform.localScale = new Vector3(0.5f, 0.5f, 1.0f);
}
private float timer = 0.0f; //計時器預設為0
private bool restart = false; //重新啟動布林值預設為否
void FixedUpdate()//固定時間更新的Update。
{
if (restart == true) //如果重新啟動布林值為是
{
timer = timer + Time.deltaTime; //開始計時
if (timer > 0.25f) //當計時到0.25f
{
//物件回到起始點、速度為0、重新啟動布林值改為否
gameObject.transform.position = new Vector3(0.0f, 3.0f, 0.0f);
gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0.0f, 0.0f);
restart = false;
}
}
}
// called when this GameObject collides with GameObject2.
//當物件1碰到物件2時會呼叫此函式
void OnTriggerEnter2D(Collider2D col)
{
Debug.Log("GameObject1 collided with " + col.name);//顯示物件1撞到物件的"名稱"
restart = true; //重新啟動布林值改為是
timer = 0.0f; //timer歸零
}
}
腳本二,掛載在物件二
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Create a rectangle that the other GameObject will collide with.
// Note that this GameObject has no visibility.
// (View in the Scene view to see this GameObject.)
//創建一個方型物件讓其他物件進行碰撞偵測,且這個物件無法被看到。(沒有渲染圖案sprite)
public class Example2 : MonoBehaviour
{
void Awake()
{
BoxCollider2D bc;//建立碰撞器
bc = gameObject.AddComponent<BoxCollider2D>() as BoxCollider2D;
bc.size = new Vector2(3.0f, 1.0f);//碰撞器範圍
bc.isTrigger = true; //設置為偵測器
//偵測器定位於Y軸上-2格
gameObject.transform.localScale = new Vector3(3.0f, 1.0f, 1.0f);
gameObject.transform.position = new Vector3(0.0f, -2.0f, 0.0f);
}
void OnTriggerEnter2D(Collider2D col)
{
Debug.Log("GameObject2 collided with " + col.name);
}
}