2015-12-22 12:03:45 bbox520 阅读数 8108
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

如果想将地图分为几个不同区域,并实时检测人物在哪个小区域,而且区域是不规则形状的类似这种地图。
这里写图片描述

很自然的想到使用模型添加meshcollider来通过碰撞检测。做几个小地图形状的meshbox,拼在一块,使用OnTriggerEnter/Stay/Exit来检测。但是首先让我们来看看meshCollider介绍。

Unity3d圣典 网格碰撞器 Mesh Collider

以下为摘选的mesh collider介绍:

网格碰撞器利用一个网格资源并在其上构建碰撞器。对于复杂网状模型上的碰撞检测,它要比应用原型碰撞器精确的多。标记为凸起的(Convex )的网格碰撞器才能够和其他网格碰撞器发生碰撞。
class-MeshCollider-0
A Mesh Collider used on level geometry 用于台阶状物体的网格碰撞器

Properties 属性

  • Material 材质
    引用何种物理材质决定了他和其他对象如何作用。
  • Is Trigger 是否触发器
    如激活,此碰撞器用于触发事件,并且被物理引擎忽略。
  • Mesh 网格
    用于碰撞所引用的网格
  • Smooth Sphere Collisions
    平滑性状碰撞
    当被激活,碰撞网格法线是平滑的。用于平滑表面比如由没有棱角的平滑起伏组成的起伏地标时应该激活。
  • Convex 凸起的
    如激活,该网格碰撞器将会和其他网格碰撞器碰撞。凸起的网格碰撞器限制在255个三角形面内。

Details 细节

网格碰撞器通过附加在游戏对象上的网格构建碰撞效果,并严格按照所附加对象的Transform属性来设定其位置和大小比例。
碰撞网格使用背面剔除(或译背面拣选,指正面多边形挡住了在它后面的背面多边形,Direct3D将通过拣选(即删除多余的处理过程)背面多边形来提高效率的过程。)如果一个对象和被背面剔除的网格碰撞,那也不会在物理上碰撞。
使用网格碰撞器有一些限制条件。通常,两个网格碰撞器之间不会发生碰撞。所有的网格碰撞器可以和任何原型碰撞器碰撞。如果网格标记为凸起的(Convex),那么就可以和其他网格碰撞器碰撞。
碰撞器作用于刚体使Unity中的物理作用生效。因为刚体允许对象被物理系统控制。碰撞器使对象之间产生碰撞作用。碰撞器必须独立于刚体加在对象上。碰撞器并不一定需要附加刚体,但是要使移动物体具有碰撞效果必须附加刚体。
当两个碰撞器间产生碰撞并且其中至少一个附加了刚体时,三个碰撞信息会发送给附加他们的对象,这些事件可以被脚本处理,而且允许用户可以选择自己写脚本或使用内置的NVIDIA PhysX引擎创建唯一的行为。

  • Triggers
    一个可供选择的碰撞器使用方法是标记他们为触发器,仅需要选中检视面板中的IsTrigger属性选择框。触发器不受物理引擎控制,当和一个触发器发生碰撞时会发出三个独特的触发信息。触发器用于触发你游戏中的其他事件,比如过场动画、自动门开启、显示教程信息等等,发挥你的想象力吧!
    当然也应该意识到为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体。一个触发器和一个普通碰撞器碰撞,其中之一必须附加刚体。想了解不同类型碰撞的详细情况,可以参考下边进阶部分中的碰撞行为矩阵。
  • Friction and bouncyness 摩擦力和弹力
    摩擦力、弹力和柔软度由物理材质中定义。标准资源( Standard Assets)中包含了大部分常见的物理材质。要使用只需点击物理材质上的下拉箭头然后选中一个,比如冰。你也可以创建你自己的物理材质并调整摩擦力的大小。

Hints 提示

除非被标记为凸起的(Convex),否则网格碰撞器间不会发生碰撞。因此,它们最常被用于背景对象比如环境布景。
凸起的网格碰撞器含有的三角形面不能多于255个。
原型控制器对于对象的物理控制更加节省资源。
当为游戏对象附加了网格碰撞器,其网格属性将被定义为用于渲染的网格,可以通过指派其他网格来改变。
要给一个对象添加多个碰撞器,应该创建子对象并给每个子对象添加一个碰撞器。这使每个碰撞器可以被单独操作。
可以通过场景视图(Scene View )中的线框(gizmos)来查看碰撞器在你的对象上的预期效果。
碰撞器尽量匹配对象的比例。如果有一组不规则伸缩(每一维度上的比例都不相同),只能使用网格碰撞器才能完全匹配。
如果你想接收通过Transform组件移动的对象的碰撞/触发信息,你必须给移动对象附件刚体。

Advanced 进阶

  • Collider combinations 碰撞器组合
    Unity中有许多不同的碰撞组合。每个游戏都很独特,不同的组合可能更好地适用于不同类型的游戏。如果你在游戏中使用了物理效果,那理解不同的基本碰撞类型会很有帮助,包括它们的常用形式及如何和其他类型的对象作用。
  • Static Collider 静态碰撞器
    指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或者很轻微的移动。对于环境模型十分好用,当和刚体碰撞时而不会移动。
  • Rigidbody Collider 刚体碰撞器
    指的是同时附加了刚体和碰撞器的游戏对象。通过脚本的力量和碰撞完全受物理引擎的影响。可以和只包含碰撞器的游戏对象碰撞。将会成为你游戏中使用物理效果的基本类型碰撞器。
  • Kinematic Rigidbody Collider 运动学刚体碰撞器
    指的是同时包含碰撞器和刚体,并且激活IsKinematic的一类游戏对象,要移动这类游戏对象,要修改它的Transform组件,而不是用力。它们很像静态碰撞器不过对于想要不停地到处移动的碰撞器很好用。这类游戏对象还有许多其他的独特使用情景。
    这类对象可以用于你通常希望用静态碰撞器发出触发事件的情形下。因为触发器必须要有刚体,你应该添加刚体然后启用IsKinematic。这会阻止你的对象因物理作用而移动并且允许接收你希望得到的触发事件。
    运动学刚体启用与否很容易控制。这对创建人偶十分适用,通常,当你希望一个角色依照动画活动,然后由于爆炸或者其他你选择的情况而引起的碰撞导致其变为人偶。这种情况下,很简单,只需要通过脚本将运动学刚体改为普通刚体。
    如果有刚体有时候变得静止不动了,那么它们就是进入休眠了。意味着它们将不受物理变化影响,也就不会移动。如果你把一个运动学刚体从一个休眠的普通刚体下边移走,那休眠的刚体就会被唤醒并重新被物理变化时时影响。所以如果你有许多希望四处移动并有不同的对象要恰好砸到它们的静态碰撞器,那就用运动学刚体碰撞器吧。
  • Collision action matrix 碰撞行为矩阵
    基于两个碰撞对象的配置,可以产生很多不同的效果。下表概括了基于附加不同组件的两个碰撞对象所产生的效果。其中有些组合只能导致碰撞的两个对象中的一个受到影响,.所以考虑到保持标准的规则-物理效果将不会对没有附加刚体的对象生效。
碰撞后有碰撞检测并有碰撞信息发出
Static Collider静态碰撞器 Rigidbody Collider刚体碰撞器 Kinematic Rigidbody Collider运动学刚体碰撞器 Static Trigger Collider静态触发碰撞器 Rigidbody Trigger Collider刚体触发碰撞器 Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Static Collider 静态碰撞器 Y
Rigidbody Collider 刚体碰撞器 Y Y Y
Kinematic Rigidbody Collider运动学刚体碰撞器 Y
Static Trigger Collider静态触发碰撞器
Rigidbody Trigger Collider刚体触发碰撞器
Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Trigger messages are sent upon collision碰撞后有触发信息
Static Collider静态碰撞器 Rigidbody Collider 刚体碰撞器 Kinematic Rigidbody Collider 运动学刚体碰撞器 Static Trigger Collider静态触发碰撞器 Rigidbody Trigger Collider刚体触发碰撞器 Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器
Static Collider 静态碰撞器 Y Y
Rigidbody Collider 刚体碰撞器 Y Y Y
Kinematic Rigidbody Collider运动学刚体碰撞器 Y Y Y
Static Trigger Collider静态触发碰撞器 Y Y Y Y
Rigidbody Trigger Collider刚体触发碰撞器 Y Y Y Y Y Y
Kinematic Rigidbody Trigger Collider运动学刚体触发碰撞器 Y Y Y Y Y Y

PS.以上为我从圣典上copy的去掉英文的介绍,别问我为什么这么做,强迫症没办法,你可以直接去圣典看。

以下是我做这个功能的情形,使用地图模型块添加meshcollider只用选择converx才能使用IsTrigger=true,但是勾选converx后,我的凹多边形就凹的地方被自动包含为凸多面体,检测将不准确,但是不勾选不能设置为触发器,也不能添加rigidbody。如下:

t

所以将人物添加boxcollider,istrigger=true,添加刚体。测试碰撞发现,只有另个物体碰撞时才会触发OnTriggerEnter/Stay/Exit,碰撞结束人物进入地图块后就会调用OnTriggerExit,并不像想象的会一直调用OnTriggerStay,而是有交集碰撞时会一直调用Stay,将meshcollider设为istrigger后发现人物碰撞mesh表面调用enter,进入mesh后一直调用stay,猜测总结为碰撞器只能表面作用,当进入碰撞器内将不再触发碰撞器函数,而触发器是会检测包含区域内的物体的,不仅是在表面碰撞时调用,碰撞器和触发器调用回调函数时间不同。

由于多个小地图块是拼合在一起的,使用convertx将会检测不准确,不适用convertx无法检测任务在meshbox内的位置。最后突然灵机一动,我为什么要一定使用碰撞检测呢,可以用射线啊。so this
每个人物脚本上在updateposition时从头顶1000高度向下发射射线,laymark设为meshcollider的layer,检测射线碰撞点在哪个mesh上,通过meshbox 的name得到是哪个地图,就知道在哪个区域了,代码类下:

    //利用射线检测区域,触发器检测只能检测凹面体表面位置
    if (Physics.Raycast(new Vector3(gpsX, 1000, gpsY), new Vector3(0, -1, 0), out_hitInfo, 10000, 1 << 11))
    {
    EnterArea(int.Parse(_hitInfo.collider.name));
    }

那就这样吧。

2013-12-27 15:24:58 li826008 阅读数 1034
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚
2014-10-14 12:17:30 jlstmac3 阅读数 317
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

蛮牛上看到的一片文章!

链接:http://www.unitymanual.com/thread-28682-1-1.html

2019-06-23 22:08:26 weixin_39549161 阅读数 849
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚

介绍

       在游戏开发过程中,很多地方要用到射线碰撞检测。比如:射击游戏中子弹是否击中敌人,在RPG游戏中是否捡到装备,无人驾驶车辆的雷达检测等。在进行碰撞检测时,我们最常用的工具就是射线,Unity 3D的物理引擎也为我们提供了射线类以及相关的函数接口。本文将对射线的使用进行一个总结。
       射线是在三维世界中从一个点沿一个方向发射的一条无限长的线。在射线的轨迹上,一旦与添加了碰撞器的模型发生碰撞,将停止发射。我们可以利用射线实现子弹击中目标的检测,鼠标点击拾取物体等功能。

射线的创建和显示

  • Ray射线类和RaycastHit射线投射碰撞信息类是两个最常用的射线工具类。
  • public Ray(Vector3 origin, Vector3 direction),创建一条射线需要指明射线的起点(origin)和射线的方向(direction)。
  • Physics.Raycast静态函数用于在场景中发射一条可以和碰撞器碰撞的射线。

程序(Game中不可见,Scence中可见)

  • 本示例中想做车辆激光雷达的检测,所以只做了一根线先练练手。
  • transform.forward为车辆坐标系,Vector3.forward为世界坐标系。
using UnityEngine;
using System.Collections;
public class lasermaster : MonoBehaviour {
    public Vector3 originPos;//射线起始位置
    public Vector3 direction;//射线方向
    public float maxDistance;//射线最大检测距离
	// Use this for initialization
	void Start () {
        maxDistance = 10.0f;
	}
	// Update is called once per frame
	void Update () {
        originPos = transform.position + transform.up * 2.2f;//射线起始位置
        direction = transform.forward;//射线方向
        Vector3 targetPos = originPos + transform.forward * maxDistance;//射线最大检测距离处的点位置,找到起始点与终点,方便画线
        Ray ray = new Ray(originPos, direction);//创建名为ray的射线
        RaycastHit hit;//碰撞检测信息存储
        if (Physics.Raycast(ray, out hit, maxDistance)){//碰撞检测
            Debug.DrawLine(originPos,hit.point);//画线显示
			Debug.Log (hit.collider.name);//打印检测到的碰撞体名称
        }
        else {
            Debug.DrawLine(originPos, targetPos);//没检测到碰撞体,则以最大检测距离画线
        }
	}
}

程序(Game中可见,Scence中可见)

using UnityEngine;
using System.Collections;
public class lasermaster : MonoBehaviour {
    public Vector3 originPos;
    public Vector3 direction;
    public float maxDistance;
	public LineRenderer line;//添加LineRenderer组件
	// Use this for initialization
	void Start () {
        maxDistance = 10.0f;
		line.enabled=true;//初始使能该组件
		line.SetColors (Color.green,Color.green);//设置颜色
		line.SetWidth (0.1f,0.1f);//线大小
	}
	// Update is called once per frame
	void Update () {
        originPos = transform.position + transform.up * 2.2f;
        direction = transform.forward;
        Vector3 targetPos = originPos + transform.forward * maxDistance;
        Ray ray = new Ray(originPos, direction);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, maxDistance)){
			Debug.DrawLine(originPos,hit.point);
			line.SetPosition(0,originPos);
			line.SetPosition(1,hit.point);
			//Debug.Log (hit.collider.name);
        }
        else {
            Debug.DrawLine(originPos, targetPos);
			line.SetPosition(0,originPos);
			line.SetPosition(1,targetPos);
        }
	}
}
2016-07-20 14:46:50 small__zhang 阅读数 599
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4711 人正在学习 去看看 张刚
Unity3d碰撞器
一.碰撞发生的必要条件:
1.产生碰撞效果需要具备两个因素

a.发起碰撞的物体
b.接收碰撞的物体

2发起碰撞的物体
a.Rigidbody
b.CharacterController

3.接受碰撞的物体
a.所有的Collider

二.在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。
触发信息:
1.MonoBehaviour.OnTriggerEnter( Collider other )当进入触发器
2.MonoBehaviour.OnTriggerExit( Collider other )当退出触发器
3.MonoBehaviour.OnTriggerStay( Collider other )当逗留触发器
碰撞信息:
1.MonoBehaviour.OnCollisionEnter( Collision collisionInfo ) 当进入碰撞器
2.MonoBehaviour.OnCollisionExit( Collision collisionInfo ) 当退出碰撞器
3.MonoBehaviour.OnCollisionStay( Collision collisionInfo )  当逗留碰撞器

三.举例
A物体和B物体要发生碰撞,则A和B中必须要带有Collider组件,并且A和B中至少一个物体携带Rigidbody
1.新建一个场景,添加CubeA,CubeB,Ground 三个物体,三个物体创建自Cube,默认带有BoxCollider组件
2.新建一个脚本,TestCollider,复写四个方法
OnCollisionenter,OnCollistionExit,OnTriggerEnter,OnTriggerExit,
在这几个函数中打印一些Log,注明当前进入的函数是哪个物体的哪个函数
3.给物体A和物体B挂上TestCollider脚本
4.为了方便测试,不给物体添加移动脚本了,运行游戏测试的时候,世界更改物体A或物体B的位置,使得A和B相交就行了
直接运行游戏,拖拽物体A移动到物体B处,未来发现打印任何的Log,因为A和B没有满足发生碰撞的必要条件,A和B只有Collider,
没有Rigidbody
5.为了进一步验证碰撞发生的必要条件,我们给a添加一个组件Rigidbody【默认Use Gravity打开,Is Kinematic关闭,
之前新建Ground物体就是为了防止有Rigidbody的物体往下掉落】,再次运行游戏,拖拽物体A移动到物体B,发现物体A不能够穿透物品B,
被B阻挡的效果,打印显示两个物品都进入了OnCollisionEnter和OnCollisitionStay方法
6.为什么只进入了CollisitionXX方法而没有进入OnTriggerXX方法呢,因为物体的Collider下的IsTrigger没有打勾,所以不会触发
7.现在把物体B的Is Trigger选项打勾,再次运行游戏,发现A会穿透B,且AB两个物体进入了OnTriggerXX函数。【这里有人会问,为什么只勾选物体B的
IsTrigger选项,起始勾选A,B任一个都行,或两个都勾选,但是这里勾选A的IsTrigger,物体A会直接掉落,可先把物体A的UseGravity钩去掉,勾选IsKinematic,再勾选IsTrigger】

四.总结
当Is Trigger=false时【Rigidbody 开启UseGravity,需要模拟物理碰撞】,碰撞器根据物理引擎引发碰撞,产生碰撞的物理效果,可以调用OnCollisionEnter/Stay/Exit函数;
当Is Trigger=true时【Rigidbody,关掉UseGravity,开启IsKinematic,避免物体下落】,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。

当需要看到物理碰撞效果的时候,调用OnCollistionXX
当需要碰撞后不影响物体位置方向等,调用OnTriggerXX

unity3d中的碰撞系统

阅读数 3421

unity3D 射线检测

阅读数 315

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