当前位置:   article > 正文

Unity实现敌人沿着指定路线移动_unity 让物体按照路径点移动

unity 让物体按照路径点移动

        使用的是2D模板,但是除了增加一个Z轴的考虑,其它基本都是一样的,当然如果你的3D场景是平坦面的话几乎代码可以直接复用。

        想要让敌人沿着指定路线移动,就要规定他需要移动的路点位置。

        在这里,我采用的是建立一个空对象line,在再这个line对象底下一次插入空对象point,使用空对象的原因是因为我们只需要路点得到的位置,除非特殊需求,我们不需要其它的组件属性,为了便于观察,设置点的图标,确定敌人是否会沿着点位移动。

        接下来,关键就是如何取得这些点位的位置了,最开始我尝试使用GetComponentsInChildren<GameObject>();拿到所有的子物体,再取得所有子物体的TransForm获得位置,但是实际上这个方法不能直接拿子物体本身,所以<>中至二级选择取TransForm就可以了,之后的部分就非常简单了,见代码。

  1. //这个的理解难度相比于弹幕追踪要简单很多,实现难度也低很多,所以注释会比较少
  2. public class AI_Move_line : MonoBehaviour
  3. {
  4. public GameObject line;//线路组
  5. public Transform[] line_array;//所有路点位置的数组
  6. [Range(0, 50)]
  7. public float speed;//移动速度
  8. [Range(0, 2)]
  9. public int move_method;//移动循环方式
  10. //0为从出发点开始,到终点时从起点为目标再次开始循环移动
  11. //1为到了终点后,沿着原路返回,回到起始点后再次按路径到终点
  12. //2为到了终点后将不再移动
  13. private Rigidbody2D body;//刚体组件
  14. [Range(0, 10)]
  15. public float point_waittime;//每次到达一个位置后的的等待时间
  16. [Range(0, 10)]
  17. public float point_distance;//距离路点的位置容忍差
  18. private int index;//标点位置
  19. private bool set = true;//路径移动辅助,默认true
  20. void Start()
  21. {
  22. index = 0;
  23. body = GetComponent<Rigidbody2D>();
  24. line_array = line.GetComponentsInChildren<Transform>();//拿到所有的路点,确定寻路位置
  25. }
  26. void Update()//根据选择的移动方式进行移动
  27. {
  28. switch (move_method)
  29. {
  30. case 0:
  31. Move_line0();
  32. break;
  33. case 1:
  34. Move_line1();
  35. break;
  36. case 2:
  37. Move_line2();
  38. break;
  39. default:
  40. break;
  41. }
  42. }
  43. private float Get_Distance(Transform point)//获取物体和路点的距离
  44. {
  45. return Vector3.Distance(transform.position, point.position);
  46. }
  47. void Move_line0()//移动方式-0,这个判断格式使得此方法可以复用
  48. {
  49. if (Get_Distance(line_array[index]) <= point_distance && set)
  50. {
  51. index = (index + 1) % line_array.Length;
  52. }
  53. else if (Get_Distance(line_array[index]) <= point_distance && !set)
  54. {
  55. index--;
  56. }
  57. Move();
  58. }
  59. void Move_line1()//移动方式-1,到大最后一个点是修改set,使得line0中index从自增改为自减
  60. {
  61. if(index == line_array.Length - 1 && set)
  62. {
  63. set = false;
  64. }
  65. else if(index == 0 && !set)
  66. {
  67. set = true;
  68. }
  69. Move_line0();
  70. }
  71. void Move_line2()//判断到达终点后不再进行移动操作
  72. {
  73. if(index == line_array.Length -1 && Get_Distance(line_array[index]) <= point_distance)
  74. {
  75. return;
  76. }
  77. else
  78. {
  79. Move_line0();
  80. }
  81. }
  82. void Move()//朝向目标移动
  83. {
  84. Vector2 rot = line_array[index].position - transform.position;
  85. rot = rot.normalized;
  86. Vector2 position = transform.position;
  87. position.x += rot.x * speed * Time.deltaTime;
  88. position.y += rot.y * speed * Time.deltaTime;
  89. body.MovePosition(position);
  90. }
  91. }

        line的作用就是存储路径,我们可以在编辑器界面设置好线路后,只需要将线路对象给line变量,就可以通过GetComponentsInChildren拿到所有子物体点的位置,特别要注意的一点是,这个方法还会将父物体本身的TransForm返回,如果你不想要计入这个点,可以将index起始设置为1。

另外这段代码其实很亢余,有些函数的调用判断其实可以简化的(Get_Distance)就是,所以仅做参考,实际使用需要学会简化算法的时间复杂度和空间复杂度,优化结构,节省性能开销。

        再来看看我设置的三种方式移动效果

 

        线路移动可以用于设置敌人沿着某个固定路线移动,从而产生一种巡逻的效果,当发现玩家时就退出线路移动追踪玩家,否则继续沿着路径移动。另外这些点在游戏中改变了位置时,敌人也会改变随之移动路径。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/367967
推荐阅读
相关标签
  

闽ICP备14008679号