Uni ty 中的碰撞检测方法

合集下载

基于Unity3D 虚拟校园漫游碰撞检测的研究

基于Unity3D 虚拟校园漫游碰撞检测的研究

撞检测。

该属性提供了3种碰撞检测方式:discrete (离散模式)、continuous(连续模式)、continuous dynamic(动态连续模式)。

这3种模式运用方法如下:discrete模式是默认的,场景中其他的所有碰撞体进行碰撞检测,一般静止或运动速度较慢的碰撞体使用该模式,虚拟校园漫游中碰撞体的速度一般都是较慢的,所以漫游时的碰撞检测使用的就是该模式。

其他另外两种模式,主要用在运动速度快的碰撞体进行碰撞检测[2]。

2碰撞的实现2.1碰撞检测方式在Unity3D中的检测碰撞发生的方式有两种,分别是碰撞器和触发器。

二者的关系如下:碰撞器是个组件,而触发器是碰撞器的一个属性即Is Trig-ger。

当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果。

碰撞器碰撞检测需要附加刚体指定为刚体碰撞器或者不附加刚体指定为静态碰撞器,触发器碰撞器不需要刚体的支持。

碰撞信息检测:①进入碰撞器MonoBehaviour.OnCollisionEnter (Collision collision)②退出碰撞器MonoBehaviour.OnCollisionExit (Collision collision)③逗留碰撞MonoBehaviour.OnCollisionStay(Colli⁃sion collision)触发信息检测:①进入触发器MonoBehaviour.OnTriggerEnter (Collider collider)②退出触发器MonoBehaviour.OnTriggerExit (Collider collider)③逗留触发器MonoBehaviour.OnTriggerStay (Collider collider)物体碰撞器的添加,选中物体执行component菜单>单击physics选择合理的碰撞器,然后在物体选中的状态下为其添加刚体(component菜单>physics> rigidbody),需要注意的是,车轮碰撞器与其他碰撞器的添加方法不同,其先在Unity3D中创建一个空对象并调整位置与车轮位置相同,接着让其作为车轮的子对象,最后为空对象添加车轮碰撞器。

unity3d的碰撞检测及trigger

unity3d的碰撞检测及trigger

unity3d的碰撞检测及triggerA、基本概念  要产⽣碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动。

碰撞体是物理组件的⼀类,它要与刚体⼀起添加到游戏对象上才能触发碰撞。

如果两个刚体相互撞在⼀起,除⾮两个对象有碰撞体时物理引擎才会计算碰撞,在物理模拟中,没有碰撞体的刚体会彼此相互穿过。

物体发⽣碰撞的必要条件: 两个物体都必须带有碰撞器(Collider),其中⼀个物体还必须带有Rigidbody刚体。

在unity3d中,能检测碰撞发⽣的⽅式有两种,⼀种是利⽤碰撞器,另⼀种则是利⽤触发器。

碰撞器:⼀群组件,它包含了很多种类,⽐如:Box Collider(盒碰撞体),Mesh Collider(⽹格碰撞体)等,这些碰撞器应⽤的场合不同,但都必须加到GameObjecet⾝上。

触发器,只需要在检视⾯板中的碰撞器组件中勾选IsTrigger属性选择框。

触发信息检测: 1.MonoBehaviour.OnTriggerEnter(Collider collider)当进⼊触发器 2.MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器 3.MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器碰撞信息检测: 1.MonoBehaviour.OnCollisionEnter(Collision collision) 当进⼊碰撞器 2.MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器 3.MonoBehaviour.OnCollisionStay(Collision collision) 当逗留碰撞器B、何时触发?下⾯就是我做的测试情况,都是A物体去撞B物体。

⼀、A(碰撞体),B(没有碰撞体,⽆论有没有刚体),没有触发事件。

unity射线碰撞检测+LayerMask

unity射线碰撞检测+LayerMask

射线在unity中是个很方便的东西,对对象查找、多用于碰撞检测(如:子弹飞行是否击中目标)、角色移动等提供了很大的帮助,在此做个总结与大家分享下,若有不足欢迎吐槽好了,话补多说啦,直接进入主题:射线:在unity中射线是由一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射。

相关API:1、Ray Camera.main.ScreenPointToRay(Vector3 pos) 返回一条射线Ray从摄像机到屏幕指定一个点2、Ray Camera.main.ViewportPointToRay(Vector3 pos) 返回一条射线Ray从摄像机到视口(视口之外无效)指定一个点3、Ray 射线类文章来自【狗刨学习网】4、RaycastHit 光线投射碰撞信息5、bool Physics.Raycast(Vector3 origin, Vector3 direction, float distance, int layerMask)当光线投射与任何碰撞器交叉时为真,否则为假。

bool Physics.Raycast(Ray ray, Vector3 direction, RaycastHit out hit, float distance, int layerMask)在场景中投下可与所有碰撞器碰撞的一条光线,并返回碰撞的细节信息()。

bool Physics.Raycast(Ray ray, float distance, int layerMask)当光线投射与任何碰撞器交叉时为真,否则为假。

bool Physics.Raycast(Vector3 origin, Vector3 direction, RaycastHit out hit,float distance, int layerMask)当光线投射与任何碰撞器交叉时为真,否则为假。

注意:如果从一个球型体的内部到外部用光线投射,返回为假。

如何使用Unity进行游戏物理模拟与碰撞检测

如何使用Unity进行游戏物理模拟与碰撞检测

如何使用Unity进行游戏物理模拟与碰撞检测引言Unity是一款功能强大的游戏引擎,广泛应用于游戏开发行业。

其中对物理模拟和碰撞检测的支持是其特色之一。

本文将介绍如何在Unity中进行游戏物理模拟和碰撞检测,以帮助开发者更好地利用Unity的物理引擎。

一、Unity中的物理引擎Unity内置了一个基于NVIDIA PhysX的三维物理引擎,可以用于进行物体的物理模拟和碰撞检测。

在使用之前,我们需要了解一些基本概念。

1. 质量和刚体在物理模拟中,我们需要给物体设置质量。

通过调整质量,我们可以让物体在物理引擎中表现出不同的运动特性,如惯性等。

同时,我们需要将物体设置为刚体,以启用物理模拟。

2. 碰撞体Unity提供了多种碰撞体类型,如盒状碰撞体、球状碰撞体、胶囊碰撞体等。

我们需要根据物体的形状选择适当的碰撞体类型,并将其添加到物体上。

碰撞体决定了物体在碰撞中的表现。

二、物理模拟Unity的物理模拟通过在场景中添加刚体组件来实现。

以下是一些常用的物理模拟技巧。

1. 重力通过给物体添加重力刚体组件,我们可以启用重力对物体的作用。

调整刚体组件的质量和重力因子,可以控制物体受到的重力大小。

2. 碰撞物理模拟中,碰撞是不可避免的。

我们可以利用Unity提供的碰撞检测功能,在碰撞发生时触发特定的逻辑。

例如,我们可以在两个物体碰撞时播放音效、产生粒子效果等。

3. 关节Unity中的关节可以用于模拟物体之间的连接关系。

例如,我们可以使用HingeJoint来模拟门的开关,或者使用SpringJoint模拟弹簧的拉伸效果。

关节是实现物理模拟中更复杂效果的重要工具。

三、碰撞检测碰撞检测是游戏开发中常用的技术,可以用于处理物体之间的碰撞事件。

在Unity中,我们可以通过以下方式进行碰撞检测。

1. OnCollisionEnter和OnCollisionExit我们可以为物体添加脚本,并在脚本中定义OnCollisionEnter 和OnCollisionExit方法。

Unity物理引擎与碰撞检测实践

Unity物理引擎与碰撞检测实践

Unity物理引擎与碰撞检测实践1. 引言Unity物理引擎是游戏开发中广泛使用的一种工具,它能模拟和模拟物体间的物理行为。

碰撞检测则是物理引擎中的关键技术,用于检测游戏中物体之间的碰撞事件。

本文将介绍Unity中物理引擎的基本原理,并通过实例演示如何实现碰撞检测。

2. Unity物理引擎基本原理Unity物理引擎基于传统的牛顿力学原理,通过模拟和计算物体间的力、速度和加速度来模拟物体的运动和碰撞。

在Unity中,可以通过刚体组件向游戏对象添加物理特性。

刚体可以定义物体的质量、碰撞形状和运动行为,并受到力的作用而产生运动。

Unity的物理引擎使用了迭代求解器来模拟物理效果,通过将物体的力和约束条件转化为线性和非线性方程组,迭代求解器可以计算物体的运动状态。

3. 刚体和碰撞器刚体是物理引擎中的基本单位,用于描述物体的质量、移动和旋转。

在Unity中,可以通过添加Rigidbody组件将游戏对象转化为刚体。

刚体可以受到力的作用而产生运动,并与其他刚体进行碰撞。

除了刚体,物体间的碰撞还需要使用碰撞器来定义碰撞形状。

在Unity中,常用的碰撞器包括SphereCollider、BoxCollider和MeshCollider等。

通过给游戏对象添加相应的碰撞器组件,可以定义物体的碰撞形状,并与其他物体进行碰撞检测。

4. 碰撞检测原理在Unity中,碰撞检测是通过检测碰撞器之间的重叠来实现的。

当两个具有碰撞器的物体重叠时,物理引擎会自动检测到碰撞事件,并根据刚体的质量、速度等参数计算碰撞后的反应。

Unity使用了分离轴定理和GJK算法等技术来进行高效的碰撞检测。

分离轴定理可以快速判断两个凸多边形是否重叠,而GJK算法则可以用于判断两个任意形状的物体是否相交。

5. 碰撞检测实践在Unity中,可以通过代码来实现碰撞检测,并根据不同的碰撞事件做出相应的处理。

首先,需要给游戏对象添加碰撞器组件,并设置合适的碰撞形状。

Python--项目实战--碰撞检测

Python--项目实战--碰撞检测

Python--项⽬实战--碰撞检测⽬标了解碰撞检测⽅法碰撞实现01,了解碰撞检测⽅法pygame提供了两个⾮常⽅便的⽅法可以实现碰撞检测:pygame.sprite,groupcollide()两个精灵组中所有的精灵的碰撞检测groupcollide(group1, group2, dokill1, diokill2, collided = None) -> Sprite_dict如果将dokill设置为True,则发⽣碰撞的精灵将⾃动移除collided参数是⽤于计算碰撞的回调函数如果没有指定,则每个精灵必须有⼀个rect属性代码实现def __check_collide(self):# 1,⼦弹摧毁敌机pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)pygame.sprite.spritecollide()判断某个精灵和指定精灵组中的精灵的碰撞spritecollide(sprite, group, dokill, collided = None) - > Sprite_dict如果将dokill设置为True,则指定精灵组中发⽣碰撞的精灵将⾃动被移除collided参数是⽤于计算碰撞的回调函数如果没有指定,则每个精灵必须有⼀个rect1属性返回精灵组中跟精灵发⽣碰撞的精灵列表代码实现# 2,敌机碰撞毁英雄pygame.sprite.spritecollide(self.hero, self.enemy_group, True)注敌机摧毁了,但是英雄缺没有牺牲02,碰撞实现根据敌机碰撞英雄返回的被摧毁的精灵列表是否有内容,判断英雄牺牲,并且结束游戏修改__check_collide⽅法# 3,判断列表是否有内容if len(enemise) > 0:# 让英雄牺牲self.hero.kill()# 结束游戏PlaneGame.__game_over()最终代码plane_sprites.pyimport randomimport pygame# 屏幕⼤⼩的常量SCREEN_RECT = pygame.Rect(0, 0, 480, 700)# 刷新的帧率FRAME_PER_SEC = 60# 创建敌机的定时器常量CREATE_ENEMY_EVENT = EREVENT# 英雄发射⼦弹事件HERO_FIRE_EVENT = EREVENT + 1class GameSprite(pygame.sprite.Sprite):"""飞机⼤战游戏精灵"""def __init__(self, image_name, speed=1):# 调⽤⽗类的初始化⽅法super().__init__()# 定义对象的属性self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speed = speeddef update(self, *args):# 在屏幕的垂直⽅向上移动self.rect.y += self.speedclass Background(GameSprite):"""游戏背景精灵"""def __init__(self, is_alt=False):# 1,调⽤⽗类⽅法实现精灵的创建(image/rect/speed)super().__init__("./images/background.png")# 2,判断是否交替图像,如果是,需要设置初始位置if is_alt:self.rect.y = -self.rect.heightdef update(self, *args):# 1,调⽤⽗类的⽅法实现super().update()# 2,判断是否移除屏幕,如果移出屏幕,将图像设置到屏幕上⽅ if self.rect.y >= SCREEN_RECT.height:self.rect.y = -self.rect.heightclass Enemy(GameSprite):"""敌机精灵"""def __init__(self):# 1,调⽤⽗类⽅法,创建敌机精灵,同事指定敌机图⽚super().__init__("./images/enemy1.png")# 2,指定敌机的初始随机速度self.speed = random.randint(1, 6)# 3,指定敌机的初始随机位置self.rect.bottom = 0max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)def update(self, *args):# 1,调⽤⽗类⽅法,保持垂直⽅向的飞⾏super().update()# 3,判断是否飞出屏幕,如果是,需要从精灵组删除敌机if self.rect.y >= SCREEN_RECT.height:# print("飞出屏幕,需要从精灵组删除")# kill ⽅法可以将精灵从所有精灵组中移除,精灵就会被⾃动销毁 self.kill()def __del__(self):# print("敌机挂了 %s" % self.rect)passclass Hero(GameSprite):"""英雄精灵"""def __init__(self):# 1,调⽤⽗类⽅法,设置 image & speedsuper().__init__("./images/me1.png", 0)# 2,设置英雄的初始化位置self.rect.centerx = SCREEN_RECT.centerxself.rect.bottom = SCREEN_RECT.bottom - 120# 3,创建⼦弹的精灵组self.bullets = pygame.sprite.Group()def update(self, *args):# 英雄在⽔平⽅向移动self.rect.x += self.speed# 控制英雄不能离开屏幕if self.rect.x < 0:self.rect.x = 0elif self.rect.right > SCREEN_RECT.right:self.rect.right = SCREEN_RECT.rightdef fire(self):print("发射⼦弹....")for i in (0, 1, 2):# 1,创建⼦弹精灵bullet = Bullet()# 2,设置精灵的初始位置bullet.rect.bottom = self.rect.y - i * 20bullet.rect.centerx = self.rect.centerx# 3,将精灵添加到精灵组self.bullets.add(bullet)class Bullet(GameSprite):"""⼦弹精灵"""def __init__(self):# 调⽤⽗类⽅法,设置⼦弹图⽚,设置初始速度super().__init__("./images/bullet1.png", -2)def update(self, *args):# 调⽤⽗类⽅法,让⼦弹沿垂直⽅向飞⾏super().update()# 判断⼦弹是否飞出屏幕if self.rect.bottom < 0:self.kill()def __del__(self):print("⼦弹被销毁...")plane_main.pyimport pygamefrom Aircraft_War.plane_sprites import *class PlaneGame(object):"""飞机⼤战主游戏"""def __init__(self):print("游戏初始化")# 1,创建游戏的窗⼝# self.screen = pygame.display.set_mode((480, 700))self.screen = pygame.display.set_mode(SCREEN_RECT.size) # 2,创建游戏的时钟self.clock = pygame.time.Clock()# 3,调⽤私有⽅法,精灵和精灵组的创建self.__create_sprites()# 4,设置定时器事件 - 创建敌机pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)pygame.time.set_timer(HERO_FIRE_EVENT, 500)def __create_sprites(self):# 创建背景精灵和精灵组bg1 = Background()bg2 = Background(True)self.back_group = pygame.sprite.Group(bg1, bg2)# 创建敌机的精灵组self.enemy_group = pygame.sprite.Group()# 创建英雄的精灵和精灵组self.hero = Hero()self.hero_group = pygame.sprite.Group(self.hero)def start_game(self):print("游戏开始...")# 1,设置刷新帧率self.clock.tick(FRAME_PER_SEC)# 2,事件监听self.__event_handler()# 3,碰撞检测self.__check_collide()# 4,更新/绘制精灵组self.__update_sprites()# 5,更新显⽰pygame.display.update()def __event_handler(self):for event in pygame.event.get():# 判断是否退出游戏if event.type == pygame.QUIT:PlaneGame.__game_over()elif event.type == CREATE_ENEMY_EVENT:print("敌机出场。

Unity3D5.x交互功能-碰撞检测函数

Unity3D5.x交互功能-碰撞检测函数

Unity3D5.x交互功能-碰撞检测函数1,给第⼀⼈称控制器添加脚本:playercollisions.js 脚本中只定义变量,先不添加⽅法:#pragma strictvar door_open_time:float=3.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;private var doorisopen:boolean=false;private var doortimer:float=0.0;private var currentdoor:GameObject;View Code2,给playercollisions.js中的变量指定对象:3,然后添加碰撞触发执⾏的⽅法:function OnControllerColliderHit(hit:ControllerColliderHit){if (hit.gameObject.tag=="playerDoor" && doorisopen==false) {opendoor(hit.gameObject);}}function opendoor(door:GameObject){doorisopen=true;door.GetComponent(AudioSource).PlayOneShot(door_open_sound);door.transform.parent.GetComponent(Animation).Play();}View Code4,确定碰撞对象已经添加Collider碰撞组件,规则物体(Cube)添加Box Collider,不规则物体添加Mesh Collider: 我们给Door添加Box Collider并增⼤Size Y ,⽅便碰撞操作:5,处理碰撞的时候,可以借助 print((hit.gameObject); 查看当前碰撞的对象是什么 是 Door 还是 OutPost:6,判断 hit.gameObject.tag=="playerDoor" 的时候,要保证⼤⼩写⼀致7,播放开门动画的时候,注意教程中outPost和⾃⼰项⽬中outPost的Animations的区别: 教程中的动画进⾏了分割,⽽⾃⼰项⽬中的动画没有,所以我们只播放⼀次:door.transform.parent.GetComponent(Animation).Play(); ------8,5.x版本中的播放⽅法:door.GetComponent(AudioSource).PlayOneShot(door_open_sound);9,碰撞开门,播放声⾳的JS代码,添加到第⼀⼈称后,即可实现碰撞开门、播放开门声⾳:#pragma strictvar door_open_time:float=3.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;private var doorisopen:boolean=false;private var doortimer:float=0.0;private var currentdoor:GameObject;function OnControllerColliderHit(hit:ControllerColliderHit){print(hit.gameObject);if (hit.gameObject.tag=="playerDoor" && doorisopen==false) {opendoor(hit.gameObject);}}function opendoor(door:GameObject){doorisopen=true;door.GetComponent(AudioSource).PlayOneShot(door_open_sound);door.transform.parent.GetComponent(Animation).Play();}View Code10,加⼊关门⽅法,3秒后再次播放动画:#pragma strictvar door_open_time:float=3.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;private var doorisopen:boolean=false;private var doortimer:float=0.0;private var currentdoor:GameObject;private var currentDoor:GameObject;function Start(){}function Update(){//如果门打开,开始计时超过3秒后再吃执⾏动画,并把开门时间重置为0if(doorisopen==true){doortimer+=Time.deltaTime;print(doortimer);if(doortimer>door_open_time){doortimer=0;shutdoor(currentDoor);}}}//检测碰撞function OnControllerColliderHit(hit:ControllerColliderHit){print(hit.gameObject);if (hit.gameObject.tag=="playerDoor" && doorisopen==false) {currentDoor=hit.gameObject;opendoor(hit.gameObject);}}////开门function opendoor(door:GameObject){doorisopen=true;door.GetComponent(AudioSource).PlayOneShot(door_open_sound);door.transform.parent.GetComponent(Animation).Play();}// 关门function shutdoor(door:GameObject){doorisopen=false;door.GetComponent(AudioSource).PlayOneShot(door_shut_sound);door.transform.parent.GetComponent(Animation).Play();}View Code11,整合开门、关门⽅法:#pragma strictvar door_open_time:float=3.0;var door_open_sound:AudioClip;var door_shut_sound:AudioClip;private var doorisopen:boolean=false;private var doortimer:float=0.0;private var currentdoor:GameObject;private var currentDoor:GameObject;function Start(){}function Update(){//如果门打开,开始计时超过3秒后再吃执⾏动画,并把开门时间重置为0if(doorisopen==true){doortimer+=Time.deltaTime;print(doortimer);if(doortimer>door_open_time){doortimer=0;//shutdoor(currentDoor);door(currentDoor,false,door_shut_sound,"closedoor");}}}//检测碰撞function OnControllerColliderHit(hit:ControllerColliderHit){print(hit.gameObject);if (hit.gameObject.tag=="playerDoor" && doorisopen==false) {currentDoor=hit.gameObject;//opendoor(hit.gameObject);door(currentDoor,true,door_open_sound,"opendoor");}}//对象,门的状态,播放的声⾳,播放的对象function door(thisDoor:GameObject,doorOpenOrClose:boolean,audio_clip:AudioClip,ani_name:String){ doorisopen=doorOpenOrClose;thisDoor.GetComponent(AudioSource).PlayOneShot(audio_clip);thisDoor.transform.parent.GetComponent(Animation).Play(); //播放动画区分开门和关门}View Code。

碰撞检测

碰撞检测

二维碰撞检测算法碰撞检测(Collision Detection,CD)也称为干涉检测或者接触检测,用来检测不同对象之间是否发生了碰撞,它是计算机动画、系统仿真、计算机图形学、计算几何、机器人学、CAD\ CAM等研究领域的经典问题。

碰撞物体可以分为两类:面模型和体模型。

面模型是采用边界来表示物体,而体模型则是使用体元表示物体。

面模型又可根据碰撞后物体是否发生形变分为刚体和软体,刚体本身又可根据生成方式的不同分为曲面模型和非曲面模型。

目前对于碰撞的研究多集中于面模型的研究,因为体模型是一种三维描述方式,对它进行碰撞检测代价较高。

而在面模型的研究中,对刚体的研究技术更为成熟。

下面列举几种常用的碰撞检测技术:1:包围盒(bounding box)是由Clark提出的,基本思想是使用简单的几何形体包围虚拟场景中复杂的几何物体,当对两个物体进行碰撞检测时,首先检查两个物体最外层的包围盒是否相交,若不相交,则说明两个物体没有发生碰撞,否则再对两个物体进行检测。

基于这个原理,包围盒适合对远距离物体的碰撞检测,若距离很近,其物体之间的包围盒很容易相交,会产生大量的二次检测,这样就增大了计算量。

包围盒的类型主要有AABB(Aligned Axis Bounding Box)沿坐标轴的包围盒、包围球、OBB(Oriented Bounding Box)方向包围盒和k-DOP(k Discrete Orientation Polytopes)离散方向多面体等。

AABB是包含几何对象且各边平行于坐标轴的最小六面体,两个AABB包围盒相交当且仅当它们三个坐标轴上的投影均重叠,只要存在一个方向上的投影不重叠,那么它们就不相交。

AABB间的相交测试和包围体的更新速度比其他算法效率高,因此使用最广泛,尤其适用于多物体运动的大规模环境和变形体碰撞检测。

OBB包围盒的相交测试基于分离轴的理论的,它的构造关键在于包围盒最佳方向的确定,最佳方向必须保证在该方向上包围盒的尺寸最小。

unity碰撞检测的基本方法、原理与实现例子

unity碰撞检测的基本方法、原理与实现例子

unity碰撞检测的基本方法、原理与实现在Unity中,实现碰撞检测有多种基本方法,但最常见的是使用Unity的物理引擎。

Unity的物理引擎使用一种叫做碰撞器(Collider)的组件来检测碰撞。

以下是一些基本步骤和原理:1.创建碰撞器:Unity提供了几种不同类型的碰撞器,如Box Collider, SphereCollider, Capsule Collider等。

你可以根据你的游戏对象形状来选择适合的碰撞器。

要添加碰撞器,首先需要在Unity的Inspector窗口中给你的游戏对象添加一个碰撞器组件。

2.启用碰撞:默认情况下,Unity的物理引擎是开启的,所以你的游戏对象在添加了碰撞器之后就会自动开始检测碰撞。

但是你需要在Unity的Physics或者Character Control面板中设置你的游戏对象为"Rigidbody",这样你的游戏对象才会在物理引擎的控制下移动和旋转。

3.碰撞事件:当两个带有碰撞器的游戏对象发生碰撞时,Unity会触发一个"OnCollisionEnter"事件。

你可以在这个事件中编写代码来处理碰撞发生后的行为。

例如,你可能希望在两个游戏对象碰撞时播放一段动画或者改变游戏对象的颜色。

4.碰撞材料:Unity的物理引擎还支持"Material"的概念。

你可以通过改变碰撞器或者游戏对象的"Material"来改变它们碰撞时的行为。

例如,你可以将两个游戏对象的"Material"设置为相同的"Material",这样它们在碰撞时就会发生粘性效果,而不是完全弹开。

以下是一个简单的示例脚本,当两个游戏对象发生碰撞时,会打印一条消息:在这个脚本中,当名为"Target"的游戏对象与任何带有该脚本的游戏对象发生碰撞时,都会在控制台中打印一条消息。

unity碰撞检测的公式

unity碰撞检测的公式

unity碰撞检测的公式Unity中的碰撞检测是通过使用物理引擎来实现的,主要有两种方法:碰撞器和物理材质。

碰撞器是一种组件,可以附加在游戏对象上,用于检测碰撞。

物理材质则用于定义物体的物理属性,例如摩擦力和弹性系数。

下面将详细介绍Unity中碰撞检测的公式。

1.碰撞器Unity中常用的碰撞器有四种:盒子碰撞器(Box Collider)、球形碰撞器(Sphere Collider)、胶囊碰撞器(Capsule Collider)和网格碰撞器(Mesh Collider)。

不同的碰撞器会使用不同的检测公式。

- 盒子碰撞器(Box Collider)盒子碰撞器用于检测具有四个相等正面的盒子形状的物体之间的碰撞。

碰撞器的位置和大小可以通过修改中心(center)属性和尺寸(size)属性来进行调整。

碰撞器的公式可以简化为使用点是否位于盒子的边界上进行判断。

- 球形碰撞器(Sphere Collider)球形碰撞器用于检测球形物体之间的碰撞。

碰撞器的位置和半径可以通过修改中心(center)属性和半径(radius)属性来进行调整。

碰撞器的公式可以简化为检查两个球心之间的距离是否小于等于两个球的半径之和。

- 胶囊碰撞器(Capsule Collider)胶囊碰撞器用于检测具有两个球形端点和一个连接两个球形端点的圆柱体的物体之间的碰撞。

碰撞器的位置、高度和半径可以通过修改中心(center)属性、高度(height)属性和半径(radius)属性来进行调整。

碰撞器的公式可以简化为通过检查两个球形端点以及两个球以及圆柱体之间的距离来进行判断。

- 网格碰撞器(Mesh Collider)网格碰撞器用于检测基于网格的物体之间的碰撞,例如复杂的模型或地形。

该碰撞器的形状和大小与物体的实际网格形状和大小完全一致。

碰撞器的公式通常使用边缘检测算法(例如GJK算法或SAT算法)来进行检测。

2.物理材质Unity中的物理材质被用于定义物体的物理属性,例如摩擦力和弹性系数。

第五十八讲碰撞检测:射线碰撞检测

第五十八讲碰撞检测:射线碰撞检测

第五十八讲碰撞检测:射线碰撞检测第五十八讲碰撞检测:射线碰撞检测在前面的刚体结构中我们介绍,刚体与刚体、刚体与碰撞器之间的碰撞。

这些碰撞都有一些共同的特点是碰撞的物体之间发生实际的接触。

在unity中还提供了一种射线检测的方式。

使用此种方式我们可以使用一条看不见的具有一定长度的射线来检测是否与其他的碰撞器之间发生了接触,此种功能的实现是通过物理类中的raycast函数来实现的。

类函数中我们可以使用raycast来发射一条射线来检测是否与其他的碰撞器发生了碰撞。

在函数中我们可以设置函数的起点射线的方向以及射线的长度及选择性的设置拒绝用碰撞器发生碰撞等来进行碰撞检测。

此种多运用于多种典型的情景中,例如在射击类游戏中我们不会去实际的检测子弹是否与某些物体发生了碰撞而是通过发射射线的方式来检测子弹是否击中了某些物体,并以此来做出反应。

例如在此场景中控制器物体是否与某物体发生了碰撞,在第一人称中心物体发出一条射线,然后在不进行接触的情况下我们就可以检测其物体是否与其他物体发生了碰撞。

我们可以新建一个脚本命名此脚本为rayCheck。

在脚本编辑器中打开,然后我们可以在脚本中添加射线检测的功能。

我们首页要声明一个变量hit,其类型为RayCastHit。

此变量用于存储射线碰到了哪些物体,并把其信息保存在当中。

我们使用一个if 语句,如果接触到某些物体就会返回为真。

代码如图所示:我们可以看下我们的脚本中是否存在错误,在底部的控制栏中是否还有错误信息。

然后我们在场景中创建一个Cube物体,在Cube物体中BoxCollider这样我们就可以检测我们的射线是否碰撞了我们的盒子物体。

我们可以对盒子物体进行缩放并调整其位置,然后我们需要拖动其脚本到第一人称角色控制器物体中。

因为在脚本中我们引用的是第一人称角色控制器物体的位置,也就是射线的发出位置。

可以看见我们的脚本显示在控制器中。

然后播放场景我们回到盒子的位置,注意当我们的射线只要碰到了盒子物体,我们可以看到在底部的控制信息栏中就会显示相应的输出信息。

碰撞检测技术

碰撞检测技术
❖ 服装参数化设计中的碰撞检 测属于
碰撞检测存在的问题
❖ 如何在很高的实时交互要求下完成对大量复杂物体的碰撞检测? ❖ 如何降低算法的复杂度? ❖ 如何准确的获取到有意义的接触信息用于处理碰撞检测? ❖ 软体对象间的实时碰撞检测和进一步提高算法效率,仍有待进
影响碰撞检测的要素
❖ 实时性 虚拟环境中通常包含大量物体,加上物体的形状复杂,检测这 些物体间的碰撞情况是一项非常耗时的工作,另外虚拟现实要 求系统能够实现与用户交互,这不仅要求实现实时绘制,而且 要实时地进行碰撞检测,表现出碰撞后的变化。
影响碰撞检测的要素
❖ 精确度 是采用近似检测还是精确检测取决于具体的应用。
碰撞检测的方法
❖ 包围盒层次法 该算法的基本思路是用一个简单的包围盒将复杂的几何形体围 住,当对两个物体碰撞检测时,首先检查两者的包围盒是否相 交,若不相交,则说明两个物体未相交,否则再进一步对两个 物体作检测,因为求 包围盒的交比求物体 的交简单的多,所以 可以快速排除很多不 相交的物体,从而加 速了算法。
碰撞检测技术
—XXXXX
2012.02.26
主要内容
31
碰撞检测的概述
2
影响碰撞检测的要素
3
碰撞检测的方法
4
碰撞检测的实例应用
53
碰撞检测存在的问题
碰撞检测的概述
❖ 在计算机辅助设计与制造(CAD/CAM)、计算几何、机器 人和自动化、工程分析、计算机图形学、虚拟现实等领域都遇 到了有关碰撞检测的问题,甚至成为其中的关键问题。
碰撞检测的方法
❖ 距离跟踪法 该算法通过寻找和跟踪两个多面体之间的最近点来计算它们之 间的距离,显然当距离小于或等于零时,两者就发生了碰撞。
碰撞检测的应用实例

Unity3D中的碰撞检测

Unity3D中的碰撞检测

很多时候,当我们的主角与其他GameObject发生碰撞时,我们需要做一些特殊的事情,比如:子弹击中敌人,敌人就得执行一系列的动作。

这时,我们就需要检测到碰撞现象,即碰撞检测。

这一篇,我来具体谈谈自己所了解的碰撞检测,希望高手不佞赐教。

测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。

这两种方式的应用非常广泛。

为了完整的了解这两种方式,我们必须理解以下概念:(一)碰撞器是一群组件,它包含了很多种类,比如:Box Collider,Capsule Collider 等,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。

(二)所谓触发器,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。

(三)在Unity3d中,主要有以下接口函数来处理这两种碰撞检测:触发信息检测:1.MonoBehaviour.On Trigge rEnter( Collider other )当进入触发器2.MonoBehaviour.OnTriggerExit( Collider other )当退出触发器3.MonoBehaviour.OnTriggerStay( Collider other )当逗留触发器碰撞信息检测:1.MonoBehaviour.On Collision Enter( Collision collisionInfo ) 当进入碰撞器2.MonoBehaviour.OnCollisionExit( Collision collisionInfo ) 当退出碰撞器3.MonoBehaviour.OnCollisionStay( Collision collisionInfo ) 当逗留碰撞器以上这六个接口都是MonoBehaviour的函数,由于我们新建的脚本都继承这个MonoBehaviour这个类。

所以我们的脚本里面可以覆写这六个函数。

下面让我举一个例子来详细讲解这几个函数的作用:首先,我们在这个工程中新建一个场景,取名为:TestCollision。

【Unity入门】碰撞检测与触发检测

【Unity入门】碰撞检测与触发检测

【Unity⼊门】碰撞检测与触发检测版权声明:本⽂为博主原创⽂章,转载请注明出处。

在Unity⾥⾯,游戏物体的碰撞我们可以通过刚体组件(Rigidbody)和碰撞器组件(Collider)来进⾏检测。

⾸先在场景⾥⾯添加⼀个Plane⾯板作为地⾯,然后在Plane⾯板的上⽅⼀定⾼度处放⼀个Cube⽴⽅体。

然后给Cube⽴⽅体添加⼀个刚体组件(Rigidbody)。

运⾏游戏,这时候我们可以看到⽴⽅体掉在了⾯板上⾯。

⽴⽅体和⾯板产⽣了碰撞,并且静⽌在⾯板上,这时候我们可以可以通过脚本来进⾏检测,⽐如⽴⽅体掉在⾯板上的时候我们可以将其销毁。

给⽴⽅体添加⼀个检测碰撞的脚本组件CubeCollision,语⾔使⽤C#。

代码如下:1/**2 * Copyright (c) Clarence Zeng Binsi3 *4 * Author: ZengBinsi5 * Date: 2016/01/25 16:10:286 * Desc: Collision test7*/89101112using UnityEngine;13using System.Collections;1415public class CubeCollision : MonoBehaviour {161718// Use this for initialization19void Start () {2021 }2223// Update is called once per frame24void Update () {2526 }2728293031// 碰撞开始32void OnCollisionEnter(Collision collision) {33// 销毁当前游戏物体34 Destroy(this.gameObject);35 }3637// 碰撞结束38void OnCollisionExit(Collision collision) {3940 }4142// 碰撞持续中43void OnCollisionStay(Collision collision) {4445 }4647 } 在MonoBehaviour类中,OnCollisionEnter、OnCollisionExit和OnCollisionStay是碰撞时的回调⽅法,我们可以在CubeCollision类中重载它们。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Unity 中的碰撞检测方法
碰撞检测技术是游戏和虚拟现实中最核心、最基本的技术。

碰撞检测技术在游戏和虚拟现实场景中非常重要,它保证了真实世界的正确虚拟化。

例如对于角色的控制欲规划,碰撞检测可以帮助角色避开场景中出现的障碍物。

为使用户在虚拟场景中能够感受到自己确实在场景中,就需要能够实时地检测角色与障碍物之间的碰撞检测,并及时作出响应。

然而在一个场景中,可能存在许多种不同类型的碰撞,这就要求有不同的碰撞检测方法来适应各种类型的碰撞。

目前,在虚拟现实技术中出现了很多种碰撞检测方法,其目的无非有3个:
检测模型之间是否发生碰撞;
预测即将发生的碰撞;
动态获取模型之间的距离。

在Unity 中主要有3种碰撞检测方法与上面的3个模型对应,分别是基本碰撞检测、触发器碰撞检测和光线投射。

无论是PC 端还是移动应用端,碰撞检测技术始终是程序开发的难点,甚至可以用碰撞检测技术作为衡量引擎是否完善的标准。

好的碰撞检测技术要求对象在场景中可以平滑移动,同时还要满足精确性和稳定性,防止对象在特殊情况下发生违背常规的状况。

例如,人物无缘无故被卡住不能前进,或者人物穿越了障碍物。

目前,引擎Unity ,其功能非常强大,集成了强大的碰撞检测功能,其中一个显著特点就是跨平台游戏开发。

碰撞检测方法
碰撞检测定义
碰撞的发生无非是检测两个物体对象之间的物理接触,在Unity 中是使用碰撞器组件覆盖在物体表面,用来负责与其它物体之间的碰撞。

这种从其它碰撞器检测和取得碰撞信息的方法称为碰撞检测。

Unity 碰撞检测方法分类
在Unity 中,可以检测两个物体之间的碰撞,也可以检测特定碰撞器之间的碰撞,甚至可以使用光线投射预先检测碰撞。

本文以一个角色与3D 物体的碰撞为例说明这3种碰撞方法的不同。

基本碰撞检测
在Unity 中,要实现碰撞检测,就必须给每个对象添加相应的碰撞器。

默认情况下,Unity 会自动将碰撞器添加到创建的对象中,当然也可以自己添加碰撞器。

判断角色是否和其它物体发生碰撞,可以使用Unity的角色控制碰撞器。

Unity 专门有一个方法OnControllerColliderHit用来检测角色控制器和其它物体之间的碰撞,只需要将包含OnControllerColliderHit 的脚本绑定到角色控制器即可。

function OnControllerColliderHit (hit : ControllerColliderHit){
//碰撞发生后的动作

其中,hit 是一个ControllerColliderHit 类型变量,包含着碰撞发生时所有产生的信息。

通过hit 变量,可以获知角色和哪一个物体发生了碰撞。

通过记录碰撞时所产生的信息,角色可以做出真实的反应。

虽然系统提供的OnControllerColliderHit 方法得以很好地利用,但该方法具有一定的局限性。

如玩家要通过一扇门进入屋内,使用上面的碰撞技术玩家会突然碰到门,然后门才缓缓打开,角色在门打开之前停下移动的脚步,这瞬间的停顿将会影响游戏的可玩性。

触发器碰撞检测
触发器碰撞检测很好地解决了上面描述的问题,指定一个处于触发状态的碰撞器,将实际检测碰撞对象包含进该触发器中。

这样,角色与对象的碰撞检测就转换为角色与触发器之间的碰撞检测。

只要增大触发器的范围,就能解决玩家和门之间出现的停顿问题。

触发器碰撞原理如下图所示。

使用触发器碰撞,需要使用两个碰撞器,一个是依附在门上的碰撞器,一个是稍微比门大点并包含门的触发器。

如上图所示,只要角色进入触发器范围,就能通过脚本代码提前让门打开,从而消除角色与门因碰撞产生的停顿感。

function OnTriggerEnter(collider :Collider){
//进入触发器后对应的动作

光线投射
光线投射是3D 场景中一个点向一个方向发射的一条无终点的线。

在发射过程中,一旦与其它对象发射碰撞,它将停止发射。

在Unity 中可以利用光线投射实现碰撞检测,即在角色所面对的方向投射出一条光线,在设定的光线长度内实现碰撞检测。

这意味着,角色靠近门时,角色不需要和门进行接触就可以实现碰撞检测。

光线投射原理如下图所示。

光线投射为了实现碰撞检测必须让光线和碰撞对象相交,也即,角色必须面对门的方向。

当角色与门的距离小于设定的光线长度时,就可判断两者发生碰撞。

示例代码如下:
function Update(){
//光线投射碰撞发生
if (Phisics .Raycast (transform .position , transform .forward
,hit ,distance)){
//碰撞后的动作


其中distance 表示光线的距离,只有当角色和门小于distance 时才会被检测到碰撞。

光线投射的缺点是角色必须面对门的方向,尽管光线投射存在缺点,但它经常被用来预测碰撞检测。

Unity 碰撞检测方法比较及应用
在所分析的示例中,基本碰撞检测和光线投射方法都存在着缺陷,使用基本碰撞检测时,只有角色碰撞到门上时门才会打开,造成角色停顿感,影响交互性;使用光线投射时,虽然能让门提前打开,消除停顿感,但是只有当角色正对着门的时候,门才会开启。

使用触发器碰撞检测是最适合的方法,它很好地解决了基本碰撞检测带来的停顿感和光线投射带来的方向限制。

基本碰撞检测虽然简单易用,但它不适合复杂的碰撞检测。

碰撞对象之间必须真实发生碰撞,而且检测代码被放入一个脚本中,不利于维护。

基本碰撞检测适合处理场景中简单的碰撞检测,如角色与石头、河流等的简单碰撞。

光线投射由于受到射线方向的限制,因此常用来检测高速运动的对象之间的碰撞,如射击游戏中子弹与人物之间的碰撞。

触发器碰撞检测需要增加一个触发碰撞器来替换碰撞对象,它适合于有预设动作的场景。

相关文档
最新文档