C# 无限移动的隧道未正确对齐

C# 无限移动的隧道未正确对齐,c#,unity3d,C#,Unity3d,如果你能想象一个游戏,玩家永远都在穿越隧道。要做到这一点,我的相机是固定的,隧道向后移动,给人一种移动的错觉 屏幕上总是有3个小隧道同时粘在一起,当一个人离开玩家的视野时,一个新的隧道在前面产生,给人一种无限的错觉 这是正常工作,除非一段隧道被删除。之后的隧道似乎停止移动了一帧,这导致前面的隧道在里面移动并重叠,我不知道为什么 每个隧道的长度正好是116.25,默认情况下,第一个隧道在屏幕上 //An array to store the pre made tunnels for easy di

如果你能想象一个游戏,玩家永远都在穿越隧道。要做到这一点,我的相机是固定的,隧道向后移动,给人一种移动的错觉

屏幕上总是有3个小隧道同时粘在一起,当一个人离开玩家的视野时,一个新的隧道在前面产生,给人一种无限的错觉

这是正常工作,除非一段隧道被删除。之后的隧道似乎停止移动了一帧,这导致前面的隧道在里面移动并重叠,我不知道为什么

每个隧道的长度正好是116.25,默认情况下,第一个隧道在屏幕上

//An array to store the pre made tunnels for easy difficulty
public GameObject[] easyTunnels;

//List of tunnels that are currently on screen
public List<GameObject> tunnels = new List<GameObject>();

float speed = 0.5f;
int level = 0;

//A list of all of the tunnels for every difficulty(only easy atm)
List<GameObject[]> levelsArray = new List<GameObject[]>();

void Start () 
{
    levelsArray.Add(easyTunnels);

    //Spawn 2 tunnels for a total of 3 in a row. Starting tunnel already exists
    for (int i = 1; i < 3; i++)
    {
        int randomTunnel = Random.Range(0, easyTunnels.Length);
        Vector3 startingPos = new Vector3(0, 0, 116.25f * i);
        GameObject tunnel = Instantiate(easyTunnels[randomTunnel]);
        tunnel.transform.position = startingPos;
        tunnels.Add(tunnel);
    }
}

void Update () 
{
    //For each tunnel on the map
    for (int i = 0; i < tunnels.Count; i++)
    {
        //As its moving on the z axis, get that value
        Transform tunnelPos = tunnels[i].transform;
        float zPos = tunnelPos.position.z;

        //Each tunnel is exactly 116.25 in length
        //If it reaches this, it means its off screen as the tunnel starts at 0
        if (zPos < -116.25f)
        {
            //Get the spawn point of the new tunnel. The existing position + the length of 3 tunnels
            float newZPos = zPos + 348.75f;

            //Destroy this one as we dont need it anymore
            Destroy(tunnels[i]);
            tunnels.RemoveAt(i);

            //And spawn the new one
            int randomTunnel = Random.Range(0, easyTunnels.Length);
            Vector3 startingPos = new Vector3(0, 0, newZPos);
            GameObject tunnel = Instantiate(levelsArray[level][randomTunnel]);
            tunnel.transform.position = startingPos;
            tunnels.Add(tunnel);

        }

        //If the tunnel exists, then move it
        if (tunnels[i] != null)
        {
            tunnelPos.position = new Vector3(tunnelPos.position.x, tunnelPos.position.y, zPos -= speed);
        }
    }
}
//一个数组,用于存储预制的隧道,非常简单
公共游戏对象[]easyTunnels;
//当前在屏幕上的隧道列表
公共列表隧道=新列表();
浮动速度=0.5f;
智力水平=0;
//每个困难的所有隧道列表(仅easy atm)
列表级别ray=新列表();
无效开始()
{
levelsArray.Add(easyTunnels);
//连续生成2个隧道,总共3个。起始隧道已存在
对于(int i=1;i<3;i++)
{
int randomTunnel=Random.Range(0,easyTunnels.Length);
矢量3开始位置=新矢量3(0,0,116.25f*i);
GameObject tunnel=实例化(easyTunnels[randomTunnel]);
tunnel.transform.position=startingPos;
隧道。增加(隧道);
}
}
无效更新()
{
//地图上的每条隧道
对于(int i=0;i

为什么要这样做?

从数组中删除和添加,同时在数组中循环从来都不是一个好主意

我建议另一种方法:

  • 创建一个TunnelManager Empty,并附加一个脚本,该脚本只生成一个随机的TunnelManager预置数组

  • 给每个隧道预制一个脚本,该脚本a)向下移动,b)在到达端点时删除自身(即116.25f)。在这样做之前,它应该调用TunnelManager的“生成新的隧道块”方法Empty


  • 这样,就不需要在每个帧中循环数组并添加或删除它。

    在循环数组的同时从数组中删除和添加,这绝不是一个好主意

    我建议另一种方法:

  • 创建一个TunnelManager Empty,并附加一个脚本,该脚本只生成一个随机的TunnelManager预置数组

  • 给每个隧道预制一个脚本,该脚本a)向下移动,b)在到达端点时删除自身(即116.25f)。在这样做之前,它应该调用TunnelManager的“生成新的隧道块”方法Empty


  • 这样,就不需要在每一帧的数组中循环并添加或删除游戏对象。

    在单个帧中删除和实例化游戏对象可能会相对昂贵,但我不能说太多,因为我不知道游戏对象的几何体、材质等

    然而,我能告诉你的是,你移除和添加隧道的方式可能会导致一个隧道不会为每一帧更新,而另一个隧道会更新两次

    您正在执行以下操作:

    for index i =0, do while i < the number of tunnels
      if the tunnel is too far away
        destroy it and create a new one, add it to the end of the list of tunnels
        reposition the tunnel at index i
    
    tunnelPos.position = new Vector3(tunnelPos.position.x, tunnelPos.position.y, zPos -= speed * Time.DeltaTime);
    
    另外,对于渲染的每一帧,它只会将它们移动一个特定的量

    由于每秒渲染的帧数是可变的,因此隧道部分的速度可能会随着帧率而下降或跳跃

    请尝试以下操作:

    for index i =0, do while i < the number of tunnels
      if the tunnel is too far away
        destroy it and create a new one, add it to the end of the list of tunnels
        reposition the tunnel at index i
    
    tunnelPos.position = new Vector3(tunnelPos.position.x, tunnelPos.position.y, zPos -= speed * Time.DeltaTime);
    

    在单个帧中删除和实例化游戏对象可能相对昂贵,但我不能说太多,因为我不知道它们的几何体、材质等

    然而,我能告诉你的是,你移除和添加隧道的方式可能会导致一个隧道不会为每一帧更新,而另一个隧道会更新两次

    您正在执行以下操作:

    for index i =0, do while i < the number of tunnels
      if the tunnel is too far away
        destroy it and create a new one, add it to the end of the list of tunnels
        reposition the tunnel at index i
    
    tunnelPos.position = new Vector3(tunnelPos.position.x, tunnelPos.position.y, zPos -= speed * Time.DeltaTime);
    
    另外,对于渲染的每一帧,它只会将它们移动一个特定的量

    由于每秒渲染的帧数是可变的,因此隧道部分的速度可能会随着帧率而下降或跳跃

    请尝试以下操作:

    for index i =0, do while i < the number of tunnels
      if the tunnel is too far away
        destroy it and create a new one, add it to the end of the list of tunnels
        reposition the tunnel at index i
    
    tunnelPos.position = new Vector3(tunnelPos.position.x, tunnelPos.position.y, zPos -= speed * Time.DeltaTime);
    

    当您从列表中删除一个隧道(“tunnels.RemoveAt(i);”)时,您可能需要将i的计数器减掉1,因为设想如下:tunnel[0]被删除(i=0)您生成一个新隧道并将其添加到屏幕(将是tunnel[3]),现在在下一个循环中,它将是i=1;但它将指向隧道[2],因为你删除了一个,所以跳过了一个。试试看会发生什么。要快速检查,请尝试注释“tunnels.Add(tunnel)”;它在循环中,看你是否得到和IndexOutOfRangeException。啊,这是有意义的,我没意识到列表会自动调整它的