我正在尝试使用刚体创建MOB AI。我想使用
使暴民(GameObject)环游世界mobrigid.AddForce((((goal - transform.position).normalized)*speed * Time.deltaTime));
(目标是围绕暴民的随机地点)。
这是复杂的地方,一些小生物以极高的速度飞向空中,而另一些生物则以低速正常移动。 (是的,我确实确定了目标。Y是地面上的地方,而不是空中的地方)。我尝试通过更改阻力来修复它,但是这导致小生物在空中行走并且不会因重力而下落。
我真的迷失了方向,无法弄清楚如何在没有得到这种奇怪行为的情况下,用刚体简单地移动游戏对象。
我的运动逻辑:
case MOBTYPE.EARTHMOB:
switch (currentstatus)
{
case MOBSTATUS.STANDING:
if (mobrigid.IsSleeping())
{
mobrigid.WakeUp();
}
goal = this.transform.position;
goal.x = Random.Range(goal.x - 150, goal.x + 150);
goal.z = Random.Range(goal.z -150, goal.z + 150);
goal.y = 0;
currentstatus = MOBSTATUS.WALKING;
// Debug.Log("Transform:"+this.transform.position+ "Goal:" + goal+ "goal-transform:" + (goal - transform.position));
break;
case MOBSTATUS.WALKING:
if (Random.Range(1, 100) == 5)
{
currentstatus = MOBSTATUS.STANDING;
}
if (mobrigid.IsSleeping())
{
mobrigid.WakeUp();
}
mobrigid.AddForce((((goal - transform.position).normalized) * 10000 * Time.deltaTime));
// transform.LookAt(goal);
var distance = Vector3.Distance(goal, gameObject.transform.position);
if (distance <=5)
{
currentstatus = MOBSTATUS.STANDING;
}
break;
}
break;
答案 0 :(得分:1)
Rigidbody.AddForce
函数用于沿某个方向向对象施加力。由于您有职位,需要将Rigidbody
移至该位置,因此必须使用Rigidbody.MovePosition
函数。您可能还需要将刚体标记为运动学的。
一个简单的协程函数,可以将刚体对象移动到特定位置:
IEnumerator MoveRigidbody(Rigidbody rb, Vector3 destination, float speed = 50f)
{
const float destThreshold = 0.4f;
while (true)
{
Vector3 direction = (destination - rb.position).normalized;
rb.MovePosition(rb.position + direction * speed * Time.deltaTime);
float dist = Vector3.Distance(rb.position, destination);
//Exit function if we are very close to the destination
if (dist <= destThreshold)
yield break;
yield return null;
//yield return new WaitForFixedUpdate();
}
}
最好从另一个coorutine函数中调用它,以便您可以屈服或等待它完成,然后执行其他任务,例如再次生成随机位置并将刚体移到那里。
您要生成新位置,然后将Rigidbody
移动到此处,这是如何调用上述函数的示例:
IEnumerator StartMoveMent()
{
Rigidbody targetRb = GetComponent<Rigidbody>();
while (true)
{
//Generate random position
Vector3 destination = new Vector3();
destination.y = 0;
destination.x = UnityEngine.Random.Range(0, 50);
destination.z = UnityEngine.Random.Range(0, 50);
//Move and wait until the movement is done
yield return StartCoroutine(MoveRigidbody(targetRb, destination, 30f));
}
}
并启动StartMoveMent
函数:
void Start()
{
StartCoroutine(StartMoveMent());
}
尽管我上面说的应该可以,但我建议您使用Unity的内置寻路系统。 Here是为此的教程。它简化了NavMesh
(也可以是baked during run-time
)寻找要前往目的地的路径的操作。