c# - 转向行为 : Why is my wandering algorithm not working as intended?

标签 c# algorithm unity3d

我们正在学习我的人工智能游戏类(class)中的转向行为,我想我会尝试实现其中的一些行为。我主要是在阅读 The Nature of Code熟悉主题。

Here是我的 Unity 项目的存储库。相关场景在Assets/Scenes/Wandering.unity下。

这是相关的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wandering : MonoBehaviour
{
    public float maxSpeed;
    private float speed;
    public float maxForce;
    public float radius;
    private Rigidbody body;


    void Awake()
    {
        body = gameObject.GetComponent<Rigidbody>();
        speed = maxSpeed;
        body.velocity = new Vector3(5, 0, 5);
    }


    void Update()
    {
        // Get future position
        Vector3 futurePosition = GetFuturePosition();

        // Select random point on circle of radius "radius" around the future position
        Vector3 target = GeneratePointOnCircle(futurePosition);

        // Compute desired velocity as one pointing there
        Vector3 desiredVelocity = GetDesiredVelocity(target);

        // Get the steering force vector
        Vector3 steerForce = desiredVelocity - body.velocity;
        steerForce.y = 0;

        // Cap the force that can be applied (lower max force = more difficult to turn)
        if (Vector3.Magnitude(steerForce) > maxForce)
        {
            steerForce = Vector3.Normalize(steerForce) * maxForce;
        }

        // Apply the force to the body
        body.AddForce(steerForce);
    }


    /* Returns a random point on a circle positioned at the given center and radius.
     */ 
    Vector3 GeneratePointOnCircle(Vector3 center)
    {
        Vector3 point = center;

        float angle = Random.Range(0, 360) * Mathf.Deg2Rad;
        point.x += radius * Mathf.Cos(angle);
        point.z += radius * Mathf.Sin(angle);

        return point;
    }


    /* Computes and returns the future, predicted position of this object, assuming
     * it continues traveling in its current direction at its current speed.
     */
    Vector3 GetFuturePosition()
    {
        // We have a current velocity
        // We have a time elapsed
        // We have a current position
        // Future position = current position + current velocity * delta time

        return transform.position + body.velocity * Time.deltaTime;
    }


    /* The desired velocity is simply the unit vector in the direction of the target
     * scaled by the speed of the object.
     */
    Vector3 GetDesiredVelocity(Vector3 target)
    {
        return Vector3.Normalize(target - transform.position) * speed;
    }
}

在编辑器中设置的值:

  • 最大速度:40
  • 最大力量:20
  • 半径:60

当我运行它时,代理没有按预期运行。主要问题是它不是平稳地移动,而是在短暂的爆发中结结巴巴,似乎停顿了一下,然后又开始移动。这种随机行为仍然非常巧妙,有点模仿迷失方向的啮齿动物的行为,但我正在寻找看起来更聪明的行为。

我的脚本或逻辑中是否有缺陷迫使代理以这种不稳定的方式行事?任何建议将不胜感激。

最佳答案

问题似乎出在我使用 Time.deltaTime 来计算 future 的预测点(如果代理继续以当前速度运行的话)。

因为这实际上是自上次帧更新以来耗时,所以它是一个很小的数字。因此,使用它来预测 future 点具有误导性,并且会产生非常接近代理的点(因此出现“卡顿”行为)。

相反,我选择使用固定的“先行”时间(比如 2)来预测更远的 future 。

关于c# - 转向行为 : Why is my wandering algorithm not working as intended?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54660195/

相关文章:

c# - 在添加新力之前从 Rigidbody 移除先前的力

ios - 使用 Jenkins 构建 Xcode 项目会出现代码设计错误

c# - 阻止 DomainUpDown 控件中的粘贴事件

c# - 在 foreach 循环中修改对象的值

python - 编辑 .txt 文件 - 算法不工作

string - 将图形转换为规范字符串

c# - 从 Windows Phone 应用程序中的 DownloadStringCompleted 处理程序填充和返回实体

c# - 在 C# 中更改 SQL Server 存储过程

swift - 如何将对象数组分组并转换为另一个分组对象数组

c# - 统一,加电碰撞问题