快捷导航
网站首页
疑难问答
Foreign
手游源码
端游源码
页游源码
手游单机
开启辅助访问
登录
or
注册
永久会员提供整站资源下载
游戏源码
»
源码论坛 BBS
›
游戏引擎
›
游戏引擎资源/文档
›
Unity3d综合教程
›
【飞机大战】开发手记(四)碰撞检测
1
2
3
4
5
6
7
8
9
10
... 19
/ 19 页
下一页
返回列表
查看:
66624
|
回复:
185
【飞机大战】开发手记(四)碰撞检测
[复制链接]
admin
admin
当前离线
积分
75866
1
主题
342
帖子
7万
积分
管理员
积分
75866
发消息
发表于 2014-9-4 05:05:31
|
显示全部楼层
|
阅读模式
虽然有了子弹和敌我双方飞机,但它们好像存在平行世界里一样没有交集。这个时候就需要做碰撞检测了,在《飞机大战》游戏中一共有三种碰撞关系需要检测:
敌方机体和我方机体碰撞,我方机体受到伤害。
导弹和敌方机体碰撞,敌方机体受到伤害。
我方机体和道具碰撞,触发相应的道具效果。
本篇暂时只做前两条的碰撞检测,剩下的原理是一样的,一并放到后面的道具篇里记录。
在开始之前需要做些准备工作,因为在
unity
中,父对象是无法获知子对象的碰撞事件的,所以需要用一个碰撞事件分发器来发布碰撞事件消息。在游戏开始时,父对象上的脚本遍历并订阅所有子对象上的碰撞事件。当子对象发生碰撞时,父对象就可以针对相应的事件进行处理。
namespace Frederick.ProjectAircraft
{
using UnityEngine;
/// <summary>
/// 碰撞事件分发器。
/// </summary>
public class CollisionEventDispatcher : MonoBehaviour
{
/// <summary>
/// 碰撞事件处理器。
/// </summary>
///碰撞信息
public delegate void CollisionEventHandler(Collision collision);
/// <summary>
/// 触发器碰撞事件处理器。
/// </summary>
///发送事件的游戏对象
///触发事件的另外一个碰撞器
public delegate void TriggerEventHandler(GameObject sender, Collider other);
/// <summary>
/// 当有触发器进入时候触发此事件。
/// </summary>
public event TriggerEventHandler TriggerEntered;
protected void OnTriggerEnter(Collider other)
{
if (TriggerEntered != null)
TriggerEntered(gameObject, other);
}
}
}
飞机的子对象只需要保持对父对象的引用就可以了,由于需要做碰撞检测,所以还需要加上对刚体组件的要求(Rigidbody)。
namespace Frederick.ProjectAircraft
{
using UnityEngine;
/// <summary>
/// 飞机的一部分。
/// </summary>
[RequireComponent(typeof (CollisionEventDispatcher))]
[RequireComponent(typeof (Rigidbody))]
public class AircraftPart : MonoBehaviour
{
/// <summary>
/// 获取或设置所属的飞机对象。
/// </summary>
public Aircraft Aircraft { get; set; }
}
}
飞机的父对象在启动时获取所有子部件,并订阅其碰撞事件,统一到OnPartTriggerEnter这个虚方法里处理。这样就可以在子类中重写碰撞逻辑了。
namespace Frederick.ProjectAircraft
{
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 飞机。
/// </summary>
public class Aircraft : MonoBehaviour
{
/// <summary>
/// 获取飞机所有的部分。
/// </summary>
public IEnumerable<AircraftPart> Parts
{
get { return mParts.AsReadOnly(); }
}
protected virtual void Awake()
{
var self = GetComponent<AircraftPart>();
var children = GetComponentsInChildren<AircraftPart>();
if (self != null)
mParts.Add(self);
mParts.AddRange(children);
foreach (var part in mParts)
{
part.Aircraft = this;
var dispatcher = part.GetComponent<CollisionEventDispatcher>();
dispatcher.TriggerEntered += OnPartTriggerEnter;
}
}
protected virtual void OnDestroy()
{
foreach (var part in mParts)
{
part.Aircraft = null;
var dispatcher = part.GetComponent<CollisionEventDispatcher>();
dispatcher.TriggerEntered -= OnPartTriggerEnter;
}
}
/// <summary>
/// 当飞机的一部分触发碰撞时调用此方法。
/// </summary>
/// <param name="part碰撞的部分</param>
/// <param name="other碰撞的碰撞器</param>
protected virtual void OnPartTriggerEnter(GameObject part, Collider other)
{
Debug.Log(string.Format("OnPartTriggerEnter:part={0} other={1}", part.transform.parent.name, other.transform.parent.name));
}
private readonly List<AircraftPart> mParts = new List<AircraftPart>();
}
}
将Aircraft脚本分别附加到我方飞机和敌方飞机的Body上,点击运行游戏,此时敌方飞机还没有移动的逻辑,所以在场景视图中手动拖动到我方飞机上。在控制台中会立即打印出碰撞调试信息。
以上是从飞机机体的角度进行碰撞检测,下面为导弹和机体之间增加碰撞检测。 选中敌方机体的Body,并在检视面板中设置标记(Tag)为Enemy。由于这个标记是自定义的,所以首先需要点击“增加标记(Add Tag...)”在标记管理器面板(Tag Manager)中新增。设置成功后别忘了还要把预设Apply一下,将标记应用到其他敌方机体上。
接下来就可以修改Missile脚本,在导弹中进行碰撞检测了。
namespace Frederick.ProjectAircraft
{
using UnityEngine;
/// <summary>
/// 导弹。
/// </summary>
[RequireComponent(typeof (BoxCollider))]
public class Missile : MonoBehaviour
{
public float StantardSpeed = 800;
protected void Awake()
{
mTransform = transform;
}
protected void OnTriggerEnter(Collider other)
{
if (other.tag != "Enemy")
return;
var part = other.GetComponent<AircraftPart>();
Debug.Log(string.Format("{0} hit!", part.Aircraft.name));
}
protected void Update()
{
var position = mTransform.localPosition + mDirection * StantardSpeed * Time.deltaTime;
if (position.y > 960)
{
Destroy(gameObject);
return;
}
mTransform.localPosition = position;
}
private readonly Vector3 mDirection = Vector3.up;
private Transform mTransform;
}
}
点击运行游戏,此时当导弹与敌机碰撞后,导弹就会销毁,并打印出命中的调试信息了。那么下一篇就准备将之前的调试信息删除,然后换上生命和伤害计算的逻辑吧。
unity3D教程飞机大战
相关帖子
?
【飞机大战】开发手记(一)精灵和动画
?
【飞机大战】开发手记(二)飞机移动控制
?
【飞机大战】开发手记(三)导弹发射控制
?
【飞机大战】开发手记(五)生命与伤害
?
【飞机大战】开发手记(六)爆炸与声音
回复
使用道具
举报
fgutrhdp2y
该用户已被删除
发表于 2014-12-28 03:05:48
|
显示全部楼层
提示:
作者被禁止或删除 内容自动屏蔽
回复
支持
反对
使用道具
举报
共和国凤凰台
共和国凤凰台
当前离线
积分
3852
0
主题
1199
帖子
3852
积分
vip会员
vip会员, 积分 3852, 距离下一级还需 6148 积分
vip会员, 积分 3852, 距离下一级还需 6148 积分
积分
3852
发消息
发表于 2015-4-6 17:04:56
来自手机
|
显示全部楼层
锄禾日当午,发帖真辛苦。谁知坛中餐,帖帖皆辛苦!
回复
支持
反对
使用道具
举报
追忆似水年华
该用户已被删除
发表于 2015-4-10 13:33:17
来自手机
|
显示全部楼层
提示:
作者被禁止或删除 内容自动屏蔽
回复
支持
反对
使用道具
举报
天亦有情
该用户已被删除
发表于 2015-4-11 00:03:26
来自手机
|
显示全部楼层
提示:
作者被禁止或删除 内容自动屏蔽
回复
支持
反对
使用道具
举报
东方故事
东方故事
当前离线
积分
4023
0
主题
1289
帖子
4023
积分
vip会员
vip会员, 积分 4023, 距离下一级还需 5977 积分
vip会员, 积分 4023, 距离下一级还需 5977 积分
积分
4023
发消息
发表于 2015-4-11 10:06:18
来自手机
|
显示全部楼层
确实不错,顶先
回复
支持
反对
使用道具
举报
舒服的
舒服的
当前离线
积分
3897
0
主题
1240
帖子
3897
积分
vip会员
vip会员, 积分 3897, 距离下一级还需 6103 积分
vip会员, 积分 3897, 距离下一级还需 6103 积分
积分
3897
发消息
发表于 2015-4-12 00:35:05
来自手机
|
显示全部楼层
支持,这个很稀有的说
回复
支持
反对
使用道具
举报
个对方过后
个对方过后
当前离线
积分
4057
0
主题
1273
帖子
4057
积分
vip会员
vip会员, 积分 4057, 距离下一级还需 5943 积分
vip会员, 积分 4057, 距离下一级还需 5943 积分
积分
4057
发消息
发表于 2015-4-12 13:27:19
来自手机
|
显示全部楼层
有空一起交流一下
回复
支持
反对
使用道具
举报
海豚的心事
该用户已被删除
发表于 2015-4-14 14:45:55
来自手机
|
显示全部楼层
提示:
作者被禁止或删除 内容自动屏蔽
回复
支持
反对
使用道具
举报
神话
该用户已被删除
发表于 2015-4-16 16:02:48
来自手机
|
显示全部楼层
提示:
作者被禁止或删除 内容自动屏蔽
回复
支持
反对
使用道具
举报
1
2
3
4
5
6
7
8
9
10
... 19
/ 19 页
下一页
返回列表
*
滑块验证:
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
enginedx注册
本版积分规则
发表回复
回帖后跳转到最后一页
邮件留言:
游戏源码
返回顶部