200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > unity3d碰撞检测之立方体碰撞算法

unity3d碰撞检测之立方体碰撞算法

时间:2022-05-08 12:22:53

相关推荐

unity3d碰撞检测之立方体碰撞算法

相信很多做游戏的开发人员都会面临 物体碰撞检测的问题 一般的手游不需要考虑Y轴 只需要用到简单的 点与面的位置关系 即1点在面内 2 点在面外或则点与线的位置关系1 点在线上 2点在线外,假如要做类似天涯明月刀的端游 人物可能会跳到房子上 这时候你需要考虑到Y轴 那么点与面的位置关系就不满足碰撞需求了我们这时候就需要用圆柱体碰撞 或则 立方体碰撞了 这里我要讲解的就是立方体碰撞检测的算法

首先做立方体碰撞检测算法需要哪些条件呢 1 立方体的8个顶点坐标 2 要检测的点坐标

假如我要做一个英雄普通攻击碰撞 我可以得到英雄的三维坐标 知道英雄的坐标,立方体的8个顶点坐标也随即可以得出了 怪物坐标自然也是已知的 分析到这里 接下来就是实现算法了

知道了立方体的8个顶点坐标 和怪物坐标

我们以立方体其中一个顶点作为坐标原点,过原点其中两个顶点分别在另两条坐标轴上 即立方体3个顶点分别在3条轴上 然后将怪物变换位置从世界坐标到坐标原点为Point1 这个时候以新坐标原点立方体的长宽高也形成了一个新的坐标Point2 最后分别比较Point1和Point2, x、y、z即可得出结果 文字分析结束下面上代码

#region 立方体碰撞/// <summary>/// 立方体碰撞(主角朝向 可对空)使用函数/// </summary>/// <param name="transform">当前对象</param>/// <param name="Point">敌人坐标</param>/// <param name="width">立方体宽度</param>/// <param name="distance">立方体长度</param>/// <param name="hight">立方体高度</param>/// <param name="JuLi">当前对象离脚底的距离</param>/// <returns>是否在立方体内</returns>public static bool Cubecollision(ref Transform Cude, Transform transform, Vector3 Point, float width, float distance, float hight, float JuLi){//得出立方体的8个顶点坐标Quaternion r = transform.rotation;Vector3 DownLeftback = (transform.position + (r * Vector3.left) * width + (r * Vector3.down) * JuLi);Vector3 DownRightback = (transform.position + (r * Vector3.right) * width + (r * Vector3.down) * JuLi);Vector3 DownLeftforward = DownLeftback + (r * Vector3.forward) * distance;Vector3 DownRightforward = DownRightback + (r * Vector3.forward) * distance;Vector3 UpLeftback = DownLeftback + (r * Vector3.up) * hight;Vector3 UpRightback = DownRightback + (r * Vector3.up) * hight;Vector3 UpLeftforward = UpLeftback + (r * Vector3.forward) * distance;Vector3 UpRightforward = UpRightback + (r * Vector3.forward) * distance;//判断是否在立方体内if (Cubedetection(ref Cude, Point, UpLeftforward, UpRightforward,UpLeftback, UpRightback, DownLeftforward,DownRightforward, DownLeftback, DownRightback)){return true;}return false;}/// <summary>/// 画线函数测试立方体是否正确/// </summary>/// <param name="transform"></param>/// <param name="Point"></param>/// <param name="width"></param>/// <param name="distance"></param>/// <param name="hight"></param>/// <param name="JuLi"></param>public static void Cubedrawingline(Transform transform, float width, float distance, float hight, float JuLi){Quaternion r = transform.rotation;Vector3 Downleftback = (transform.position + (r * Vector3.left) * width + (r * Vector3.down) * JuLi);Vector3 DownRightback = (transform.position + (r * Vector3.right) * width + (r * Vector3.down) * JuLi);Vector3 DownLeftforward = Downleftback + (r * Vector3.forward) * distance;Vector3 DownRightforward = DownRightback + (r * Vector3.forward) * distance;Vector3 UpLeftback = Downleftback + (r * Vector3.up) * hight;Vector3 UpRightback = DownRightback + (r * Vector3.up) * hight;Vector3 UpLeftforward = UpLeftback + (r * Vector3.forward) * distance;Vector3 UpRightforward = UpRightback + (r * Vector3.forward) * distance;//底面Debug.DrawLine(Downleftback, DownRightback);Debug.DrawLine(Downleftback, DownLeftforward);Debug.DrawLine(DownRightback, DownRightforward);Debug.DrawLine(DownLeftforward, DownRightforward);//左面Debug.DrawLine(Downleftback, UpLeftback);Debug.DrawLine(UpLeftback, UpLeftforward);Debug.DrawLine(UpLeftforward, DownLeftforward);Debug.DrawLine(DownLeftforward, Downleftback);//右面Debug.DrawLine(DownRightback, UpRightback);Debug.DrawLine(UpRightback, UpRightforward);Debug.DrawLine(UpRightforward, DownRightforward);Debug.DrawLine(DownRightforward, DownRightback);//上面Debug.DrawLine(UpRightback, UpRightforward);Debug.DrawLine(UpLeftback, UpRightback);Debug.DrawLine(UpLeftback, UpLeftforward);Debug.DrawLine(UpLeftforward, UpRightforward);//前面Debug.DrawLine(UpLeftforward, UpRightforward);Debug.DrawLine(UpLeftforward, DownLeftforward);Debug.DrawLine(UpRightforward, DownRightforward);Debug.DrawLine(DownLeftforward, DownRightforward);//后面Debug.DrawLine(UpLeftback, UpRightback);Debug.DrawLine(UpLeftback, Downleftback);Debug.DrawLine(UpRightback, DownRightback);Debug.DrawLine(Downleftback, DownRightback);}/// <summary>/// 立方体碰撞检测算法/// </summary>/// <param name="Cude">Transform 坐标原点 没办法因为要用到InverseTransformPoint函数必须传个Transform进来 为了节约性能用了ref引用传递 </param>/// <param name="Point">敌人坐标</param>/// <param name="UpLeftforward">立方体上左前坐标</param>/// <param name="UpRightforward">立方体上右前坐标</param>/// <param name="UpLeftback">立方体上左后坐标</param>/// <param name="UpRightback">立方体上右后坐标</param>/// <param name="DownLeftforward">立方体下左前坐标</param>/// <param name="DownRightforward">立方体下右前坐标</param>/// <param name="DownLeftback">立方体下左后坐标</param>/// <param name="DownRightback">立方体下右前坐标</param>/// <returns>返回是否在立方体内</returns>private static bool Cubedetection(ref Transform Cude, Vector3 Point, Vector3 UpLeftforward, Vector3 UpRightforward, Vector3 UpLeftback, Vector3 UpRightback, Vector3 DownLeftforward, Vector3 DownRightforward, Vector3 DownLeftback, Vector3 DownRightback){//判断(Cude代表坐标原点)Cude是否为空if (Cude == null){Cude = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;//去掉Mesh使之成为一个空物体Destroy(Cude.GetComponent<MeshFilter>());Destroy(Cude.GetComponent<BoxCollider>());Destroy(Cude.GetComponent<MeshRenderer>());}//这里以上左后为坐标原点 规定Y轴上方向为正方向 X轴右方向为正 Z轴前方向为正Cude.position = UpLeftback;//得出以Cude为坐标原点立方体长宽高形成的新坐标x y zfloat x = (UpRightback - UpLeftback).x;float y = (DownLeftback - UpLeftback).y;float z = (UpLeftforward - UpLeftback).z;//转换Point变换位置从世界坐标到Cude自身坐标Vector3 m_Point = Cude.InverseTransformPoint(Point);//比较x y z大小判断是否在立方体内if (m_Point.y >= y && m_Point.y <= 0 && m_Point.x <= x && m_Point.x >= 0 && m_Point.z <= z && m_Point.z >= 0){Debug.Log("对方在立方体内");return true;}Debug.Log("对方不在立方体内");return false;}#endregion

版权声明:本篇文章为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,谢谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。