Unity3D AI角色移动和自动跟随
2015-12-15 11:58
543 查看
AI角色按照一定的移动逻辑进行移动时,AI逻辑处理角色需要移动的位置,还需要移动逻辑实时处理角色的当前速度和角度。官方的示例中角色的移动是通过设置速度之后,依靠动画的位移来实现的,所以代码中只需要设置角色的速度和角度即可。Animator控件中的Apply Root Motion需要勾选,这样才能使用动画中的位移,而不需要在代码中更新角色坐标,勾选之后也不能通过代码更新了。
其中的nav是绑定在角色身上的navMeshAgent。deadZone是忽略区间,当实际角度和目标角度的差值在忽略区间内时就不再改变方向了,这样可以避免走曲线。
这里的normal法向量,叉乘和点乘是为了确定角度的正负。
animSetup.Setup()中的方法主要是:
anim.SetFloat(“Speed”,0,speedDampTime,Time.deltaTime);
anim.SetFloat(“AnglarSpeed”, angleRad,anglarSpeedDampTime,Time.deltaTime);
这两个方法会渐变的设置参数,也就会有一个加速的过程,不会显得突兀。
navMeshAgent的作用是给定一个位置可以告诉我们该怎么走,但是具体怎么走过去,速度,方向的设置还是需要我们自己来设置的,就像一个复杂的A星算法一样。
有时候会有一些自动跟随的需要,比如宠物跟着主角走,思路就是将主角的空间位置设置为移动目标,通过update里的迭代去接近目标,朝向也是同样处理,朝向上的接近使用:Quaternion.Slerp(self.transform.rotation, target.transform.rotation, Time.deltaTime * dirSpeed);
移动上的接近使用:Vector3.MoveTowards(self.transform.position, target.transform.position, Time.deltaTime * moveSpeed);
如果要让跟随更自然一些,可以在主角移动,每次转向的时候传给宠物一个目标,宠物按顺序将这些目标位置存放在一个列表里,按照列表里的顺序移动,就像重走了一遍主角的路线一样。
其中的nav是绑定在角色身上的navMeshAgent。deadZone是忽略区间,当实际角度和目标角度的差值在忽略区间内时就不再改变方向了,这样可以避免走曲线。
这里的normal法向量,叉乘和点乘是为了确定角度的正负。
animSetup.Setup()中的方法主要是:
anim.SetFloat(“Speed”,0,speedDampTime,Time.deltaTime);
anim.SetFloat(“AnglarSpeed”, angleRad,anglarSpeedDampTime,Time.deltaTime);
这两个方法会渐变的设置参数,也就会有一个加速的过程,不会显得突兀。
navMeshAgent的作用是给定一个位置可以告诉我们该怎么走,但是具体怎么走过去,速度,方向的设置还是需要我们自己来设置的,就像一个复杂的A星算法一样。
有时候会有一些自动跟随的需要,比如宠物跟着主角走,思路就是将主角的空间位置设置为移动目标,通过update里的迭代去接近目标,朝向也是同样处理,朝向上的接近使用:Quaternion.Slerp(self.transform.rotation, target.transform.rotation, Time.deltaTime * dirSpeed);
移动上的接近使用:Vector3.MoveTowards(self.transform.position, target.transform.position, Time.deltaTime * moveSpeed);
如果要让跟随更自然一些,可以在主角移动,每次转向的时候传给宠物一个目标,宠物按顺序将这些目标位置存放在一个列表里,按照列表里的顺序移动,就像重走了一遍主角的路线一样。
代码块
宠物跟随示例,这里仅展示下大致方法:using UnityEngine; public class PetMovement : BaseMovement { void Update() { Player ownerPlayer = pet.OwnerPlayer; GameObject target = GetTarget(ownerPlayer ); if (target != null) { float distance = Vector3.Distance(transform.position, target.transform.position); PetInfo petInfo = GetPetInfo(pet.ID); var dir = target.transform.position - transform.position; int skillRange = petInfo.skillRange; if (skillRange < distance) // 当和主人之间的距离超过技能距离时跟随 { Action.ChangeAction(CAction.RunFront);// 改变动画 var destPos = transform.position + dir.normalized * (distance - skillRange + 1); transform.position = Vector3.MoveTowards(transform.position, destPos, Time.deltaTime * move_Speed); } var rotation = Quaternion.LookRotation(dir); // 获得 目标方向 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5); // 差值 宠物朝向趋向目标 return; } } }
相关文章推荐
- Unity Sprite切割导出
- Unity3D 巡逻敌兵探测玩家逻辑实现
- Unity3D 摄像机平滑跟随角色
- Unity3D角色换装实现原理及步骤
- unity3d爬坑手记3
- 【Unity Shaders】Lighting Models —— 灯型号Lit Sphere
- 在Unity3D中使用ScriptableObject进行序列化
- unity发布程序的选项
- 使用vs调试unity脚本的方法
- Unity日志工具——封装,跳转
- Unity的Vsync Count垂直同步原理剖析
- UNITY 5.2 Quaternion 类
- unity5.x的bug
- Unity3d 配置OpenCV(EmguCV) 周围环境
- [Unity3D]脚本中Start()和Awake()的区别
- Unity3D Socket流数据大小端读写封装
- Unity3D 使用异步socket通讯
- unity, TRANSFORM_TEX
- unity, access scene ambient
- Unity3D研究院之主角面朝方向一定区域内对象角度计算(四十五)