0%

Untiy相关C#常用API

Unity常用API

Unity初级常用API

 

碰撞检测

对于一个触发器,碰撞事件的三个状态:

  • OnTriggerEnter2D: 开始碰撞
  • OnTriggerStay2D: 碰撞中
  • OnTriggerExit2D: 碰撞分开
void OnTriggerEnter2D(Collider2D collider)
    {
        Debug.Log("撞到啦...");
        Debug.Log(collider.gameObject.tag);
    }
// 碰撞检测函数,进入的时候执行

void OnTriggerStay2D(Collider2D collider)
{
Debug.Log("一直停留在碰撞状态…");
}
// 停留的时候执行

void OnTriggerExit2D(Collider2D collider)
{
Debug.Log("退出碰撞状态…");
}
// 退出的时候执行

使用条件:检测的对象必须拥有col相关组件碰撞脚本,而且这个适用于触发器

如果检测器不是触发器,即需要有具体的物理系统,则使用如下对应函数:

	private void OnCollisionEnter(Collision collision)
    {
        print(collision.gameObject.name);
    }
     private void OnCollisionExit(Collision collision)
    {
        print(collision.gameObject.name);
    }

 

非物理碰撞检测(Bounds 外包围盒)

有时候由于脚本冲突,比如对象不是按照官方的物理逻辑在编写碰撞的,则直接检测是否经过而不是判断物理碰撞来检测碰撞

使用BoundsAPI

bounds.center
bounds.size
bounds.min
bounds.max
bounds.center.x
bounds.center.y

其中center和size只读

常用方法:

public bool Contain(Vector3 point);//判断点是否在内部
public void Encapsulate(Vector3 point);//自动扩充大小来包括这个点
public void Encapsulate(Bounds bounds);//自动扩充大小来把这个bounds包括
public bool IntersectRay(Ray ray);//判断这个射线是否与包围盒相交
public Vector3 ClosestPoint(Vector3 point);//包括盒最近的点
public void SetMinMax(Vector3 min,Vecor3 max);//设置边界框的最小最大值

与Collider的区别:Bounds不会跟着模型旋转,只会跟着变大变小,作为五向的,精度更小

包围盒的类型

  • AABB包围盒(Axis-aligned bounding box)
  • 包围球(Sphere)
  • OBB包围盒(Oriented bounding box)
  • 凸包包围盒(Convex Hull)

AABB:构造简单存储空间小紧密性差,对于不规则体荣誉空间大,两个点描述(立方体对角线)

从算法角度上看,其实就是计算两点在坐标轴上的投影,然后对比两个对象的投影在坐标轴上的描述,如果xyz轴(如果是2D则xy轴)都有交叉段,则判断相撞

与OBB差别:不可旋转

 

判断某点是否在Bounds内

 Vector3 pos = someRenderer.transform.position;
 Bounds bounds = myBoxCollider.bounds;
 bool rendererIsInsideTheBox = bounds.Contains(pos);

带碰撞的

 Bounds rendererBounds = someRenderer.bounds;
 Bounds colliderBounds = myBoxCollider.bounds;
 bool rendererIsInsideBox = colliderBounds.Intersects(rendererBounds);

get与set属性访问器(其实是刚好了解到这个东西才写进来的)

 

一般情况下在C#中编写脚本声明变量时:

private float num;
public int index;

其实隐藏了get与set:

public float Num
{
    get { return Num; }
    set { Num= value; }
}

getset内的定义其实就是上述,get返回Num的值,调用Num时返回Num本身,也就拿到了Num值,set让Num附上value值,所以说这两个相当于“读”和“写”,其具体作用其实也是在声明读和写

一般声明变量,unity默认为读写,也就是默认这两个访问器都能用,但如果自行编写这两个访问器的其中之一,那么就相当于编写成“只读”或“只写”

private float num//只读属性,只能读取该属性的值
{
    get { return num; }
}
private float num//只写属性,只能给该属性设置值
{
    set { num = value; }
}
private float num//可读可写的属性
{
    get { return num; }
    set { num = value; }
}

在C++中,我们为变量赋值时,可能会遇到变量有一定范围的需求,于是我们一般创建一个新变量来做判断以限定范围:

int a;//假如a范围为0~10
int b;
cin<<b<<endl;
if(b>=0&&b<=10)
{
  a=b;    
}

这样的目的是保持变量安全性,a永远不可能被外界设置成0到10以外的值

这个方式和C#中使用get与set保护变量有异曲同工之妙:

private float num;
 

public float Num
{
get { return num; }
set //value小于等于10
{
if (value>10)
{
value = 10;
}

    num = value;
}

}

建立新值num来为Num赋值,看似多此一举,其实就是防止Num溢出

不过最标准的命名变量的方式可能是如此:

private float num{get;set;};

用来强调可读可写