unity3d个人写的检测障碍物并避开的方法
来源:互联网 发布:mac ps2017中文破解版 编辑:程序博客网 时间:2024/04/30 18:11
虽然unity3d有自带的navigation避开障碍物,但有一次做项目时发现:当场景大而且人物变多时这个navigation计算不是很灵敏,于是心想能否自己想出另外一个检测障碍物并避开的方法。话不多说,上代码:
using UnityEngine;
using System.Collections;
public class ObstacleDetection : MonoBehaviour {
public float MoveSpeed = 2;//避开时的移动速度
public float ColliderDistance = 2;//检测距离
public string[] ObstacleTags;//障碍物的标签,就是要避开的障碍物
public bool IsObstacle{get{return _IsObstacle;}}//是否有障碍物,用来给外部的接口
private Vector3 pos;//记录避开障碍物前的的旋转坐标
private bool IsForward = false;//前方是否有障碍物
private bool IsInLeft = false;//左方是否有障碍物
private bool IsInRight = false;//右方是否有障碍物
private bool _IsObstacle = false;//是否有障碍物
private float timer = 0;//避开障碍物后返回原先状态的缓冲计时
private Transform m_transform;
// Use this for initialization
void Start () {
m_transform = this.transform;
}
// Update is called once per frame
void Update () {
MoveForward ();
Detection();
}
//当侧面有障碍物而前方没有时向前移动
void MoveForward()
{
if(_IsObstacle)
{
if(!IsForward)
{
pos = m_transform.localEulerAngles;
m_transform.Translate(Vector3.forward*Time.deltaTime*MoveSpeed);
}
}
}
//障碍物检测
#region Detection
void Detection()
{
IsForward = DirectionForward ();
IsInLeft = DirectionLeft ();
IsInRight = DirectionRight ();
if (IsForward) {
if (IsInLeft && !IsInRight)
{
float rotateAnglesY = RotateAngles (pos.y + 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
rotateAnglesY,
m_transform.localEulerAngles.z);
}
else if (!IsInLeft && IsInRight)
{
float rotateAnglesY = RotateAngles (pos.y - 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
rotateAnglesY,
m_transform.localEulerAngles.z);
}
else if (IsInLeft && IsInRight)
{
float rotateAnglesY = RotateAngles (pos.y + 180);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
rotateAnglesY,
m_transform.localEulerAngles.z);
}
else
{
float rotateAnglesY = RotateAngles (pos.y + Random_1_1 () * 90);
m_transform.localEulerAngles = new Vector3 (m_transform.localEulerAngles.x,
rotateAnglesY,
m_transform.localEulerAngles.z);
}
}
else
{
if(!IsInLeft && !IsInRight)
{
if(IsObstacle)
{
//避开障碍物到返回原先状态的缓冲时间
timer += Time.deltaTime;
if(timer > 0.8f)
{
timer = 0;
_IsObstacle = false;
}
}
}
}
}
//检测前方
bool DirectionForward()
{
bool check = false;
RaycastHit hitForward;
Vector3 LocalForward = m_transform.TransformPoint(Vector3.forward)-m_transform.position;
if (Physics.Raycast (m_transform.position,
LocalForward,
out hitForward, ColliderDistance/2))
{
if(CompareTags(hitForward.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
//检测右方
bool DirectionRight()
{
bool check = false;
RaycastHit hitRight;
Vector3 LocalRight = m_transform.TransformPoint(Vector3.right)-m_transform.position;
if (Physics.Raycast (m_transform.position,
LocalRight,
out hitRight, ColliderDistance))
{
if(CompareTags(hitRight.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
//检测左方
bool DirectionLeft()
{
bool check = false;
RaycastHit hitLeft;
Vector3 LocalLeft = m_transform.TransformPoint(-Vector3.right)-m_transform.position;
if (Physics.Raycast (m_transform.position,
LocalLeft,
out hitLeft, ColliderDistance))
{
if(CompareTags(hitLeft.transform.gameObject.tag))
{
_IsObstacle =true;
check = true;
}
}
return check;
}
#endregion
//自己写的一些小功能
#region MyFunction
//遍历ObstacleTags数组,是否与其中的一个值相符
bool CompareTags(string name)
{
bool isSame = false;
for(int i = 0; i < ObstacleTags.Length;i++)
{
if(ObstacleTags[i].Equals(name))
{
isSame = true;
break;
}
}
return isSame;
}
//将角度规范,变为0~360之间
float RotateAngles(float Angles)
{
float angles = 0;
if (Angles >= 0) {
angles = Angles - ((int)(Angles / 360)) * 360;
}
else
{
angles = (((int)(Angles / 360))+1) * 360 - Angles;
}
return angles;
}
//产生-1~1的随机数,不包括0
float Random_1_1()
{
float index = Random.Range (-1,1);
if(index == 0)
{
index = Random_1_1();
}
return index;
}
#endregion
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.forward*ColliderDistance/2));
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.right*ColliderDistance));
Gizmos.DrawLine (transform.position, transform.TransformPoint(Vector3.left*ColliderDistance));
}
}
0 0
- unity3d个人写的检测障碍物并避开的方法
- 基于视觉的障碍物检测和规避
- 避开障碍物转向
- 基于深度摄像头的障碍物检测(realsense+opencv)
- 检测图像边缘(包括障碍物的边缘,道路边缘)算法
- 基于深度摄像头的障碍物检测(realsense+opencv)
- 关于避开轮询方法的方法
- Unity3D开发技巧:如何避开unity编辑器的那些坑
- Unity20--动态的障碍物
- 个人写的分割正整数方法
- Unity3DAI行为------避开障碍物简单实现
- 移动平台上100个人复杂障碍物寻路的思考和实现(理论篇)
- 移动平台上100个人复杂障碍物寻路的思考和实现(理论篇)
- Unity3D 之OnTriggerEnter和OnCollisionEnter方法的一点个人心得
- 读论文《汽车自动驾驶汇总基于单目视觉的障碍物检测》陈存祺
- 关于Unity3d中物体之间碰撞检测的方法
- Flash避开微软新ActiveX控件升级的方法
- flash 避开微软新ActiveX控件升级的方法
- Android多线程编程
- GRUB,UEFI
- JAVA基础-01(环境搭建,配置path环境变量)
- C++基础::string
- CentOS安装Nginx
- unity3d个人写的检测障碍物并避开的方法
- 常见的dos命令
- tomcat源代码系列--请求处理过程
- HTTP协议学习(五)——代理
- 浅谈onclick与addEventListener两种添加事件方式的区别
- CF405E 挺好的爆搜题
- 项目实战 网易彩票2
- 【开发知识储备】UNIX操作系统和Linux操作系统
- poj--2935(bfs+记录路径)