unity3d碰撞检测之立方体碰撞算法
2015-08-09 21:05
831 查看
相信很多做游戏的开发人员都会面临 物体碰撞检测的问题 一般的手游不需要考虑Y轴 只需要用到简单的 点与面的位置关系 即1点在面内 2 点在面外或则点与线的位置关系1 点在线上 2点在线外,假如要做类似天涯明月刀的端游 人物可能会跳到房子上 这时候你需要考虑到Y轴 那么点与面的位置关系就不满足碰撞需求了 我们这时候就需要用圆柱体碰撞 或则 立方体碰撞了 这里我要讲解的就是立方体碰撞检测的算法
首先做立方体碰撞检测算法需要哪些条件呢 1 立方体的8个顶点坐标 2 要检测的点坐标
假如我要做一个英雄普通攻击碰撞 我可以得到英雄的三维坐标 知道英雄的坐标,立方体的8个顶点坐标也随即可以得出了 怪物坐标自然也是已知的 分析到这里 接下来就是实现算法了
知道了立方体的8个顶点坐标 和怪物坐标
我们以立方体其中一个顶点作为坐标原点,过原点其中两个顶点分别在另两条坐标轴上 即立方体3个顶点分别在3条轴上 然后将怪物变换位置从世界坐标到坐标原点为Point1 这个时候以新坐标原点立方体的长宽高也形成了一个新的坐标Point2 最后分别比较Point1和Point2, x、y、z即可得出结果 文字分析结束下面上代码
版权声明:本篇文章为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,谢谢!
首先做立方体碰撞检测算法需要哪些条件呢 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 z float 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
版权声明:本篇文章为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,谢谢!
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- 我是运营,我没有假期
- c#调用COM组件
- 开发人员、程序员与计算机科学家三者之间的区别
- 每个 Linux 游戏玩家都绝不想要的恼人体验
- Steam 让我们在 Linux 上玩 Windows 的游戏更加容易
- 如何使用 Steam Play 在 Linux 上玩仅限 Windows 的游戏
- 新一代iPad适配应用之游戏篇
- 动易2006序列号破解算法公布
- VB实现的《QQ美女找茬游戏》作弊器实例
- C#实现把指定数据写入串口
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#通用邮件发送类分享
- C#中this的用法集锦
- C#.NET获取拨号连接的宽带连接方法
- C#实现AddRange为数组添加多个元素的方法