首页 文章

Endless Runner无限轨道生成 - Unity3D C#

提问于
浏览
2

我是团结的新手,我正在创造我的第一个无尽的亚军游戏 . 我目前有一个立方体作为播放器和另一个立方体(预制件)作为轨道 . 我创建了一个脚本,旨在在运行时实例化预制件并将轨道移向播放器(而不是移动播放器) . 出于某种原因,在运行时实例化的轨道正在相同位置生成,并且似乎没有朝向播放器移动 . 有谁能告诉我,如果我做得对吗?如何生成无限/无尽的轨道?提前致谢

public GameObject[] trackPieces;
public float trackLength;
public float trackSpeed;

private GameObject trackObject;

// Update is called once per frame
void Update ()
{
    GenerateInfiniteTrack();
}

private void GenerateInfiniteTrack()
{
        trackObject = InstantiatePrefab();
        trackObject.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed);
}

private GameObject InstantiatePrefab()
{
    return Instantiate(trackPieces[Random.Range(0, trackPieces.Length)]) as GameObject;
}

1 回答

  • 1

    每帧都会覆盖

    trackObject

    您的轨道没有移动,因为移动它的调用仅在实例化时发生一次,而不再发生 . 每次更新()都会覆盖要移动的轨道的值 . 这是发生的事情:

    您拨打的每次更新:

    private void GenerateInfiniteTrack()
    

    调用此方法时,实例化一个新的预制件(对象的新实例)并告诉对象移动

    trackObject.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed);
    

    当您下次失去对原始对象的引用时调用该方法,因为您正在创建另一个替换trackObject中保存的值的方法 . 所以先前生成的对象永远不会再移动 . 您的新对象移动一次,然后丢失,再次,并重复 .

    下面我建议了一些可行的代码 . 您仍然需要决定如何处理轨道对象,因为您以非常快的速度创建轨道对象 . 如果您能想到使用InvokeRepeating()来解决此问题的方法,那么这将是最干净的 . 调用重复有一些限制,比如无法将参数传递给重复函数,所以我没有在这里使用它,但可以想象它是另一种选择 .

    这是我的例子 .

    var TrackObjects = new List<GameObject>();
    
    private void MoveInfiniteTrack() 
    {
        foreach(GameObject gO in TrackObjects )
        {
             gO.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed); 
        }
    }
    
    private void GenerateInfiniteTrack()
    {
            TrackObject = InstantiatePrefab();
            TrackObjects.Add(TrackObject);
    }
    
    void Update ()
    {
        GenerateInfiniteTrack();
        MoveInfiniteTrack() 
    }
    
    void Foo()
    {
        // Delete your track on some kind schedule or you will quickly get infinite objects and massive lag.
    }
    

    作为一般观察,创造这么多的轨道(每秒60x)是非常低效的 . 我建议你要么:

    A. 创建更大的轨道段,例如每1或10秒一次并移动它 . 我不记得究竟该怎么做,但它是这样的:

    var lastchecked= datetime.now 
    
    Update()
    {
        if((datetime.now - lastchecked).seconds > 1)
        {
            // put here what you will do every 1 second.
            lastchecked= datetime.now 
        }
    }
    

    B. 创建一个大圆柱并旋转它以用作轨道 .

相关问题