AI运动层的一套基于加速度的基本移动方案
来源:互联网 发布:sony walkman mac 编辑:程序博客网 时间:2024/06/05 00:57
移动组件:
using UnityEngine;using System.Collections;using System.Collections.Generic;public class MoveComponent : MonoBehaviour{ #region 字段 public float maxSpeed = 10; // 最大速度 public float maxForce = 100; // 最大推力 public float mass = 1; // 对象质量 public Vector3 velocity; // 速度向量 public float damping = 0.9f; // 旋转速率 public float computeInteval = 0.2f; // 计算间隔 public float completeDisatnce = 3f; // 到达距离 private Vector3 acceleration; // 加速度 private float timer = 0; // 计时器 private Vector3 steeringForce = Vector3.zero; // 推力 private Dictionary<MoveType, MoveBase> moveDic = new Dictionary<MoveType, MoveBase>(); // 移动字典 public List<MoveType> arriveRemove = new List<MoveType>(); // 移动完成需要删除的移动 #endregion void Awake() { moveDic[MoveType.Seek] = null; moveDic[MoveType.Arrive] = null; moveDic[MoveType.Flee] = null; moveDic[MoveType.FollowPath] = null; moveDic[MoveType.Pursuit] = null; moveDic[MoveType.CollisionAvoidance] = null; } void Update() { timer += Time.deltaTime; if(timer > computeInteval) { //得到当前帧的推力 steeringForce = Vector3.zero; //遍历当前激活的移动并添加推力*权重 foreach(var v in moveDic) { if(v.Value != null) { steeringForce += v.Value.Force() * v.Value.Weight; } } //移除完成的移动 foreach (var v in arriveRemove) { moveDic[v] = null; } arriveRemove.Clear(); //限制最大力 steeringForce = Vector3.ClampMagnitude(steeringForce, maxForce); //加速度=推力/质量 acceleration = steeringForce / mass; timer = 0; } } void FixedUpdate() { //增加加速度 velocity += acceleration * Time.fixedDeltaTime; //控制最大速度 if (velocity.sqrMagnitude > maxSpeed * maxSpeed) velocity = velocity.normalized * maxSpeed; //移动 transform.position += velocity * Time.fixedDeltaTime; //插值旋转 if(velocity.sqrMagnitude > 0.01f) { //计算当前前方到目标方向的插值 Vector3 newForward = Vector3.Slerp(transform.forward, velocity, damping * Time.fixedDeltaTime); transform.forward = newForward; } } #region 接口 public void SeekTo(Transform target) { if(moveDic[MoveType.Seek] != null) { if ((moveDic[MoveType.Seek] as MoveSeek).target == target) return; } moveDic[MoveType.Seek] = new MoveSeek(this, target); } public void ArriveTo(Transform target, float slowDistance) { if (moveDic[MoveType.Arrive] != null) { if ((moveDic[MoveType.Arrive] as MoveArrive).target == target) return; } moveDic[MoveType.Arrive] = new MoveArrive(this, target, slowDistance); } public void FleeTo(Transform target,float fearDistance) { if (moveDic[MoveType.Flee] != null) { if ((moveDic[MoveType.Flee] as MoveFlee).target == target) return; } moveDic[MoveType.Flee] = new MoveFlee(this, target, fearDistance); } public void PursuitTo(Transform target) { if(moveDic[MoveType.Pursuit] != null) { if ((moveDic[MoveType.Pursuit] as MovePursuit).target == target) return; } moveDic[MoveType.Pursuit] = new MovePursuit(this, target); } public void FollowPath(List<Transform> path) { if(moveDic[MoveType.FollowPath] != null) { if ((moveDic[MoveType.FollowPath] as MoveFllowPath).path == path) return; } moveDic[MoveType.FollowPath] = new MoveFllowPath(this, path); } public void OpenCollisionAvoidance(float seeAheadDistance) { moveDic[MoveType.CollisionAvoidance] = new MoveCollisionAvoidance(this, seeAheadDistance); } #endregion}public enum MoveType{ Seek, Arrive, Flee, Pursuit, FollowPath, CollisionAvoidance}
移动方式基类:
using UnityEngine;using System.Collections;public class MoveBase { public float Weight = 1; //移动优先级 protected Vector3 disiredVelocity; //目标速度 protected MoveComponent move; //移动脚本 public MoveBase(MoveComponent move) { this.move = move; } public virtual Vector3 Force() { return Vector3.zero; }}
靠近:
using UnityEngine;using System.Collections;public class MoveSeek : MoveBase { public Transform target; public MoveSeek(MoveComponent move, Transform target) : base(move) { this.target = target; } public override Vector3 Force() { //完成目标移除 if (Vector3.Distance(target.transform.position, move.transform.position) < move.completeDisatnce) { move.arriveRemove.Add(MoveType.Seek); move.velocity = Vector3.zero; return Vector3.zero; } //要到达的速度 disiredVelocity = (target.transform.position - move.transform.position).normalized * move.maxSpeed; //加速度:当速度=要到达的速度,加速度为0 return disiredVelocity - move.velocity; }}
缓速到达:
using UnityEngine;using System.Collections;public class MoveArrive : MoveBase { public Transform target; //减速范围 float slowDistance; public MoveArrive(MoveComponent move, Transform target, float slowDistance) : base(move) { this.target = target; this.slowDistance = slowDistance; } public override Vector3 Force() { if (Vector3.Distance(target.transform.position, move.transform.position) > move.completeDisatnce) { Vector3 toTarget = target.transform.position - move.transform.position; Vector3 returnForce; float distance = toTarget.magnitude; if (distance > slowDistance) { //目标速度 disiredVelocity = toTarget * move.maxSpeed; //加速度:当速度=要到达的速度,加速度为0 returnForce = disiredVelocity - move.velocity; } else { //当进入减速范围时 目标速度 = 长度向量-速度向量 逐渐缩小 disiredVelocity = toTarget - move.velocity; returnForce = disiredVelocity - move.velocity; } return returnForce; } else { //完成目标移除 move.arriveRemove.Add(MoveType.Arrive); move.velocity = Vector3.zero; return Vector3.zero; } }}
逃离:
using UnityEngine;using System.Collections;public class MoveFlee : MoveBase { public Transform target; float fearDistance; public MoveFlee(MoveComponent move, Transform target, float fearDistance) : base(move) { this.target = target; this.fearDistance = fearDistance; } public override Vector3 Force() { if(Vector3.Distance(move.transform.position,target.position) > fearDistance) { //完成目标移除 move.arriveRemove.Add(MoveType.Flee); move.velocity = Vector3.zero; return Vector3.zero; } //反方向加速度向量 disiredVelocity = (move.transform.position - target.position).normalized * move.maxSpeed; return disiredVelocity - move.velocity; }}
路径移动:
using UnityEngine;using System.Collections;using System.Collections.Generic;public class MoveFllowPath : MoveBase { public List<Transform> path = new List<Transform>(); private float slowDistance = 5f; private Transform target; private int index = 0; public MoveFllowPath(MoveComponent move, List<Transform> path) : base(move) { this.path = path; target = path[index]; } public override Vector3 Force() { Vector3 returnForce = Vector3.zero; Vector3 distance = target.position - move.transform.position; //最后一点 if (index == path.Count - 1) { if (Vector3.Distance(target.position, move.transform.position) < move.completeDisatnce) { //完成目标移除 move.arriveRemove.Add(MoveType.FollowPath); move.velocity = Vector3.zero; return Vector3.zero; } if (distance.magnitude > slowDistance) { disiredVelocity = distance.normalized * move.maxSpeed; } else { disiredVelocity = distance - move.velocity; } returnForce = disiredVelocity - move.velocity; } else { if(Vector3.Distance(target.position,move.transform.position) < move.completeDisatnce) { index++; target = path[index].transform; } disiredVelocity = distance.normalized * move.maxSpeed; returnForce = disiredVelocity - move.velocity; } return returnForce; }}
拦截:
using UnityEngine;using System.Collections;public class MovePursuit : MoveBase { public Transform target; public MovePursuit(MoveComponent move, Transform target) : base(move) { this.target = target; } public override Vector3 Force() { if(target.GetComponent<MoveComponent>()==null) { move.arriveRemove.Add(MoveType.Pursuit); return Vector3.zero; } if (Vector3.Distance(target.transform.position, move.transform.position) > move.completeDisatnce) { Vector3 toTarget = target.transform.position - move.transform.position; //两个对象的前方向量夹角 float relativeDirection = Vector3.Dot(move.transform.forward, target.transform.forward); //追踪向量和对象前方向量的夹角>0并且两个对象前方夹角<18 if(Vector3.Dot(toTarget,move.transform.forward) > 0 && relativeDirection < -0.95f) { //差不多在一直线上 disiredVelocity = (target.transform.position - move.transform.position).normalized * move.maxSpeed; return disiredVelocity - move.velocity; } //预期到达目标的前方位置的时间 float lookheadTime = toTarget.magnitude / (move.maxSpeed + target.GetComponent<MoveComponent>().velocity.magnitude); //预期目标位置 = 目标位置 + 目标速度*预期到达时间 disiredVelocity = (target.transform.position + target.GetComponent<MoveComponent>().velocity * lookheadTime - move.transform.position).normalized * move.maxSpeed; return disiredVelocity - move.velocity; } else { //完成目标移除 move.arriveRemove.Add(MoveType.Pursuit); move.velocity = Vector3.zero; return Vector3.zero; } }}
避障:
using UnityEngine;using System.Collections;public class MoveCollisionAvoidance : MoveBase { private float maxSeeAhead = 2.0f; public MoveCollisionAvoidance(MoveComponent move, float maxSeeAhead) : base(move) { this.maxSeeAhead = maxSeeAhead; } public override Vector3 Force() { RaycastHit hit; Vector3 returnForce = Vector3.zero; //方向:速度向量 距离:视线 * 时间 if(Physics.Raycast(move.transform.position,move.velocity,out hit,maxSeeAhead * move.velocity.magnitude /move.maxSpeed)) { //发生碰撞的视线前方向量 Vector3 ahead = move.transform.position + move.velocity * maxSeeAhead * (move.velocity.magnitude /move.maxSpeed); //用视线向量-碰撞物体的中心点 得到 碰撞物体中心指向视线向量的向量 用这个向量来偏移 returnForce = ahead - hit.collider.transform.position; returnForce *= move.maxForce; returnForce.y = 0; } return returnForce; }}
0 0
- AI运动层的一套基于加速度的基本移动方案
- 层的缓冲运动
- 基于陀螺进行运动检测的电子稳像方案
- 基于激光传感器的移动机器人动态运动检测
- 多轴运动出现加速度跳变的平滑处理
- 基于MPU6050的加速度求角度
- 一套完整的网站建设方案
- 一套系统的硬件架构方案
- 多旋翼-加速度计耦合机体运动加速度处理方案
- Android通过手机的传感器计算手机的移动加速度
- 基于VMM的寄存器抽象层验证技术和方案
- 一套基于NSPredicate的NSArray过滤框架
- 基于JQUERY的动态创建可移动层
- 基于jquery的可移动dialog 和 页面遮盖层
- 基于光流场的运动分析
- 基于帧间差法的运动检测
- 基于单目视觉的移动机器人室内定位与运动目标跟踪
- 加速度传感器的原理和应用-手机翻转、失重检测、运动检测、位置识别
- 理解函数式编程
- 在Linux中使用线程
- JQ_操作
- 从mongo数据库中导出数据的方法
- okhttp封装地址
- AI运动层的一套基于加速度的基本移动方案
- SpringMVC 前端接收ResponseBody数据例子
- HTTP之持久连接
- self
- 使用IntelliJ IDEA12创建Maven多模块项目
- codevs 3002 石子归并3 (四边形不等式优化dp)
- php 常用数组函数 array_reduce
- CreateThread的用法及在Qt等GUI开发中使用CreateThread的一些技巧
- Android (系统+自定义)短视频录制(含暂停继续录制功能) 总结