課程大綱
- 第一週 (4/17) ♥♥
- Unity程式基礎 範例專案下載
- string字串,int整數,bool布林
//要買的飲料是什麼,要幾杯,老闆帥不帥 public string 飲料="珍奶"; public int 幾杯=1; public bool 老闆帥=true;
- Debug.Log(s)
- if else 條件語句
- for 迴圈
- transform.Translate(x,y,z) 物件移動
- transform.Rotate(x,y,z) 物件旋轉
- Input.GetMouseButtonDown(Button) 檢查滑鼠輸入
- Input.GetKey(KeyCode key) 檢查鍵盤輸入
- PlayerController.cs
//將要顯示的句子用 + 組合起來一次顯示出來 Debug.Log ("老闆我要"+幾杯+"杯"+飲料);
//如果老闆帥就要電話,如果不帥就叫老闆快點 if (老闆帥) { Debug.Log ("老闆可以給我你的電話號碼嗎"); } else { Debug.Log ("老闆可以快點嗎 我趕時間"); }
//睡不著的時候用迴圈數羊 Debug.Log ("睡不著覺來數羊"); //從第1隻開始數,要數到1000隻 for (int 第幾 = 1; 第幾 < 1000; 第幾++) { Debug.Log (第幾 + "隻羊");//現在數到第幾隻 //數到300隻就睡著了 if (第幾 == 300) { Debug.Log ("zzzZZZ");// zzzZZZ 睡著了 break; //已經睡著就不再數了 } }
//Unity中OnGUI函式可以在畫面上畫出簡單的GUI void OnGUI (){ //如果GUI上的按鈕被按下 //這個按鈕在X10,Y10的地方,寬200,高30,上面寫著X ++的字 if (GUI.Button(new Rect(10,10,200,30),"X ++")) { //讓物件向X軸移動1單位 Target.transform.Translate (1,0,0); } if (GUI.Button(new Rect(210,10,200,30),"X --")) { Target.transform.Translate (-1,0,0); } if (GUI.Button(new Rect(10,40,200,30),"Y ++")) { Target.transform.Translate (0,1,0); } if (GUI.Button(new Rect(210,40,200,30),"Y --")) { Target.transform.Translate (0,-1,0); } if (GUI.Button(new Rect(10,70,200,30),"Z ++")) { Target.transform.Translate (0,0,1); } if (GUI.Button(new Rect(210,70,200,30),"Z --")) { Target.transform.Translate (0,0,-1); } //如果按下鍵盤W鍵 if (Input.GetKey(KeyCode.W)) { Target.transform.Translate (0,0,1);//向z軸移動 } //如果按下鍵盤S鍵 if (Input.GetKey(KeyCode.S)) { Target.transform.Translate (0,0,-1);//向z軸反方向移動 } }
//Unity中OnGUI函式可以在畫面上畫出簡單的GUI void OnGUI (){ //如果GUI上的按鈕被按下 //這個按鈕在X10,Y10的地方,寬200,高30,上面寫著X ++的字 if (GUI.Button(new Rect(10,10,200,30),"X ++")) { //讓物件以X軸旋轉10度 Target.transform.Rotate (10,0,0); } if (GUI.Button(new Rect(210,10,200,30),"X --")) { Target.transform.Rotate (-10,0,0); } if (GUI.Button(new Rect(10,40,200,30),"Y ++")) { Target.transform.Rotate (0,10,0); } if (GUI.Button(new Rect(210,40,200,30),"Y --")) { Target.transform.Rotate (0,-10,0); } if (GUI.Button(new Rect(10,70,200,30),"Z ++")) { Target.transform.Rotate (0,0,10); } if (GUI.Button(new Rect(210,70,200,30),"Z --")) { Target.transform.Rotate (0,0,-10); } }
//Unity中Update函式可以在畫面更新時執行一次 void Update() { //如果按下滑鼠左鍵,顯示按下按下滑鼠左鍵 if (Input.GetMouseButtonDown(0)){ Debug.Log("按下滑鼠左鍵"); } if (Input.GetMouseButtonDown(1)){ Debug.Log("按下滑鼠右鍵"); } if (Input.GetMouseButtonDown(2)){ Debug.Log("按下滑鼠中鍵"); } //Input.GetAxis("Mouse X") 可以取得滑鼠左右移動的差值 Target.transform.Rotate (0,Input.GetAxis("Mouse X"),0);//依取得的差值用Y軸旋轉(即左右旋轉) }
//Unity中Update函式可以在畫面更新時執行一次 void Update() { //如果按下鍵盤向上方向鍵,顯示向上方向鍵被按了 if (Input.GetKey(KeyCode.UpArrow)){ print("向上方向鍵被按了"); } //如果按下鍵盤向下方向鍵,顯示向下方向鍵被按了 if (Input.GetKey(KeyCode.DownArrow)){ print("向下方向鍵被按了"); } }
//Unity中Update函式可以在畫面更新時執行一次 void Update() { //用鍵盤控制移動 if(Input.GetKey(KeyCode.W)){ gameObject.transform.Translate(0,0,.1f); } if(Input.GetKey(KeyCode.S)){ gameObject.transform.Translate(0,0,-.1f); } if(Input.GetKey(KeyCode.D)){ gameObject.transform.Translate(.1f,0,0); } if(Input.GetKey(KeyCode.A)){ gameObject.transform.Translate(-.1f,0,0); } //用鍵盤控制旋轉 if(Input.GetKey(KeyCode.E)){ gameObject.transform.Rotate(0,10,0); } if(Input.GetKey(KeyCode.Q)){ gameObject.transform.Rotate(0,-10,0); } //用滑鼠控制旋轉 gameObject.transform.Rotate(0,Input.GetAxis("Mouse X")*10,0); }
- Unity程式基礎 範例專案下載
- 多人連線遊戲 完整步驟
- 開新專案(3D)->建立新場景->儲存場景取名叫Main
- 在場景中建立一個空物件(重新命名為NetworkManager)->在該物件上加入NetworkManager及NetworkManagerHUD組件
- 製作Player遊戲物件->在該遊戲物件上加入NetworkIdentity組件(並勾選Local Player Authority)
- 將Player Prefab加入NetworkManager/Spwan Info/Player Prefab中
- 在Player Prefab上加入一個新的程式PlayerController->執行看看
using UnityEngine; public class PlayerController : MonoBehaviour { void Update() { var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0);//旋轉 transform.Translate(0, 0, z);//前進後退 } }
- 修改PlayerController程式->在Player Prefab上加入NetworkTransform組件
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { void Update() { if (!isLocalPlayer) { return; } var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0); transform.Translate(0, 0, z); } }
- 修改PlayerController程式(讓連線時可以分辯)
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { void Update() { if (!isLocalPlayer) { return; } var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0); transform.Translate(0, 0, z); } public override void OnStartLocalPlayer() { GetComponent
().material.color = Color.blue; } }
步驟1-7 影片參考 - 建立遊戲物件命名為Bullet->加入Rigidbody並製作成Prefab->修改PlayerController程式
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { public GameObject bulletPrefab; public Transform bulletSpawn; void Update() { if (!isLocalPlayer) { return; } var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0); transform.Translate(0, 0, z); if (Input.GetKeyDown(KeyCode.Space)) { Fire(); } } void Fire() { // Create the Bullet from the Bullet Prefab var bullet = (GameObject)Instantiate( bulletPrefab, bulletSpawn.position, bulletSpawn.rotation); // Add velocity to the bullet bullet.GetComponent
().velocity = bullet.transform.forward * 6; // Destroy the bullet after 2 seconds Destroy(bullet, 2.0f); } public override void OnStartLocalPlayer () { GetComponent ().material.color = Color.blue; } }
步驟8 影片參考 - Bullet Prefab上加入NetworkIdentity和NetworkTransform(並將NetworkTransform中的Network Send Rate設為0)->並把Bullet Prefab加入NetworkManager/Spwan Info/Registered Spawnable Prefabs中->更新PlayerController程式
using UnityEngine; using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { public GameObject bulletPrefab; public Transform bulletSpawn; void Update() { if (!isLocalPlayer) { return; } var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; transform.Rotate(0, x, 0); transform.Translate(0, 0, z); if (Input.GetKeyDown(KeyCode.Space)) { CmdFire(); } } // This [Command] code is called on the Client … // … but it is run on the Server! [Command] void CmdFire() { // Create the Bullet from the Bullet Prefab var bullet = (GameObject)Instantiate( bulletPrefab, bulletSpawn.position, bulletSpawn.rotation); // Add velocity to the bullet bullet.GetComponent
().velocity = bullet.transform.forward * 6; // Spawn the bullet on the Clients NetworkServer.Spawn(bullet); // Destroy the bullet after 2 seconds Destroy(bullet, 2.0f); } public override void OnStartLocalPlayer () { GetComponent ().material.color = Color.blue; } }
步驟9 影片參考 - 建立子彈碰撞後銷毀程式->加入使用者血量和血量程式以及讓血量固定面向攝影機
using UnityEngine; using System.Collections; public class Bullet : MonoBehaviour { void OnCollisionEnter(Collision collision) { var hit = collision.gameObject; var health = hit.GetComponent
(); if (health != null) { health.TakeDamage(10); } Destroy(gameObject); } } using UnityEngine; using UnityEngine.UI; using System.Collections; public class Health : MonoBehaviour { public const int maxHealth = 100; public int currentHealth = maxHealth; public RectTransform healthBar; public void TakeDamage(int amount) { currentHealth -= amount; if (currentHealth <= 0) { currentHealth = 0; Debug.Log("Dead!"); } healthBar.sizeDelta = new Vector2(currentHealth, healthBar.sizeDelta.y); } }
using UnityEngine; using System.Collections; public class Billboard : MonoBehaviour { void Update () { transform.LookAt(Camera.main.transform); } }
步驟10 影片參考 - 修改血量程式由Server端處理並同步
using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using System.Collections; public class Health : NetworkBehaviour { public const int maxHealth = 100; [SyncVar(hook = "OnChangeHealth")] public int currentHealth = maxHealth; public RectTransform healthBar; public void TakeDamage(int amount) { if (!isServer) return; currentHealth -= amount; if (currentHealth <= 0) { currentHealth = 0; Debug.Log("Dead!"); } } void OnChangeHealth (int health) { healthBar.sizeDelta = new Vector2(health, healthBar.sizeDelta.y); } }
步驟11 影片參考 - 修改血量程式(角色死亡和重生)
using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using System.Collections; public class Health : NetworkBehaviour { public const int maxHealth = 100; [SyncVar(hook = "OnChangeHealth")] public int currentHealth = maxHealth; public RectTransform healthBar; public void TakeDamage(int amount) { if (!isServer) return; currentHealth -= amount; if (currentHealth <= 0) { currentHealth = maxHealth; // called on the Server, but invoked on the Clients RpcRespawn(); } } void OnChangeHealth (int currentHealth ) { healthBar.sizeDelta = new Vector2(currentHealth , healthBar.sizeDelta.y); } [ClientRpc] void RpcRespawn() { if (isLocalPlayer) { // move back to zero location transform.position = Vector3.zero; } } }
步驟12 影片參考
- 參考資料Multiplayer Networking
- 練習/提問
- 第二週進度專案下載