完成品: Unity3D-Game2
設定:
Floor
Create -> Cube
Scale: 8, 1, 2.5
platform_end
Scale: 0.5, 0.2, 1
platform_middle
Scale: 1, 0.2, 1
|
V
platform
Create Empty
Reset
Drag -> Prefab
Edge Trigger
Position:
Scale:
Add -> EdgeTrigger.cs
Main Camera
tag: Main Camera
Change -> Background(195, 114, 214, 5)
Add -> GameControl.cs
platformPrefab
Add -> GameGUI.cs
Character
Add -> Sphere
Scale:
|
V
Player
tag: Player
untick -> Mesh Renderer
Add -> Rigidbody
tick -> Freeze Rotation: XYZ
Add -> Physics/Configurable Joint
Anchor Y:1
zMotion Locked
Angular xMotion Locked
Angular YMotion Locked
Angular zMotion Locked
Slerp Drive/Max.Force:0
Angular XDrive/Max.Force:0
Angular YZDrive/Max.Force:0
Add -> Playermovement.cs
程式碼:
GameControl.cs
using UnityEngine; using System.Collections; // 定義常數--遊戲狀態--playing, gameover public enum GameState { playing, gameover }; public class GameControl : MonoBehaviour { // 設定預製物件(浮台) public Transform platformPrefab; // 設定遊戲狀態 public static GameState gameState; // 加入玩家 private Transform playerTrans; // 設定浮台高度 private float platformsSpawnedUpTo = 0.0f; // 設定浮台陣列 private ArrayList platforms; private float nextPlatformCheck = 0.0f; void Awake () { // 找尋標籤Player playerTrans = GameObject.FindGameObjectWithTag("Player").transform; // 新浮台陣列 platforms = new ArrayList(); SpawnPlatforms(25.0f); StartGame(); } // 開始遊戲 void StartGame() { // 遊戲場景播放--正常 Time.timeScale = 1.0f; // 遊戲狀態 playing gameState = GameState.playing; } // 結束遊戲 void GameOver() { // 遊戲場景播放--暫停 Time.timeScale = 0.0f; //Pause the game // 遊戲狀態 gameover gameState = GameState.gameover; // 載入 GameGUI GameGUI.SP.CheckHighscore(); } // 更新攝影機, 浮台, 玩家 void Update () { //Do we need to spawn new platforms yet? (we do this every X meters we climb) float playerHeight = playerTrans.position.y; if (playerHeight > nextPlatformCheck) { PlatformMaintenaince(); //Spawn new platforms } // 攝影機跟隨玩家位置 , 玩家低過攝影機高度 -> 遊戲狀態 gameover //Update camera position if the player has climbed and if the player is too low: Set gameover. float currentCameraHeight = transform.position.y; float newHeight = Mathf.Lerp(currentCameraHeight, playerHeight, Time.deltaTime * 10); if (playerTrans.position.y > currentCameraHeight) { transform.position = new Vector3(transform.position.x, newHeight, transform.position.z); }else{ //Player is lower..maybe below the cameras view? if (playerHeight < (currentCameraHeight - 10)) { GameOver(); } } // 更新分數 -- 玩家新分數大過舊分數, 記錄新分數替代 //Have we reached a new score yet? if (playerHeight > GameGUI.score) { GameGUI.score = (int)playerHeight; } } void PlatformMaintenaince() { nextPlatformCheck = playerTrans.position.y + 10; //Delete all platforms below us (save performance) for(int i = platforms.Count-1;i>=0;i--) { Transform plat = (Transform)platforms[i]; if (plat.position.y < (transform.position.y - 10)) { Destroy(plat.gameObject); platforms.RemoveAt(i); } } //Spawn new platforms, 25 units in advance SpawnPlatforms(nextPlatformCheck + 25); } // 複製浮台 void SpawnPlatforms(float upTo) { float spawnHeight = platformsSpawnedUpTo; while (spawnHeight <= upTo) { // 浮台在水平範圍生成(以0,X 為中心延伸) //float x = Random.Range(-10.0f, 10.0f); float x = Random.Range(-4.0f, 4.0f); // 浮台生成位置--X水平, Y垂直, Z深度 (深度需調較和地面Z深度一致) //Vector3 pos = new Vector3(spawnHeight, x, 12.0f); Vector3 pos = new Vector3(x, spawnHeight, 0f); Transform plat = (Transform)Instantiate(platformPrefab, pos, Quaternion.identity); platforms.Add(plat); // 浮台在垂直範圍生成-(最低位置, 最高位置) // 需留意玩家高度計劃難度(以X,0 為中心延伸) //spawnHeight += Random.Range(3.0f, 5.0f); spawnHeight += Random.Range(1.6f, 3.5f); } platformsSpawnedUpTo = upTo; } } // 作者: http://www.m2h.nl/ // 原檔案: https://www.assetstore.unity3d.com/#/content/116(內附教學文件)
Playermovement.cs
using UnityEngine; using System.Collections; public class Playermovement : MonoBehaviour { // 玩家移動設定 public float movementSpeed = 5.0f; private bool isGrounded = false; void Update() { // 設定X和Z速度為0 //Set X and Z velocity to 0 rigidbody.velocity = new Vector3(0, rigidbody.velocity.y, 0); transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * movementSpeed, 0, 0); /*if (Input.GetButtonDown("Jump") && isGrounded) { Jump(); //Manual jumping }*/ } // 玩家跳高 void Jump() { if (!isGrounded) { return; } isGrounded = false; rigidbody.velocity = new Vector3(0, 0, 0); // 玩家跳高設定Y rigidbody.AddForce(new Vector3(0, 700, 0), ForceMode.Force); } void FixedUpdate() { isGrounded = Physics.Raycast(transform.position, -Vector3.up, 1.0f); if (isGrounded) { Jump(); //Automatic jumping } } } // 作者: http://www.m2h.nl/ // 原檔案: https://www.assetstore.unity3d.com/#/content/116(內附教學文件)
GameGUI.cs
using UnityEngine; using System.Collections; public class GameGUI : MonoBehaviour { public static GameGUI SP; // 設定分數 public static int score; // 設定最高分數 private int bestScore = 0; void Awake() { SP = this; score = 0; bestScore = PlayerPrefs.GetInt("BestScorePlatforms", 0); } void OnGUI() { GUILayout.Space(3);// 垂直間距 GUILayout.Label(" Score: " + score); GUILayout.Label(" Highscore: " + bestScore); // 載入 GameControl 遊戲狀態 gameover if (GameControl.gameState == GameState.gameover) { GUILayout.BeginArea(new Rect(0, 0, Screen.width, Screen.height)); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); GUILayout.Label("Game over!"); if (score > bestScore) { GUI.color = Color.red; GUILayout.Label("New highscore!"); GUI.color = Color.white; } if (GUILayout.Button("Try again")) { Application.LoadLevel(Application.loadedLevel); } GUILayout.FlexibleSpace(); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndArea(); } } // 檢查及儲存最高分數 public void CheckHighscore() { if (score > bestScore) { PlayerPrefs.SetInt("BestScorePlatforms", score); } } } // 作者: http://www.m2h.nl/ // 原檔案: https://www.assetstore.unity3d.com/#/content/116(內附教學文件)
EdgeTrigger.cs
using UnityEngine; using System.Collections; public class EdgeTrigger : MonoBehaviour { //You could implement this yourself.. void OnTriggerEnter(){ Debug.Log("OnTriggerEnter.."); } } // 作者: http://www.m2h.nl/ // 原檔案: https://www.assetstore.unity3d.com/#/content/116(內附教學文件)