【问题标题】:How to make an object follow another object's path in Unity3D?Unity3D中如何让一个对象跟随另一个对象的路径?
【发布时间】:2016-10-09 21:51:45
【问题描述】:

我尝试在 Unity 回答网站上提出这个问题,但由于我还没有收到答案,所以我想我也会在这里问这个问题。我正在尝试制作游戏“Snake”的 3D 版本,但在尝试使第一个蛇段跟随蛇的头部时遇到了严重的问题。我使用的游戏对象是带有刚体组件的球体,玩家只能控制蛇的“头部”。然后,随着蛇的成长,会添加更多的球体,这些球体应该遵循主球体的路径。

我想知道是否有更优雅的解决方案来解决我想要实现的目标,或者至少对我可以做些什么来修复当前的实现有所帮助。我附上了应该跟随头部的段的代码。对象的命名是西班牙语,但从非西班牙语人士的角度来看,可能并不难弄清楚发生了什么。

我还对代码进行了适当的注释,以便您了解我在每个句子中所做的事情。现在部分可行的主要想法是向蛇段发送有关头部转弯的确切位置的信息,以便当这些段到达特定的转折点时,它们可以在头部转动的方向上转弯。我遇到的问题是,有时路段会经过它应该转弯的点,我不明白这是否是因为精度问题(我正在进行浮动比较以确定路段是否已到达某个位置它转向哪里)或者是别的什么东西。

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

 public class ControladorSegmento : MonoBehaviour {

     //This is a generic list of Objects that store both turning position and turning direction that the head has made
     public List<PosicionCambioDireccion> listaPosicionesCambioDireccion;

     //This would be the head in the case of only one segment that is following
     public GameObject lider;

     //Speed
     public float rapidez;

     //Direction
     public Vector3 direccion;

     //This is an index that is used to iterate over the list of turning points
     private int indiceCambioDireccion;

     // Use this for initialization
     void Start () {

         indiceCambioDireccion = 0;

         listaPosicionesCambioDireccion = new List<PosicionCambioDireccion>();

         //First find the Head of the snake so that we can access its position in order to determine segment spawning position
         lider = GameObject.Find("Cabeza");

         //Set the position of the new segment 2 units right behind the head
         transform.position = lider.GetComponent<Transform>().position - lider.GetComponent<ControladorCabeza>().direccion * 2f;

         //Get the current direction of the head so that the segment inmediately moves in its direction
         direccion = lider.GetComponent<ControladorCabeza>().direccion;
     }

     void LateUpdate () {

         //Check if there has been a change in direction that the segment has to follow
         if ((listaPosicionesCambioDireccion.Count > 0) && (listaPosicionesCambioDireccion.Count > indiceCambioDireccion)) {

             //Compare how close we are to the turning position. If we are sufficiently close, change segment direction
             if (Mathf.Abs(transform.position.x - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.x) < 0.0999999 &&
                 Mathf.Abs(transform.position.z - listaPosicionesCambioDireccion[indiceCambioDireccion].posicion.z) < 0.0999999) {

                 //Change segment direction at the current position
                 direccion = listaPosicionesCambioDireccion[indiceCambioDireccion].direccion;

                 //Increment turning positions list index so that we get the next turning point in the list (if there is any)
                 indiceCambioDireccion++;
             }
         }
     }

     void FixedUpdate() {


         //Change the velocity
         GetComponent<Rigidbody>().velocity = direccion * rapidez;

     }
 }

我仍然是 Unity 的新手,看来我还有很多东西要学。同样,如果您对我想要实现的目标有更优雅的解决方案,请告诉我。没错,我知道这种实现可能会导致某种内存泄漏,因为只要头部不断改变方向,存储的转折点列表就会不断增长,这显然是我们应该做的避免。

【问题讨论】:

    标签: c# unity3d path-finding rigid-bodies


    【解决方案1】:

    您可以在列表的最后一帧中记录每个片段的位置(包括头部),在下一帧,创建一个从头部片段的当前位置到最后一帧记录的最后位置的向量。然后从头部的当前位置开始计算头部和第一段半径之和的距离,并将你的第一段放在那里。对包含蛇的所有其他部分重复这些步骤。希望对您有所帮助。

    【讨论】:

    • 感谢您的贡献。我正在这样做,但如果我直接控制球体的位置,则运动看起来很不稳定和丑陋。我正在寻找一种解决方案,该解决方案涉及通过修改刚体的实际速度来移动球体,因为移动动画更加流畅。您推荐的解决方案使球体看起来正在被传送。
    • 您可以通过物理速度移动头部,但在 Update() 调用中每帧更新其他片段,这将使它们变得流畅。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多