【问题标题】:Why is my airplane moving only partway and not all the way?为什么我的飞机只在中途移动而不是一直移动?
【发布时间】:2016-01-14 21:32:11
【问题描述】:

所以我花了 2 天时间查看这个脚本,但我仍然没有发现我做错了什么。我想制作一架简单的人工智能飞机,可以从一个点飞到另一个点。到达航点 1 后,它应该飞向航点 2。我将在下面包含我的脚本:

 using UnityEngine;
 using System.Collections

 public class AICustomScript : MonoBehaviour
 {
 //first waypoint
 public Transform Waypoint;
 //second waypoint
 public Transform Waypoint2;


 void Start()
 {
     rb = GetComponent<Rigidbody>();
 //make plane point in direction of first waypoint
     transform.LookAt(Waypoint);
 }
 //allow me to select amount of force in editor
 public float AddForceAmount;
 //allow me to select plane in editor
 public Rigidbody rb;

/void FixedUpdate()
 {
//make plane move
     rb.AddForce(transform.forward * AddForceAmount);
 }
 //PART OF CODE TO DETECT ARRIVAL ON WAYPOINT
 void OnTriggerEnter(Collider other)
{
     if (other.gameObject)
     {
//destroys waypoint
         Destroy(other.gameObject);
  //makes plane look at 2nd waypoint (Waypoint2)
         transform.LookAt(Waypoint2);
     }
 }
 }

 //SO WHAT'S WRONG?

我在 cmets 中包含了我的逻辑思维。然而,当飞机到达航点 1 时,它会转向航点 2,但只是部分转向。因此,当它飞向第二个航路点时,它永远不会“击中”它。为什么?

截图:

【问题讨论】:

  • 飞机是部分转向还是部分行进到waypoint2?
  • 是的,但只是部分。
  • 假设一个物体在一个方向上具有特定的速度。然后你向另一个方向施加力。在现实世界的物理学中,物体可能会改变其方向,但方向不会与力对齐。如果你向东扔一个球,那么球就会有一个力把它拉下来,但它不会直接向下移动。它在下降时一直向东移动。在这个物理系统中也是这样吗?你给一个物体一个速度;添加一个力可能会改变方向,但不一定会使物体沿力的方向移动。
  • 我明白了;所以AI是人类玩家的对手。您在这里面临许多有趣的问题,而物理问题并不是最难的。赛车游戏 AI 的棘手之处在于为 玩家玩得开心 而优化 AI,而不是 AI 获胜。进行数学运算以使 AI 得出最佳路线很棘手,但最终毫无意义;和这样的AI对战一点都不好玩!
  • 我的建议是为您的 AI 模块提供玩家拥有的相同控件,并全面了解玩家的行为。如果 AI 可以做出玩家无法做到的技巧,例如停在一角硬币上并任意改变方向,那会让玩家感到被欺骗。现在,您的 AI 会模拟人类在运行过程中会进行的控制动作。但是你拥有人类在赛道上会做的控制动作;玩几百次游戏并记录你的动作

标签: c# unity3d artificial-intelligence transform


【解决方案1】:

您可能希望使用球面插值使飞机在改变其位置时面向航路点。而不是增加前进的力量。

using UnityEngine;
using System.Collections;

public class AICustomScript : MonoBehaviour
{
    public Transform[] Waypoints;
    public float minimumTouchDistance = 2.0f; // minimum distance between the airplane and the waypoint
    public float airplaneSpeed = 10.0f;
    private Transform currentWaypoint; // keep track of current waypoint
    private int currentIndex; // current position in the waypoint array

     void Start()
     {
         currentWaypoint = Waypoints[0]; // set initial waypoint
        currentIndex = 0; // set initial index
     }

     void Update()
     {
       faceAndMove();

       if (Vector3.Distance(currentWaypoint.transform.position, transform.position) < minimumTouchDistance)
       {
            currentIndex++;
             if (currentIndex > Waypoints.Length - 1)
             {
                 currentIndex = 0;
             }
            currentWaypoint = Waypoints[currentIndex];
         }
     }

      void faceAndMove()
      {
           Vector3 deltaPosition = currentWaypoint.transform.position - transform.position;
           Vector3 calcVector = deltaPosition.normalized * airplaneSpeed * Time.deltaTime;
           this.transform.position += calcVector;
           this.transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(deltaPosition), 4 * Time.deltaTime);
        }
     }

【讨论】:

  • 代码转储答案并不比代码转储问题有用。请通过添加说明 OP 做错什么以及您发布的代码如何纠正错误的说明性文字来改进您的答案。
  • 感谢您的帮助,但我该如何使用该代码?正如彼得所说,对它的作用以及如何使用它有点困惑......
  • @Antonnelson:基本上这个答案是说,与其将其建模为一堆物体并对其施加力,不如将初始位置和航路点之间的空间划分为一些点沿途并让飞机简单地从一个点过渡到下一个点,直到击中航点。
  • 非常感谢!在编辑代码并修复错误后,它运行得非常好,我非常感谢你,因为这是游戏的基础。我会尝试更好地理解脚本,因为其中有很多我不知道的东西(例如 Quaternion.Slerp 和 calcVector 等),但这对我自己来说将是一个很好的教育项目:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
相关资源
最近更新 更多