3D作業4--遊戲對象與圖形基礎

基本操作演練【建議做】

下載 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的添加方式:

  1. 直接在菜單上(scene中)創建添加;
  2. 在代碼中通過Instantiate() 函數實例化預製來創建;
  3. 下載現有的遊戲對象到自己項目的Asset然後使用。
    可以根據具體使用情況選擇添加的方式。

此外,我還學習到了GameObject的組件修改方法:

  1. 通過右側的Inspector欄來進行調節一些基礎的組件(如Transform、Filter、Render等)
  2. 通過腳本的方式修改其屬性

編程實踐

牧師與魔鬼 動作分離版

【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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章