我们正在学习游戏类人工智能中的转向行为,我认为我会尽力实现其中的一些行为。我主要阅读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;
}
}
在编辑器中设置的值:
maxSpeed
:40 maxForce
:20 radius
:60 运行此命令时,代理的行为不符合预期。主要问题是,它没有平稳地行驶,而是突然停顿了一下,似乎停了下来,然后又开始运动。这种随机行为仍然很整洁,并且有点像迷失方向的啮齿动物的行为,但是我正在寻找更智能的行为。
我的脚本或逻辑中是否存在迫使代理以这种不稳定方式运行的缺陷?任何建议将不胜感激。
答案 0 :(得分:2)
问题似乎出在我是否使用Time.deltaTime
来计算代理是否以当前速度继续运行的情况下的预测点。
因为这实际上是自上一帧更新以来经过的时间,所以它是一个很小的数字。因此,将其用于预测未来点会产生误导,并且会产生非常接近代理的点(因此会出现“口吃”行为)。
相反,我选择使用固定的“超前”时间(例如2
)来预测未来。