⚙️ 五、高级功能与模块化 (29-31 步)
29. 实现空中控制 (AirControl.cs)
为了让 Level 2 更有挑战性,我们通过 组件化 实现了空中控制。
- 操作: 创建独立脚本
AirControl.cs。 - 原理:
AirControl没有继承PlayerMovement。它通过GetComponent<PlayerMovement>()获取玩家的isGrounded状态,然后在空中独立施加修正力。 - 应用: 只将
AirControl.cs附加到 Level 2 的Player对象上。
💻 核心代码:空中修正力
C#
// AirControl.cs
void FixedUpdate()
{
// 只有当玩家不在地面上时,才施加侧向修正力
if (playerMovement != null && !playerMovement.isGrounded)
{
float horizontalInput = Input.GetAxis("Horizontal");
float airForce = horizontalInput * airControlForce * Time.deltaTime;
// 使用 VelocityChange,直接改变玩家速度
rb.AddForce(airForce, 0, 0, ForceMode.VelocityChange);
}
}
30. 创建跳板 (Launcher.cs)
引入跳板为关卡设计提供了垂直变化。
- 操作: 创建
Cube,勾选Is Trigger,设置 Tag:LaunchPad,附加Launcher.cs。
💻 核心代码:瞬间推力
C#
// Launcher.cs
public float launchForce = 1500f;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Rigidbody rb = other.GetComponent<Rigidbody>();
if (rb != null)
{
// 清零垂直速度,确保获得最大的向上推力
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
// 使用 Impulse 施加瞬间的力
rb.AddForce(Vector3.up * launchForce, ForceMode.Impulse);
// 播放特效
launchEffect.Play();
}
}
}
31. 创建动态陷阱 (移动与旋转)
引入移动和旋转障碍物增加了游戏的动态难度。
- 物理优化: 动态障碍物的 Rigidbody 组件的 Collision Detection 必须设置为 Continuous。
💻 核心代码:往复移动(PingPong)
C#
// MoveBetweenPoints.cs
void Update()
{
// Math.PingPong(time, length) 使 time 在 0 和 length 之间来回震荡
timeElapsed += Time.deltaTime * speed;
float t = Mathf.PingPong(timeElapsed, 1f);
// Lerp(A, B, t) 平滑地在起点和终点之间移动
transform.position = Vector3.Lerp(startPosition, endPosition, t);
}
💻 核心代码:恒定旋转
C#
// RotateAroundAxis.cs
public float rotationSpeed = 100f;
public Vector3 rotationAxis = Vector3.up;
void Update()
{
// 围绕指定轴以指定速度旋转
transform.Rotate(rotationAxis, rotationSpeed * Time.deltaTime);
}
🗺️ 六、游戏流程控制与启动 (32-33 步)
32. 多场景切换与 Build Settings
实现了从 Level 1 到 Level 2 的自动切换,并将所有场景整合到游戏启动流程中。
- 操作: 在 File -> Build Settings 中,将所有场景按顺序添加到列表:
MainMenu(0) →Level1(1) →Level2(2)。
💻 核心代码:延迟加载下一关
C#
// GameController.cs
public void GameWon()
{
// 停止计时器,显示 UI
// ...
// 延迟 3 秒后调用 LoadNextLevel 函数
Invoke("LoadNextLevel", 3f);
}
public void LoadNextLevel()
{
int nextSceneIndex = SceneManager.GetActiveScene().buildIndex + 1;
// 确保索引有效,然后加载下一个场景
if (nextSceneIndex < SceneManager.sceneCountInBuildSettings)
{
SceneManager.LoadScene(nextSceneIndex);
}
else
{
// 游戏通关,回到主菜单或第一关
SceneManager.LoadScene(0);
}
}
33. 创建主菜单 (MenuManager.cs)
为主菜单添加启动和退出功能,完成游戏的启动循环。
💻 核心代码:启动与退出
C#
using UnityEngine.SceneManagement;
// MenuManager.cs
public class MenuManager : MonoBehaviour
{
public void StartGame()
{
// 加载 Level 1 场景 (索引 1)
SceneManager.LoadScene(1);
}
public void QuitGame()
{
// 退出游戏应用程序
Application.Quit();
// 提示:在 Unity 编辑器中运行时,此代码只会在控制台打印消息
Debug.Log("Application Quit!");
}
}
✅ 总结与发布(Final Build)
- 最终检查: 确保所有场景内容完整且已保存。
- Player Settings 配置: 设置公司名、产品名和游戏图标。
- 打包: 在 Build Settings 中选择目标平台 (PC/Mac/Linux),点击 Build 导出可执行文件。