C# 将繁殖对象移动到随机位置
我有一个产卵器对象。每次生成一个游戏对象时,我都希望该对象随机移动(漫游)。我的脚本中的问题是游戏对象的移动非常随机(抖动)。我怎样才能解决这个问题C# 将繁殖对象移动到随机位置,c#,unity3d,game-physics,C#,Unity3d,Game Physics,我有一个产卵器对象。每次生成一个游戏对象时,我都希望该对象随机移动(漫游)。我的脚本中的问题是游戏对象的移动非常随机(抖动)。我怎样才能解决这个问题 void Start () { InvokeRepeating("SpawnNPC", Spawntime, Spawntime); } // Update is called once per frame void Update () { population = GameObject.FindGameObjectsWithTa
void Start ()
{
InvokeRepeating("SpawnNPC", Spawntime, Spawntime);
}
// Update is called once per frame
void Update () {
population = GameObject.FindGameObjectsWithTag("NPCobject");
for (int i = 0; i < population.Length; i++)
{
getNewPosition();
if (population[i].transform.position != pos)
{
population[i].transform.position = Vector3.MoveTowards(population[i].transform.position, pos, .1f);
}
}
}
void getNewPosition()
{
float x = Random.Range(-22, 22);
float z= Random.Range(-22, 22);
pos = new Vector3(x, 0, z);
}
void Start()
{
调用重复(“SpawnNPC”、Spawntime、Spawntime);
}
//每帧调用一次更新
无效更新(){
population=GameObject.FindGameObjectsWithTag(“NPCobject”);
for(int i=0;i
我用不同的方法创建了新的随机化向量,因为我计划使用pathfinder函数对其进行更改,并将其设置在不同的线程/任务中 抖动的根源来自这样一个事实:您正在更新位置以移动每一帧,因此您的对象永远不会有一个一致的位置来移动。我建议为每个对象附加一个新脚本,分别处理它们的移动。在该脚本中,您可以执行以下操作,这会延迟目标位置保持1帧以上
float delaytimer;
Vector3 pos;
void Start () {
getNewPosition(); // get initial targetpos
}
void Update () {
delaytimer += Time.deltaTime;
if (delaytimer > 1) // time to wait
{
getNewPosition(); //get new position every 1 second
delaytimer = 0f; // reset timer
}
transform.position = Vector3.MoveTowards(transform.position, pos, .1f);
}
void getNewPosition()
{
float x = Random.Range(-22, 22);
float z= Random.Range(-22, 22);
pos = new Vector3(x, 0, z);
}
抖动的根源来自这样一个事实:您正在更新位置以移动每一帧,这样您的对象就永远不会有一个一致的位置来移动。我建议为每个对象附加一个新脚本,分别处理它们的移动。在该脚本中,您可以执行以下操作,这会延迟目标位置保持1帧以上
float delaytimer;
Vector3 pos;
void Start () {
getNewPosition(); // get initial targetpos
}
void Update () {
delaytimer += Time.deltaTime;
if (delaytimer > 1) // time to wait
{
getNewPosition(); //get new position every 1 second
delaytimer = 0f; // reset timer
}
transform.position = Vector3.MoveTowards(transform.position, pos, .1f);
}
void getNewPosition()
{
float x = Random.Range(-22, 22);
float z= Random.Range(-22, 22);
pos = new Vector3(x, 0, z);
}
您正在为每一帧选择一个新方向。那将永远是非常紧张的。至少在一小段时间后,你不需要改变方向。下面是Unity网站上的一个链接 您正在为每一帧选择一个新方向。那将永远是非常紧张的。至少在一小段时间后,你不需要改变方向。下面是Unity网站上的一个链接 你正在改变它们在每一帧中的移动方向,这就是造成抖动的原因 你可以等一会儿再改变方向,也许是这样
// Outside update
float betweenChanges = 2;
float lastChange = 0;
// Inside update
if(Time.realtimeSinceStartup > lastChange)
{
// Change directions
// ...
lastChange = Time.realTimeSinceStart + betweenChanges;
}
您还可以通过使用invokererepeating
或corroutine
来解决这个问题
如果您不希望所有NPC同时改变方向,并且仍然计划像您的示例中那样从同一个类控制每个NPC,那么您可能应该为每个NPC实例添加一个计时器,并使用它来决定何时改变方向
更好的办法是让每个NPC都有自己的
移动
-脚本。您正在改变它们在每个帧中的移动方向,这就是导致抖动的原因
你可以等一会儿再改变方向,也许是这样
// Outside update
float betweenChanges = 2;
float lastChange = 0;
// Inside update
if(Time.realtimeSinceStartup > lastChange)
{
// Change directions
// ...
lastChange = Time.realTimeSinceStart + betweenChanges;
}
您还可以通过使用invokererepeating
或corroutine
来解决这个问题
如果您不希望所有NPC同时改变方向,并且仍然计划像您的示例中那样从同一个类控制每个NPC,那么您可能应该为每个NPC实例添加一个计时器,并使用它来决定何时改变方向
一个更好的办法是让每个NPC都有自己的动作-脚本。如何使用?正如您所说的“漫游”
,我认为它会给您带来一个很好的结果,并使您的代码变得简单
下面的屏幕截图是一个导航示例。移动的游戏对象也在很好地改变它们的方向,尽管在示例中无法看到,因为游戏对象是胶囊
Ground
示例程序中的游戏对象具有NavMesh
。请参见以构建NavMesh
Agent
游戏对象具有NavMeshAgent
组件。请注意设置它
下面的行为类用于代理
游戏对象
using UnityEngine;
using UnityEngine.AI;
public class NavAgentBehaviour : MonoBehaviour {
public Transform[] Destinations { get; set; }
// Use this for initialization
void Start ()
{
InvokeRepeating("changeDestination", 0f, 3f);
}
void changeDestination()
{
var agent = GetComponent<NavMeshAgent>();
agent.destination = Destinations[Random.Range(0, Destinations.Length)].position;
}
}
增加目的地的数量,使移动看起来更随机。顺便说一句,目的地不需要由游戏对象指定,这只是为了便于查看示例程序的行为。如何使用?正如您所说的“漫游”
,我认为它会给您带来一个很好的结果,并使您的代码变得简单
下面的屏幕截图是一个导航示例。移动的游戏对象也在很好地改变它们的方向,尽管在示例中无法看到,因为游戏对象是胶囊
Ground
示例程序中的游戏对象具有NavMesh
。请参见以构建NavMesh
Agent
游戏对象具有NavMeshAgent
组件。请注意设置它
下面的行为类用于代理
游戏对象
using UnityEngine;
using UnityEngine.AI;
public class NavAgentBehaviour : MonoBehaviour {
public Transform[] Destinations { get; set; }
// Use this for initialization
void Start ()
{
InvokeRepeating("changeDestination", 0f, 3f);
}
void changeDestination()
{
var agent = GetComponent<NavMeshAgent>();
agent.destination = Destinations[Random.Range(0, Destinations.Length)].position;
}
}
增加目的地的数量,使移动看起来更随机。顺便说一下,目的地不需要由游戏对象指定,这只是为了便于查看示例程序的行为。这是正确的方法是正确的方法是使用navmesh。但我正在尝试让getNewPosition()在另一个线程中运行。例如,在我编写寻路代码之前。但是,谢谢你的回答和解释。这是正确的方法。是的,正确的方法是使用navmesh。但我正在尝试让getNewPosition()在另一个线程中运行。例如,在我编写寻路代码之前。但是,谢谢你的回答和解释。