Unity3D之主角面朝方向一定区域内对象角度计算.docx

上传人:b****5 文档编号:3360040 上传时间:2022-11-22 格式:DOCX 页数:8 大小:16.95KB
下载 相关 举报
Unity3D之主角面朝方向一定区域内对象角度计算.docx_第1页
第1页 / 共8页
Unity3D之主角面朝方向一定区域内对象角度计算.docx_第2页
第2页 / 共8页
Unity3D之主角面朝方向一定区域内对象角度计算.docx_第3页
第3页 / 共8页
Unity3D之主角面朝方向一定区域内对象角度计算.docx_第4页
第4页 / 共8页
Unity3D之主角面朝方向一定区域内对象角度计算.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

Unity3D之主角面朝方向一定区域内对象角度计算.docx

《Unity3D之主角面朝方向一定区域内对象角度计算.docx》由会员分享,可在线阅读,更多相关《Unity3D之主角面朝方向一定区域内对象角度计算.docx(8页珍藏版)》请在冰豆网上搜索。

Unity3D之主角面朝方向一定区域内对象角度计算.docx

Unity3D之主角面朝方向一定区域内对象角度计算

Unity3D之主角面朝方向一定区域内对象角度计算

 如何获取主角面朝方向一定区域中的敌人对象。

这个命题看似简单,其实里面蕴含了很多数学方面的东西。

今天刚好有时间我就彻底的把这个疑问来解答下。

希望可以帮助到大家。

在上代码之前请大家跟我先做几个简单的练习题,角度向量的计算一定要学会,不然后面的东西会很难懂。

1.已知3D坐标,和一个旋转角度,以及一段距离,求目标点的3D坐标。

已知当前点为Target,目标点沿着Target的Y轴旋转30度,沿着Target的X轴延伸10米求目标点的3D坐标?

usingUnityEngine;

usingSystem.Collections;

publicclassTest:

MonoBehaviour

{

publicTransformTarget;

voidLateUpdate()

{

Quaternionrotation=Quaternion.Euler(0f,30f,0f)*Target.rotation;

Vector3newPos=rotation*newVector3(10f,0f,0f);

Debug.DrawLine(newPos,Vector3.zero,Color.red);

Debug.Log("newpos"+newPos+"nowpos"+Target.position+"distance"+Vector3.Distance(newPos,Target.position));

}

}

 

输出结果:

新坐标 (8.7,0.0,-5.0)当前坐标(0.0,0.0,0.0)两点之间的距离10。

 2.已知3D模型的角度求它的向量。

已知3D模型Target,Y轴旋转30度后向前平移。

usingUnityEngine;

usingSystem.Collections;

publicclassTest:

MonoBehaviour

{

publicTransformTarget;

voidLateUpdate()

{

if(Input.GetMouseButton(0))

{

Quaternionrotation=Quaternion.Euler(0f,30f,0f)*Target.rotation;

Vector3newPos=rotation*Vector3.forward;

Target.Translate(newPos.x,newPos.y,newPos.z);

}

}

}

3.已知一个目标点,让模型朝着这个目标点移动。

这是一个比较简单的例子,大家应该都能看明白

Target.transform.LookAt(newVector3(100f,200f,300f));

Target.Translate(Vector3.forward);

    

    这里我要说的就是Vector3.forward,它等价与newVector3(0,0,1);它并不是一个坐标,它是一个标准向量,方向是沿着Z轴向前。

这样平移一次的距离就是1米,如果Vector3.forward*100那么一次平移的距离就是100米。

 

在看看下面这段代码

Vector3vecn=(TargetCube.position-Target.position).normalized;

Target.Translate(vecn*0.1f);

    

    用向量减去一个向量求出它们的差值,normalized是格式化向量,意思是把它们之间向量格式化到1米内。

这样就可以更加精确的计算一次平移的距离了vecn*0.1f就标示一次平移1分米,蛤蛤。

 向量不仅可以进行XYZ轴的移动,同样可以进行旋转,下面这段代码就是让向量沿着Y轴旋转30度。

Vector3vecn=(TargetCube.position-Target.position).normalized;

vecn=Quaternion.Euler(0f,30f,0f)*vecn;

Target.Translate(vecn*0.1f);

     

    如果上述三道简单的练习题 你都能了然于心的话,那么本文最大的难题我相信也不会是什么难事,继续阅读吧。

文章出处狗刨学习网

    假设我们需要计算主角面前5米内所有的对象时。

以主角为圆心计算面前5米外的一个点,为了让大家看清楚我现将这条线绘制出来。

privatefloatdistance=5f;

voidUpdate() 

{

Quaternionr=transform.rotation;

Vector3f0=(transform.position+(r*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f0,Color.red);

}

    如下图所,我们已经将这两个点计算出来了。

此时你可以动态的编辑主角Y轴的坐标,这个点永远都是沿着主角当前角度面前5米以外的点。

 

接下来,我们需要计算主角面前的一个发散性的角度。

假设主角看到的是向左30度,向右30度在这个区域。

privatefloatdistance=5f;

voidUpdate() 

{

Quaternionr=transform.rotation;

Vector3f0=(transform.position+(r*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f0,Color.red);

Quaternionr0=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y-30f,transform.rotation.eulerAngles.z);

Quaternionr1=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y+30f,transform.rotation.eulerAngles.z);

Vector3f1=(transform.position+(r0*Vector3.forward)*distance);

Vector3f2=(transform.position+(r1*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f1,Color.red);

Debug.DrawLine(transform.position,f2,Color.red);

Debug.DrawLine(f0,f1,Color.red);

Debug.DrawLine(f0,f2,Color.red);

}

如下图所示,这时主角面前的区域就计算出来了。

看起来就是两个三角形之间的区域。

 

最后就是简单的套用公式,计算一个点是否在三角形内,在本文中就是计算敌人的点是否在面前的这两个三角形内。

文章出处狗刨学习网

usingUnityEngine;

usingSystem.Collections;

publicclassMyTest:

MonoBehaviour{

publicTransformcube;

privatefloatdistance=5f;

voidUpdate() 

{

Quaternionr=transform.rotation;

Vector3f0=(transform.position+(r*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f0,Color.red);

Quaternionr0=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y-30f,transform.rotation.eulerAngles.z);

Quaternionr1=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y+30f,transform.rotation.eulerAngles.z);

Vector3f1=(transform.position+(r0*Vector3.forward)*distance);

Vector3f2=(transform.position+(r1*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f1,Color.red);

Debug.DrawLine(transform.position,f2,Color.red);

Debug.DrawLine(f0,f1,Color.red);

Debug.DrawLine(f0,f2,Color.red);

Vector3point=cube.position;

if(isINTriangle(point,transform.position,f1,f0)||isINTriangle(point,transform.position,f2,f0))

{

Debug.Log("cubeinthis!

!

!

");

}else 

{

Debug.Log("cubenotinthis!

!

!

");

}

}

privatefloattriangleArea(floatv0x,floatv0y,floatv1x,floatv1y,floatv2x,floatv2y) 

{

returnMathf.Abs((v0x*v1y+v1x*v2y+v2x*v0y

-v1x*v0y-v2x*v1y-v0x*v2y)/2f);

}

boolisINTriangle(Vector3point,Vector3v0,Vector3v1,Vector3v2)

{

floatx=point.x;

floaty=point.z;

floatv0x=v0.x;

floatv0y=v0.z;

floatv1x=v1.x;

floatv1y=v1.z;

floatv2x=v2.x;

floatv2y=v2.z;

floatt=triangleArea(v0x,v0y,v1x,v1y,v2x,v2y);

floata=triangleArea(v0x,v0y,v1x,v1y,x,y)+triangleArea(v0x,v0y,x,y,v2x,v2y)+triangleArea(x,y,v1x,v1y,v2x,v2y);

if(Mathf.Abs(t-a)<=0.01f) 

{

returntrue;

}else 

{

returnfalse;

}

}

}

如下图所示,如果箱子对象是主角的视野中就会检测到。

 

 

    注意,上图中我的视野选择了两个三角形,如果你需要视野目标点是椭圆形的话,那么可以多设置一些三角形。

但是这样就会非常消耗效率,我觉得这里完全可以使用1个三角形,,只是正对的目标点会出现一些偏差,影响其实并不会很大。

如下图所示

 

代码简单的修改一下即可。

usingUnityEngine;

usingSystem.Collections;

publicclassMyTest:

MonoBehaviour{

publicTransformcube;

privatefloatdistance=5f;

voidUpdate() 

{

Quaternionr=transform.rotation;

Vector3f0=(transform.position+(r*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f0,Color.red);

Quaternionr0=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y-30f,transform.rotation.eulerAngles.z);

Quaternionr1=Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y+30f,transform.rotation.eulerAngles.z);

Vector3f1=(transform.position+(r0*Vector3.forward)*distance);

Vector3f2=(transform.position+(r1*Vector3.forward)*distance);

Debug.DrawLine(transform.position,f1,Color.red);

Debug.DrawLine(transform.position,f2,Color.red);

Debug.DrawLine(f1,f2,Color.red);

Vector3point=cube.position;

if(isINTriangle(point,transform.position,f1,f2))

{

Debug.Log("cubeinthis!

!

!

");

}else 

{

Debug.Log("cubenotinthis!

!

!

");

}

}

privatefloattriangleArea(floatv0x,floatv0y,floatv1x,floatv1y,floatv2x,floatv2y) 

{

returnMathf.Abs((v0x*v1y+v1x*v2y+v2x*v0y

-v1x*v0y-v2x*v1y-v0x*v2y)/2f);

}

boolisINTriangle(Vector3point,Vector3v0,Vector3v1,Vector3v2)

{

floatx=point.x;

floaty=point.z;

floatv0x=v0.x;

floatv0y=v0.z;

floatv1x=v1.x;

floatv1y=v1.z;

floatv2x=v2.x;

floatv2y=v2.z;

floatt=triangleArea(v0x,v0y,v1x,v1y,v2x,v2y);

floata=triangleArea(v0x,v0y,v1x,v1y,x,y)+triangleArea(v0x,v0y,x,y,v2x,v2y)+triangleArea(x,y,v1x,v1y,v2x,v2y);

if(Mathf.Abs(t-a)<=0.01f) 

{

returntrue;

}else 

{

returnfalse;

}

}

}

 

上面我们介绍了三角形判断,当然也可以通过矩形来判断是否相交。

 

代码:

usingUnityEngine;

usingSystem.Collections;

publicclassMyTest:

MonoBehaviour{

publicTransformcube;

privatefloatdistance=5f;

voidUpdate() 

{

Quaternionr=transform.rotation;

Vector3left=(transform.position+(r*Vector3.left)*distance);

Debug.DrawLine(transform.position,left,Color.red);

Vector3right=(transform.position+(r*Vector3.right)*distance);

Debug.DrawLine(transform.position,right,Color.red);

Vector3leftEnd=(left+(r*Vector3.forward)*distance);

Debug.DrawLine(left,leftEnd,Color.red);

Vector3rightEnd=(right+(r*Vector3.forward)*distance);

Debug.DrawLine(right,rightEnd,Color.red);

Debug.DrawLine(leftEnd,rightEnd,Color.red);

Vector3point=cube.position;

if(isINRect(point,leftEnd,rightEnd,right,left))

{

Debug.Log("cubeinthis!

!

!

");

}else 

{

Debug.Log("cubenotinthis!

!

!

");

}

}

privatefloatMultiply(floatp1x,floatp1y,floatp2x,floatp2y,floatp0x,floatp0y)

{

return((p1x-p0x)*(p2y-p0y)-(p2x-p0x)*(p1y-p0y));

}

boolisINRect(Vector3point,Vector3v0,Vector3v1,Vector3v2,Vector3v3)

{

floatx=point.x;

floaty=point.z;

floatv0x=v0.x;

floatv0y=v0.z;

floatv1x=v1.x;

floatv1y=v1.z;

floatv2x=v2.x;

floatv2y=v2.z;

floatv3x=v3.x;

floatv3y=v3.z;

if(Multiply(x,y,v0x,v0y,v1x,v1y)*Multiply(x,y,v3x,v3y,v2x,v2y)<=0&&Multiply(x,y,v3x,v3y,v0x,v0y)*Multiply(x,y,v2x,v2y,v1x,v1y)<=0)

returntrue;

else

returnfalse;

}

}

好了就到这了,希望我的这些对大家有一定的帮助。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 学科竞赛

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1