目錄
基本操作演練【建議做】
下載 Fantasy Skybox FREE, 構建自己的遊戲場景
使用unity打開asset store,搜索“Fantasy Skybox FREE”並下載,
之後import使用,得到以下頁面,點擊import。
創建一個新的Material(菜單 Assets→create→Material),更改Shader爲Skybox-6 Sided(右邊Inspector欄→shader→skybox→6 sided),按前後(Z)、上下(Y)、左右(X)拖入6個圖片(在Fantasy Skybox Free中的Textures文件夾的貼圖文件,或者在Inspector欄中點擊select按名字進行選擇),至此製作完成,便可拖入使用
寫一個簡單的總結,總結遊戲對象的使用
當需要在新的一個project使用已經下載過的skybox時,可在asset store中賬號管理(右上角的L圓圈)中的My assets中找到。
至此,我學習到了多種GameObject的添加方式:
- 直接在菜單上(scene中)創建添加;
- 在代碼中通過Instantiate() 函數實例化預製來創建;
- 下載現有的遊戲對象到自己項目的Asset然後使用。
可以根據具體使用情況選擇添加的方式。
此外,我還學習到了GameObject的組件修改方法:
- 通過右側的Inspector欄來進行調節一些基礎的組件(如Transform、Filter、Render等)
- 通過腳本的方式修改其屬性
編程實踐
牧師與魔鬼 動作分離版
【2019新要求】:設計一個裁判類,當遊戲達到結束條件時,通知場景控制器遊戲結束
調整Controller的結構到Action類
首先,重新調整Controller的結構,創建一個Action類,使其在不同控制器中進行實例化以實現各遊戲對象移動操作的轉移,並將動作的實現放在Action中。即在調用動作時,改爲調用Action類中的該動作函數。修改前的代碼和修改後的代碼如下(主要是對Controller腳本的修改,其餘的只需修改調用函數即可,這裏就沒有貼上來了)
修改前:
using UnityEngine;
namespace MyNamespace {
public enum Location { left, right }
public class CoastController {
public Coast coast;
public CoastController(string _location) {
coast = new Coast(_location);
}
public int GetEmptyIndex() {
for (int i = 0; i < coast.characters.Length; ++i) {
if (coast.characters[i] == null) {
return i;
}
}
return -1;
}
public Vector3 GetEmptyPosition() {
Vector3 pos = coast.positions[GetEmptyIndex()];
pos.x *= (coast.Location == Location.right ? 1 : -1);
return pos;
}
public void GetOnCoast(CharacterController character) {
int index = GetEmptyIndex();
coast.characters[index] = character;
}
public void GetOffCoast(string passenger_name) {
for (int i = 0; i < coast.characters.Length; ++i) {
if (coast.characters[i] != null &&
coast.characters[i].character.Name == passenger_name) {
coast.characters[i] = null;
}
}
}
public int[] GetCharacterNum() {
int[] count = { 0, 0 };
for (int i = 0; i < coast.characters.Length; ++i) {
if (coast.characters[i] != null) {
if (coast.characters[i].character.Name.Contains("priest")) {
count[0]++;
} else {
count[1]++;
}
}
}
return count;
}
public void Reset() {
coast.characters = new CharacterController[6];
}
}
public class BoatController {
public Boat boat;
public BoatController() {
boat = new Boat();
}
public void Move() {
if (boat.Location == Location.left) {
boat.mScript.SetDestination(boat.departure);
boat.Location = Location.right;
} else {
boat.mScript.SetDestination(boat.destination);
boat.Location = Location.left;
}
}
public int GetEmptyIndex() {
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] == null) {
return i;
}
}
return -1;
}
public bool IsEmpty() {
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] != null) {
return false;
}
}
return true;
}
public Vector3 GetEmptyPosition() {
Vector3 pos;
int emptyIndex = GetEmptyIndex();
if (boat.Location == Location.right) {
pos = boat.departures[emptyIndex];
} else {
pos = boat.destinations[emptyIndex];
}
return pos;
}
public void GetOnBoat(CharacterController character) {
int index = GetEmptyIndex();
boat.passenger[index] = character;
}
public void GetOffBoat(string passenger_name) {
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] != null &&
boat.passenger[i].character.Name == passenger_name) {
boat.passenger[i] = null;
}
}
}
public int[] GetCharacterNum() {
int[] count = { 0, 0 };
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] != null) {
if (boat.passenger[i].character.Name.Contains("priest")) {
count[0]++;
} else {
count[1]++;
}
}
}
return count;
}
public void Reset() {
boat.mScript.Reset();
if (boat.Location == Location.left) {
Move();
}
boat.passenger = new CharacterController[2];
}
}
public class CharacterController {
readonly UserGUI userGUI;
public Character character;
public CharacterController(string _name) {
character = new Character(_name);
userGUI = character.Role.AddComponent(typeof(UserGUI)) as UserGUI;
userGUI.SetCharacterCtrl(this);
}
public void SetPosition(Vector3 _pos) {
character.Role.transform.position = _pos;
}
public void MoveTo(Vector3 _pos) {
character.mScript.SetDestination(_pos);
}
public void GetOnBoat(BoatController boatCtrl) {
character.Coast = null;
character.Role.transform.parent = boatCtrl.boat._Boat.transform;
character.IsOnBoat = true;
}
public void GetOnCoast(CoastController coast) {
character.Coast = coast;
character.Role.transform.parent = null;
character.IsOnBoat = false;
}
public void Reset() {
character.mScript.Reset();
character.Coast = (Director.GetInstance().CurrentSecnController as FirstController).rightCoastCtrl;
GetOnCoast(character.Coast);
SetPosition(character.Coast.GetEmptyPosition());
character.Coast.GetOnCoast(this);
}
}
}
修改後:
using UnityEngine;
namespace MyNamespace {
public enum Location { left, right }
public class CoastController {
public Coast coast;
public Action coastAction = new Action();
public CoastController(string _location) {
coast = new Coast(_location);
}
public int GetEmptyIndex() {
for (int i = 0; i < coast.characters.Length; ++i) {
if (coast.characters[i] == null) {
return i;
}
}
return -1;
}
public Vector3 GetEmptyPosition() {
Vector3 pos = coast.positions[GetEmptyIndex()];
pos.x *= (coast.Location == Location.right ? 1 : -1);
return pos;
}
public int[] GetCharacterNum() {
int[] count = { 0, 0 };
for (int i = 0; i < coast.characters.Length; ++i) {
if (coast.characters[i] != null) {
if (coast.characters[i].character.Name.Contains("priest")) {
count[0]++;
} else {
count[1]++;
}
}
}
return count;
}
public void Reset() {
coast.characters = new CharacterController[6];
}
}
public class BoatController {
public Boat boat;
public Action boatAction = new Action();
public BoatController() {
boat = new Boat();
}
public int GetEmptyIndex() {
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] == null) {
return i;
}
}
return -1;
}
public bool IsEmpty() {
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] != null) {
return false;
}
}
return true;
}
public Vector3 GetEmptyPosition() {
Vector3 pos;
int emptyIndex = GetEmptyIndex();
if (boat.Location == Location.right) {
pos = boat.departures[emptyIndex];
} else {
pos = boat.destinations[emptyIndex];
}
return pos;
}
public int[] GetCharacterNum() {
int[] count = { 0, 0 };
for (int i = 0; i < boat.passenger.Length; ++i) {
if (boat.passenger[i] != null) {
if (boat.passenger[i].character.Name.Contains("priest")) {
count[0]++;
} else {
count[1]++;
}
}
}
return count;
}
public void Reset() {
boat.mScript.Reset();
if (boat.Location == Location.left) {
boatAction.boatMove(this);
}
boat.passenger = new CharacterController[2];
}
}
public class CharacterController {
readonly UserGUI userGUI;
public Character character;
public Action myAction = new Action();
public CharacterController(string _name) {
character = new Character(_name);
userGUI = character.Role.AddComponent(typeof(UserGUI)) as UserGUI;
userGUI.SetCharacterCtrl(this);
}
public void SetPosition(Vector3 _pos) {
character.Role.transform.position = _pos;
}
public void MoveTo(Vector3 _pos) {
character.mScript.SetDestination(_pos);
}
public void Reset() {
character.mScript.Reset();
character.Coast = (Director.GetInstance().CurrentSecnController as FirstController).rightCoastCtrl;
myAction.GetOnCoast(this, character.Coast);
SetPosition(character.Coast.GetEmptyPosition());
//character.Coast.GetOnCoast(this);
}
}
public class Action {
//船移動
public void boatMove(BoatController boatCtrl) {
if (boatCtrl.boat.Location == Location.left) {
boatCtrl.boat.mScript.SetDestination(boatCtrl.boat.departure);
boatCtrl.boat.Location = Location.right;
} else {
boatCtrl.boat.mScript.SetDestination(boatCtrl.boat.destination);
boatCtrl.boat.Location = Location.left;
}
}
//上船
public void GetOnBoat(CharacterController charactrl, BoatController boatCtrl) {
//船控制器
int index = boatCtrl.GetEmptyIndex();
boatCtrl.boat.passenger[index] = charactrl;
//人物控制器
charactrl.character.Coast = null;
charactrl.character.Role.transform.parent = boatCtrl.boat._Boat.transform;
charactrl.character.IsOnBoat = true;
}
//下船
public void GetOffBoat(string passenger_name, BoatController boatCtrl) {
for (int i = 0; i < boatCtrl.boat.passenger.Length; ++i) {
if (boatCtrl.boat.passenger[i] != null &&
boatCtrl.boat.passenger[i].character.Name == passenger_name) {
boatCtrl.boat.passenger[i] = null;
}
}
}
//上岸
public void GetOnCoast(CharacterController charactrl,CoastController coastctrl) {
//船
int index = coastctrl.GetEmptyIndex();
coastctrl.coast.characters[index] = charactrl;
//人物
charactrl.character.Coast = coastctrl;
charactrl.character.Role.transform.parent = null;
charactrl.character.IsOnBoat = false;
}
//下岸
public void GetOffCoast(string passenger_name, CoastController coastctrl) {
for (int i = 0; i < coastctrl.coast.characters.Length; ++i) {
if (coastctrl.coast.characters[i] != null &&
coastctrl.coast.characters[i].character.Name == passenger_name) {
coastctrl.coast.characters[i] = null;
}
}
}
}
}
調整FirstController到Judge類
其次,理論上,同樣的道理,因爲FirstController需要管理的事情太多,所以需要將判斷遊戲輸贏的check函數分離出來,交給單獨的一個類管理,但在這裏我並沒有進行修改(其實修改也很簡單,操作同之前的操作即可,只需創建一個新的裁判類Judge,將原代碼中的check 函數更改爲Judge中的函數即可),原因是我的check函數功能比較集中(沒有分checkWin和checkLose而是一整個函數,要是單獨出來,新類Judge也只有一個函數的功能,意義不大)。
遊戲截圖
最後出來的遊戲截圖:
完整代碼請見我的Github