首先,因为我从这里找到的其他帖子中找到了很多帮助,所以我考虑注册,所以我想这是我的第一篇帖子!
无论如何,我目前正在使用 C# 开发 Unity3D 游戏,我们基本上有一个无尽的驾驶游戏,玩家可控制的汽车可以在三个车道之间移动,同时避开路上的敌人和障碍物。
为了给人一种汽车在无尽道路上行驶的错觉,我将一小段道路制作成预制件,并使用我的脚本,假设每 x 秒实例化这些模块/部分中的一个。这些部分有另一个脚本,根据我设置的速度每帧向前移动它们的位置,它移动到静止的汽车下方,看起来汽车在路上行驶。通过精确调整这些路段的时间和速度,它们在屏幕外一个接一个地生成,看起来就像一条单一的、无限的道路。然后在播放器后面删除路段,不再看到它们以节省资源。
这个概念最初效果很好,随着游戏时间的推移,玩家下方的道路会移动得更快,游戏会变得更加困难。
随着我实现更多游戏机制,我注意到这些实例化的路段之间有时会出现一些小的间隙,就好像一个实例化的有点晚了。快速查看分析器会发现,当一个部分被实例化时,整体性能会下降,有时会出现这些差距。
我通过使用“InvokeRepeating("spawnModule", 0f, spawnDelay);" 来实例化我的路段,并且由于 InvokeRepeating 基本上每 x 秒重复一次所述方法,它应该始终以不会产生间隙的方式生成我的路段,因为实例化晚于另一个。此问题不会出现在具有更高处理能力的系统上,因为 Instantiate() 不会在那里引起很大的性能问题。
无论如何,我希望我的概念是清晰的,仅供参考,如果有人可以按照我正在做的事情,我有每帧移动每个模块的脚本,并控制实例化方法的时间(请记住一些变量没有用英语声明,因为它不是我的主要语言:
模块生成器脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ModulSpawn : MonoBehaviour {
public GameObject ModulPrefab;
public GameObject ModulSpawnPoint;
public Vector3 SpawnDrehung;
public float BewGeschwindigkeit;
public float spawnDelay;
[SerializeField] float gameTime;
float delayDifference;
public int Stufe;
public float[] speedListe;
public float[] delayListe;
public float[] timerListe;
public bool switcherActive = true;
public bool updateInvoke = false;
// Use this for initialization
void Start() {
Stufe = 0;
//Instantiate(ModulPrefab, ModulSpawnPoint.transform.position, Quaternion.Euler(SpawnDrehung));
InvokeRepeating("spawnModule", 0f, spawnDelay);
//delayDifference = spawnDelay;
}
// Update is called once per frame
void FixedUpdate() {
//gameTime = Time.time;
/*
if (gameTime >= delayDifference) {
//Debug.Log(delayDifference);
Instantiate(ModulPrefab, ModulSpawnPoint.transform.position, Quaternion.Euler(SpawnDrehung));
if (switcherActive == true) stufenSwitcher();
delayDifference += spawnDelay;
Debug.Log("Now");
} */
//Debug.Log(gameTime);
}
void OnTriggerExit(Collider other)
{
if (other.CompareTag("Modul")) {
Destroy(other.gameObject);
}
}
void spawnModule() {
Instantiate(ModulPrefab, ModulSpawnPoint.transform.position, Quaternion.Euler(SpawnDrehung));
gameTime = Time.time;
if (Time.time >= timerListe[Stufe] && delayListe[Stufe] != 0 && switcherActive == true)
{
spawnDelay = delayListe[Stufe];
CancelInvoke("spawnModule");
InvokeRepeating("spawnModule", 0f, spawnDelay);
BewGeschwindigkeit = speedListe[Stufe];
Stufe++;
//if (Stufe > timerListe.Length) switcherActive = false;
}
if (updateInvoke == true) {
updateInvoke = false;
CancelInvoke("spawnModule");
InvokeRepeating("spawnModule", 0f, spawnDelay);
}
}
}
模块移动脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ModulMove : MonoBehaviour {
public bool Xpos;
public bool Xneg;
public bool Ypos;
public bool Yneg;
public bool Zpos;
public bool Zneg = true;
Vector3 BewRichtung = new Vector3(0f, 0f, -1f);
public float BewGeschwindigkeit;
public ModulSpawn modulSpawnScript;
Rigidbody rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
RichtungsCheckbox();
modulSpawnScript = GameObject.Find("ModulSpawner").GetComponent<ModulSpawn>();
}
void Update () {
BewGeschwindigkeit = modulSpawnScript.BewGeschwindigkeit;
gameObject.transform.Translate(BewRichtung * BewGeschwindigkeit * Time.deltaTime * 50);
//Debug.Log(Time.deltaTime);
//+= BewRichtung * (BewGeschwindigkeit * Time.deltaTime);
//rb.velocity = new Vector3(0f, 0f, -5f);
}
void RichtungsCheckbox()
{
if (Xpos == true)
{
BewRichtung = new Vector3(1, 0, 0);
}
if (Xneg == true)
{
BewRichtung = new Vector3(-1, 0, 0);
}
if (Ypos == true)
{
BewRichtung = new Vector3(0, 1, 0);
}
if (Yneg == true)
{
BewRichtung = new Vector3(0, -1, 0);
}
if (Zpos == true)
{
BewRichtung = new Vector3(0, 0, 1);
}
if (Zneg == true)
{
BewRichtung = new Vector3(0, 0, -1);
}
}
}
如果我能找到一些替代方案的建议,我会非常高兴。我正在考虑也许在部分应该出现的时间之间进行实例化,以避免在一个部分实际上必须精确出现时出现滞后。
你怎么看?