完成品: 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(內附教學文件)
