C# 转向行为:为什么我的漫游算法不能按预期工作?
在我的“人工智能游戏”课程中,我们正在学习指导行为,我想我应该尝试实现其中的一些。我主要是通过阅读来熟悉这些话题 是我的Unity项目的存储库。相关场景位于C# 转向行为:为什么我的漫游算法不能按预期工作?,c#,algorithm,unity3d,C#,Algorithm,Unity3d,在我的“人工智能游戏”课程中,我们正在学习指导行为,我想我应该尝试实现其中的一些。我主要是通过阅读来熟悉这些话题 是我的Unity项目的存储库。相关场景位于资源/场景/漫游.unity下 以下是相关脚本: using System.Collections; using System.Collections.Generic; using UnityEngine; public class Wandering : MonoBehaviour { public float maxSpeed;
资源/场景/漫游.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;
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共阶级漂泊:单一行为
{
公共浮动最大速度;
私人浮动速度;
公共安全部队;
公众浮标半径;
私人刚体;
无效唤醒()
{
body=gameObject.GetComponent();
速度=最大速度;
body.velocity=新矢量3(5,0,5);
}
无效更新()
{
//获得未来职位
Vector3 futurePosition=GetFuturePosition();
//选择未来位置周围半径为“半径”的圆上的随机点
Vector3目标=生成圈(未来位置);
//计算所需的速度作为一个指向那里的速度
Vector3 desiredVelocity=GetDesiredVelocity(目标);
//得到转向力矢量
Vector3 steerForce=所需速度-body.velocity;
转向力y=0;
//限制可施加的力(最大力越小=转动越困难)
if(矢量3.幅值(转向力)>最大力)
{
steerForce=Vector3.规格化(steerForce)*maxForce;
}
//对身体施力
body.AddForce(Steerinforce);
}
/*返回位于给定圆心和半径的圆上的随机点。
*/
矢量3发生器同心圆(矢量3中心)
{
矢量3点=中心;
浮动角度=随机范围(0,360)*Mathf.Deg2Rad;
点x+=半径*数学坐标(角度);
点z+=半径*数学正弦(角度);
返回点;
}
/*计算并返回此对象的未来预测位置,假设
*它继续以当前速度沿当前方向行驶。
*/
Vector3获取未来位置()
{
//我们有一个流速
//我们已经过了一段时间
//我们现在有一个职位
//未来位置=当前位置+当前速度*增量时间
返回transform.position+body.velocity*Time.deltaTime;
}
/*理想速度只是目标方向上的单位矢量
*按对象的速度缩放。
*/
Vector3获得所需速度(Vector3目标)
{
返回向量3.规格化(目标-变换位置)*速度;
}
}
在编辑器中设置的值:
:40maxSpeed
:20maxForce
:60半径
我的脚本或逻辑中是否存在迫使代理以这种不稳定的方式行为的缺陷?任何建议都将不胜感激。问题似乎是我使用了
时间。deltaTime
来计算未来的预测点,如果代理继续以当前速度运行
由于这实际上是自上次帧更新以来经过的时间,所以这是一个相当小的数字。因此,使用它来预测未来的点是误导性的,并且会产生非常接近代理的点(因此出现“口吃”行为)
相反,我选择使用固定的“前瞻”时间(比如说
2
)来预测未来 哦,我想我可能已经弄明白了。这是否与Time.deltaTime
是一个很小的值,因此对未来的预测很小有关?从技术上讲,这是从最后一帧开始经过的时间,据我所知,这始终是恒定的。我想我还应该创建一个随机的初始速度,因为否则我会偏离代理的大致方向。