2015-08-09 21:05:03 a524371025 阅读数 3189

         相信很多做游戏的开发人员都会面临 物体碰撞检测的问题  一般的手游不需要考虑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 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

 

 

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

 

2014-05-07 22:45:27 wangbin_jxust 阅读数 2100

转载出处:http://blog.csdn.net/pleasecallmewhy/article/details/8289880

需求:当立方体Cube碰到地面Plane的时候,输出碰撞物体的名称,则表述检测到立方体碰撞了地面。

过程:

1.搭建一个简单的场景。

在新的工程中选择File->new Scene创建新的场景。

然后在该场景中添加地板:GameObject->Create Other->Plain,

以及正方体:GameObject->Create Other->Cube。

给正方体添加刚体:Component->Physics->Rigidbody。

添加后可以设置刚体属性。

在Project处右击,选择Import Package->Physic Matarials。

引入完成后可以直接把材质拖动到Hierachy窗口的组件中。

bouncy:弹力十足的蹦蹦跳跳型。

ice:像冰块一样碰撞。

metal:像金属一样碰撞。

rubber:像橡胶一样碰撞。

wood:像木头一样碰撞。

然后在“Hierarchie”面板中单击表示地板的组件,然后在Inspector中给它命名为“Ground”

然后调整他们的位置大约像这样:



2.创建脚本文件添加监听。


选择Assets->Create->Javascript,创建JS文件并且重命名为“Collision”

在Project窗口中双击它,Unity会启动Monodevelop来编辑js文件。
清除里面默认创建的代码。写上。

[javascript] view plaincopy
  1. function OnCollisionEnter(obj:Collision)  
  2. {  
  3.     Debug.Log("Collider:"+obj.collider.name+" gameObject:"+obj.gameObject.name);  
  4. }  


onCollisionEnter函数解释:这个函数是在被绑定的物体与其他物体发生碰撞的时候被调用。

obj参数解释:被撞的物体参数,类型是Collision,在本例中就是“Ground”。

携带变量gameObject,是我们碰撞的物体。

3、将脚本文件拖到立方体上实现绑定

在"Project"面板中选中collision.js脚本,按住鼠标左键不放,直接拖入“Hierarchie”面板中,放到Ground上,松开鼠标即完成绑定。可以在右边的Inspetor面板查看相关内容。


现在可以运行该程序了。

运行后在界面左下角会输出:

        Collider:Cube gameObject:Cube

至此一个简单的碰撞检测便完成了。

2014-05-04 14:30:46 u013951435 阅读数 1668
在这章内容里,我们来看看在unity3d中是如何完成简单的碰撞检测的。描述如下:当立方体碰到地面,输出被立方体碰撞的地面的name“地板”,则表述检测到立方体碰撞了地面。

第一步 搭建场景。

        如何搭建场景,只要同学们看完第零章以及第零章内推荐的视频教程相信能轻松完成。这里就不重复叙述了。场景截图如下


        我们在“Hierarchie”面板中单击表示地板的组件(我用的是box);然后在Inspector中给它命名为“地板”
        
           

第二步 编写代码

        在“Project”面板中单击“Create”旁边的小三角,选择“javascript”创建一个名为“collision”的js文件。双击它,系统启动Monodevelop来编辑js文件。
        清除里面默认创建的代码。写上。

function OnCollisionEnter(obj:Collision)
{
Debug.Log(obj.gameObject.name);
}

        onCollisionEnter函数解释:这个函数是在被绑定的物体与其他物体发生碰撞的时候被调用。
        obj参数解释:被撞的物体参数,类型是Collision,在本例中就是“地板”.携带变量gameObject,是我们碰撞的物体name,就是我们为地板设置的name。

第三步 将脚本文件拖到立方体上实现绑定

        这步很容易操作,在" Project"面板中选中collision脚本,按住鼠标左键不放,直接拖入“Hierarchie”面板中,放到立方体上,松开鼠标即完成绑定。

第四步  点顶部的小三角运行程序

        程序运行结果,当立方体与地板碰撞时,unity3d底部状态栏会输出地板的nameunity3d游戏测评

        搞定。


2014-04-01 13:33:06 RanShaoBaLieHuo 阅读数 967
在这章内容里,我们来看看在unity3d中是如何完成简单的碰撞检测的。描述如下:当立方体碰到地面,输出被立方体碰撞的地面的name“地板”,则表述检测到立方体碰撞了地面。

第一步 搭建场景。

        如何搭建场景,只要同学们看完第零章以及第零章内推荐的视频教程相信能轻松完成。这里就不重复叙述了。场景截图如下

          

        我们在“Hierarchie”面板中单击表示地板的组件(我用的是box);然后在Inspector中给它命名为“地板”
        
          

第二步 编写代码

        在“Project”面板中单击“Create”旁边的小三角,选择“javascript”创建一个名为“collision”的js文件。双击它,系统启动Monodevelop来编辑js文件。
        清除里面默认创建的代码。写上。
  1. function OnCollisionEnter(obj:Collision)
  2. {
  3. Debug.Log(obj.gameObject.name);
  4. }
复制代码
        onCollisionEnter函数解释:这个函数是在被绑定的物体与其他物体发生碰撞的时候被调用。
        obj参数解释:被撞的物体参数,类型是Collision,在本例中就是“地板”.携带变量gameObject,是我们碰撞的物体name,就是我们为地板设置的name。

第三步 将脚本文件拖到立方体上实现绑定

        这步很容易操作,在" Project"面板中选中collision脚本,按住鼠标左键不放,直接拖入“Hierarchie”面板中,放到立方体上,松开鼠标即完成绑定。

第四步  点顶部的小三角运行程序

        程序运行结果,当立方体与地板碰撞时,unity3d底部状态栏会输出地板的name

          

        搞定。


DEMO 网址:http://download.csdn.net/detail/ranshaobaliehuo/7129265

2015-10-09 09:36:56 lengyuefengqing 阅读数 472

当立方体Cube碰到地面Plane的时候,输出碰撞物体的名称,则表述检测到立方体碰撞了地面。

过程:

1.搭建一个简单的场景。

在新的工程中选择File->new Scene创建新的场景。

然后在该场景中添加地板:GameObject->Create Other->Plain,

以及正方体:GameObject->Create Other->Cube。

给正方体添加刚体:Component->Physics->Rigidbody。

添加后可以设置刚体属性。

在Project处右击,选择Import Package->Physic Matarials。

引入完成后可以直接把材质拖动到Hierachy窗口的组件中。

bouncy:弹力十足的蹦蹦跳跳型。

ice:像冰块一样碰撞。

metal:像金属一样碰撞。

rubber:像橡胶一样碰撞。

wood:像木头一样碰撞。

然后在“Hierarchie”面板中单击表示地板的组件,然后在Inspector中给它命名为“Ground”

然后调整他们的位置大约像这样:



2.创建脚本文件添加监听。


选择Assets->Create->Javascript,创建JS文件并且重命名为“Collision”

在Project窗口中双击它,Unity会启动Monodevelop来编辑js文件。
清除里面默认创建的代码。写上。

[javascript] view plaincopy
  1. function OnCollisionEnter(obj:Collision)  
  2. {  
  3.     Debug.Log("Collider:"+obj.collider.name+" gameObject:"+obj.gameObject.name);  
  4. }  


onCollisionEnter函数解释:这个函数是在被绑定的物体与其他物体发生碰撞的时候被调用。

obj参数解释:被撞的物体参数,类型是Collision,在本例中就是“Ground”。

携带变量gameObject,是我们碰撞的物体。

3、将脚本文件拖到立方体上实现绑定

在"Project"面板中选中collision.js脚本,按住鼠标左键不放,直接拖入“Hierarchie”面板中,放到Ground上,松开鼠标即完成绑定。可以在右边的Inspetor面板查看相关内容。


没有更多推荐了,返回首页