public class GameManager : MonoBehaviour
{
public static GameManager I { get; private set; }
public GameState State { get; private set; }
public float Speed = baseSpeed + Time.time * speedIncrease;
[Header(Config)]
public float baseSpeed = 5;
public float speedIncrease = 0.1f;
void Awake()
{
I = this;
Application.targetFrameRate = 60;
}
public void StartGame()
{
State = GameState.Playing;
Time.timeScale = 1;
SceneManager.LoadScene(Game); // 简单重置
}
public void GameOver()
{
State = GameState.GameOver;
Time.timeScale = 0;
UIManager.I.ShowGameOver();
}
}
2、PlayerController.cs(新输入系统)
csharp
public class PlayerController : MonoBehaviour
{
[Header(Lanes)]
public float laneDistance = 3;
public float laneChangeSpeed = 10;
[Header(Jump & Roll)]
public float jumpHeight = 2;
public float jumpDuration = 0.5f;
public float rollDuration = 0.5f;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag(Obstacle))
GameManager.I.GameOver();
else if (other.CompareTag(Coin))
{
CoinManager.I.AddCoin();
other.gameObject.SetActive(false);
}
}
}
3、WorldGenerator.cs(无限跑道)
csharp
public class WorldGenerator : MonoBehaviour
{
[Header(Prefabs)]
public GameObject[] groundPrefabs;
public GameObject[] obstaclePrefabs;
public GameObject coinPrefab;
[Header(Spawn)]
public int initSegments = 10;
public float segmentLength = 10;
public int coinsPerSegment = 5;
void Start()
{
for (int i = 0; i < initSegments; i++)
SpawnSegment(i * segmentLength);
}
void Update()
{
if (PlayerController.I.transform.position.z + 50 nextSpawnZ)
SpawnSegment(nextSpawnZ);
if (activeSegments.Count 0 &&
activeSegments.Peek().transform.position.z + 50 < PlayerController.I.transform.position.z)
{
var seg = activeSegments.Dequeue();
Addressables.ReleaseInstance(seg); // 热更资源
}
}
void SpawnSegment(float z)
{
var ground = Addressables.InstantiateAsync(
groundPrefabs[Random.Range(0, groundPrefabs.Length)],
new Vector3(0, 0, z), Quaternion.identity).WaitForCompletion();
activeSegments.Enqueue(ground);
// 障碍
int obstacleLane = Random.Range(0, 3);
var obstacle = Addressables.InstantiateAsync(
obstaclePrefabs[Random.Range(0, obstaclePrefabs.Length)],
new Vector3((obstacleLane 1) * 3, 0, z + segmentLength * 0.5f),
Quaternion.identity).WaitForCompletion();
activeSegments.Enqueue(obstacle);
// 金币
for (int i = 0; i < coinsPerSegment; i++)
{
int coinLane = Random.Range(0, 3);
var coin = Addressables.InstantiateAsync(coinPrefab,
new Vector3((coinLane 1) * 3, 1, z + Random.Range(0, segmentLength)),
Quaternion.identity).WaitForCompletion();
activeSegments.Enqueue(coin);
}
nextSpawnZ += segmentLength;
}
}
4、CoinManager.cs(简单数据持久化)
csharp
public class CoinManager : MonoBehaviour
{
public static CoinManager I { get; private set; }
public int Coins { get; private set; }
八、可热更配置表
使用 ScriptableObject + Addressables:
csharp
[CreateAssetMenu(menuName=Game/LevelConfig)]
public class LevelConfig : ScriptableObject
{
public float baseSpeed = 5;
public AnimationCurve speedCurve;
public int coinValue = 1;
}