9.unity物件侦测(碰撞Collider2D)

碰撞器2D (参阅Collider 2D)

碰撞器可以让物体碰撞停下、设定障碍物;也可以达成捡金币、攻击...这类物件侦测事件。

如何侦测两个物件接触?

碰撞器在物件身上建立一个碰装侦测范围,可以去碰撞其他带有碰撞器的物件。
并且规定主动方(移动的物件)必须带有Rigidbody,碰撞时才有因应的物理系统。
※且不可两边的rigidbody都使用Kinematic运动学(忽略物理)

添加碰撞元件
Add Component元件 → 形状 Collider 2D
1.png
方盒碰撞器;椭圆碰撞器;圆形碰撞器;复合碰撞器;边界碰撞器;多边形碰撞器;瓦片地图碰撞器
依照物件选择适合的碰撞器即可。

以BoxCollider2D为例
2.png

Edit Collider 碰撞范围编辑,可以手动调整碰撞范围
3.png

Material 材质,可以下载不同模式的碰撞效果(例如弹跳皮球或冰块材质的运动),也可以是空值。

Is Trigger 触发器,打开的话不会与其他物体碰撞,取消物理系统,会被穿越,碰到可以触发事件。


侦测事件

Enter函式是两个物件碰撞瞬间,执行一次函式

Exit函式是两个物件分开瞬间,执行一次函式

Stay函式是两个物件保持接触,不断执行函式

基本写法:

void OnCollisionEnter2D(Collision2D coll) //传入碰撞对象,coll(自己取)
{
   //碰撞成立之後想干嘛就写在这里
}

碰撞事件 OnCollision

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(值,值,...) 回传最小值。
        }
    }
 }

触发事件 OnTrigger

用法基本上跟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);
        }
    }
}

OnTriggerEnter2D官方脚本

脚本一,挂载在物件一
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);
    }
}

<<:  Day3 逻辑斯回归(Logistic Regression)

>>:  数据中台:实施阶段

[Day16] 均线策略投资组合绩效回测

投资一个常见的观念就是要分散风险,今天就来计算如果用00646和006208做两支均线策略,各放一半...

Docker Debug 挑战题 - 网页跑板了!? 小容器 我要进来罗

这边为一道设计过的 Docker Debug 挑战题目,初始环境有所设置错误,请大家帮忙找出 Do...

Day 26 介绍 vite

vite 是 Vue.js 的作者所做的一个新的 bundler ,如果你有用过应该会知道,它最特别...

Day 29 : 堆积排序 Heap Sort

今天要来实作最後一个方法,也就是Heap Sort来解Sort an Array。 如果对Heap不...

14.MYSQL搜寻字串

在资料库中除了有数字和字母之外,当然也会有字串,如果想要搜寻字串,就要使用'单引号' 而字串要使用运...