关于Unity中的碰撞检测和管理(2D)

创建Unity3D项目和Unity2D项目的区别。

1.3D项目有摄像机和太阳光,2D项目只有摄像机

2.3D项目使用的贴图类型是Texture纹理,2D项目使用的贴图类型是Sprite 2D/UI

这里我们创建一次2D工程来实现飞机大战的碰撞检测

一、2D中的碰撞检测

1.创建一个Canvas

2.把Canvas节点的Canvas组件中的Render Mode设置为Screen Space-Camera,并把Main Camera节点拖进Render Camera属性

3.把Canvas节点的Canvas Scaler组件的UI Scale Mode设置为Scale With Screen Size,并把Refernces Resultion设置为和Game视图分辨率一样的640X960

4.把地图贴纸设置为Texture类型,虽然是在2D项目当中,但是如果要做地图滚动的话,地图的类型必须是Texture

5,.创建一个Raw Image类型的UI节点放在父节点Canvas下面,把地图拖进去,节点大小设置为512X1024

6.设置地图节点的Scale的x为1.25,y也为1.25,覆盖整个Canvas画布

7.写一个脚本挂在sky背景节点下面控制地图滚动

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class sky : MonoBehaviour {
RawImage img;
public float speed = 0.1f;
// Use this for initialization
void Start () {
this.img = this.GetComponent<RawImage>();
} // Update is called once per frame
void Update () {
Rect r = this.img.uvRect;
r.y += this.speed * Time.deltaTime;
this.img.uvRect = r;
}
}

8.创建一个Image类型的名为player的飞机节点在父节点Canvas节点下面,把主角飞机贴图拖过去,set native size,调整一下节点的大小,128X128

9.给player增加一个Box Collider 2D形状组件,也叫矩形碰撞器,碰撞器size大小128X128

10.可以给player加一个刚体组件Rigidbody 2D,其实没必要加刚体,如果加了就设置重力Gravity Scale为0

11创建一个Image类型的名为enemy的敌机节点在父节点Canvas节点下面,把敌机贴图拖过去,set native size,调整一下节点的大小,128X128

12.给enemy增加一个Box Collider 2D形状组件,也叫矩形碰撞器,碰撞器size大小128X128

13.可以给enemy加一个刚体组件Rigidbody 2D,其实没必要加刚体,如果加了就设置重力Gravity Scale为0

14.写一个脚本挂在enemy敌机节点下面控制敌机运动

using UnityEngine;
using System.Collections; public class enemy : MonoBehaviour {
public Vector2 speed = new Vector2(, -);
Rigidbody2D body = null;
// Use this for initialization
void Start () {
this.body = this.GetComponent<Rigidbody2D>();
this.body.velocity = speed;
} // Update is called once per frame
void Update () { }
}

15.打开物理引擎设置

edit --> ProjectSetting -->Physices 2D;

打开后可以对重力进行设置,形状碰撞组件默认材质进行设置,还可以设置永远打开形状碰撞组件的边界框以及设置边界框的颜色

碰撞检测和刚体组件和碰撞形状组件都有关系,有时候没有用到刚体组件Rigidbody 2D,但是一定会用到碰撞形状组件Box Collider 2D

16.碰撞状态分为3种

a.开始

b.持续

c.结束

当两个物体发生碰撞,碰撞器会去遍历碰撞器所挂节点上的所有脚本,然后调用脚本写的函数。所以我们必须在要发生碰撞的物体节点下面的脚本里面写这三个碰撞函数

(1)OnCollisionEnter2D(Collision2D c)方法; -->开始碰撞

(2)OnCollisionExit2D(Collision2D c)方法; -->结束碰撞

(3)OnCollisionStay2D(Collision2D c)方法; -->碰撞持续;(一个物体粘着一个物体不分开的时候,大多数是两个物体碰撞在一起不分开一起运动的状态),里面的内容貌似只执行一次。

设置碰撞节点的Tag

在节点的Inspector视图的左上角的Tag属性选择,可以自定义Tag,有了Tag就可以知道自己碰到的是哪个节点

下面的代码写在player节点下面挂载的脚本里面

// 碰撞开始
// Collision2D 碰撞信息
void OnCollisionEnter2D(Collision2D c) {
// 获取了与我们碰撞的节点;
//
if (c.gameObject.tag == "enemy") {
Debug.Log("OnCollisionEnter2D Contact with enmy!!!");
} }
// 碰撞结束
void OnCollisionExit2D(Collision2D c) {
// Debug.Log("OnCollisionExit2D called");
} // 碰撞持续
void OnCollisionStay2D(Collision2D c) {
// Debug.Log("OnCollisionStay2D called");
}
// end

17.碰撞有两种类型,上面是碰撞器与碰撞器碰撞,还有一种碰撞是碰撞器与触发器碰撞

触发器就是把节点下面的Box Collider 2D碰撞形状组件的Is Trigger属性打钩,打钩之后,就不会产生碰撞效果,没有任何的物理运算。但是两个物体如果发生交互的时候还是会触发事件,触发函数,玩家捡金币就是用到这种碰撞,触发的函数有下面三个

(1)OnTriggerEnter2D(Collider2D c) -->开始

(2)OnTriggerExit2D(Collider2D c) -->结束

(3)OnTriggerStay2D(Collider2D c) -->持续碰撞

设置碰撞节点的Tag

在节点的Inspector视图的左上角的Tag属性选择,可以自定义Tag,有了Tag就可以知道自己碰到的是哪个节点

下面的代码写在player节点下面挂载的脚本里面

 void OnTriggerEnter2D(Collider2D c)
{
if (c.gameObject.tag == "enemy") {
Debug.Log("OnTriggerEnter2D called");
}
} void OnTriggerExit2D(Collider2D c)
{
if (c.gameObject.tag == "enemy")
{
Debug.Log("OnTriggerEnter2D called");
}
} void OnTriggerStay2D(Collider2D c)
{
if (c.gameObject.tag == "enemy")
{
Debug.Log("OnTriggerEnter2D called");
}
}

18.最后,我们还需要一个碰撞矩阵列表,来表示哪些物体之间需要碰撞,哪些物体不用发生碰撞,比如玩家和玩家不用发生碰撞,玩家和敌机会发生碰撞......这个表一般是在开始的时候就确定的。

而这个矩阵的设置步骤

a.给每个节点设置所在的层(Inspector视图右上角的layer,可以自定义,更Tag一样的)

b.打开物理引擎设置edit --> ProjectSetting -->Physices 2D;下面那个三角形的矩阵就是碰撞矩阵,可以打钩和去钩,

不打钩就是不产生碰撞的两个物体之间不会产生碰撞消息,不管是碰撞器与碰撞器碰撞,还是碰撞器与触发器碰撞都不会去执行碰撞函数。

上一篇:使用BigDecimal进行精确运算以及格式化输出数字


下一篇:FAST LOW-RANK APPROXIMATION FOR COVARIANCE MATRICES