3D遊戲04——遊戲對象與圖形基礎

基本操作演練

1. 下載 Fantasy Skybox FREE, 構建自己的遊戲場景

  • 方法一:在Asset Store中購買天空盒素材,在場景中直接添加下載後的天空盒素材
    在這裏插入圖片描述
    導入天空盒素材
  • 方法二
    創建一個Material,把shader的值改爲skybox->6side
    在這裏插入圖片描述
  • 拖入六張貼圖素材
    在這裏插入圖片描述
  • 就完成天空盒了
    在這裏插入圖片描述
  • 下面創建地面,插入一個Terrain, 在Inspector面板調整它的形狀屬性。
  • 插入一些樹木和石頭素材
  • 完成一個如下的地面場景
    在這裏插入圖片描述
    運行遊戲,試試在場景中穿梭的感覺:
    在這裏插入圖片描述

編程實踐

牧師與魔鬼 動作分離版

關於如何實現動作分離。我們可以將遊戲對象的一個完整動作提取成幾個基礎動作,用類的方法來執行這些動作。同時,增加動作對象管理者,去調度遊戲對象執行動作。
在這裏插入圖片描述

  • 動作管理類,通過ActionManager接口管理動作集合
    //動作管理接口
    public class ActionManager : System.Object
    {
        private static ActionManager ins;

        public static ActionManager get_instance()
        {
            if (ins == null)
            {
                ins = new ActionManager();
            }
            return ins;
        }


        public UAction ApplyMoveToAction(GameObject obj, Vector3 target, float speed, ActionCompleted completed)
        {
            MoveToAction ac = obj.AddComponent<MoveToAction>();
            ac.setting(target, speed, completed);
            return ac;
        }

        public UAction ApplyMoveToAction(GameObject obj, Vector3 target, float speed)
        {
            return ApplyMoveToAction(obj, target, speed, null);
        }

        //對象在平面上的平移動作
        public UAction ApplyMoveToTrans(GameObject obj, Vector3 target, float speed, ActionCompleted completed)
        {
            MoveToTrans ac = obj.AddComponent<MoveToTrans>();
            ac.setting(obj, target, speed, completed);
            return ac;
        }

        public UAction ApplyMoveToTrans(GameObject obj, Vector3 target, float speed)
        {
            return ApplyMoveToTrans(obj, target, speed, null);
        }
    }
  • MoveToAction類實現遊戲對象動作的分配
  • 方法setting設置target, speed和monitor的值
  • 方法update以step位幀,對遊戲對象的狀態進行更新。當monitor爲null時,意味着動作完成,Destroy實例
    public class MoveToAction : UActionAuto
    {
        public Vector3 target;
        public float speed;

        private ActionCompleted monitor = null;

        public void setting(Vector3 target, float speed, ActionCompleted monitor)
        {
            this.target = target;
            this.speed = speed;
            this.monitor = monitor;
            GameSceneController.GetInstance().Set_move(true);
        }

        void Update()
        {
            float step = speed * Time.deltaTime;
            transform.position = Vector3.MoveTowards(transform.position, target, step);

            if (transform.position == target)
            {
                GameSceneController.GetInstance().Set_move(false);
                if (monitor != null)
                {
                    monitor.OnActionCompleted(this);
                }
                Destroy(this);
            }
        }
    }
  • 對MoveToAction類進行進一步動作分離。我們可以把遊戲對象(牧師、魔鬼、船)的動作歸類爲:左右平移(y方向)和上下平移(z方向)
  • 我們建立MoveToTrans類實現動作的分離和組合
 public class MoveToTrans : UActionAuto, ActionCompleted
    {
        public GameObject obj;
        public Vector3 target;
        public float speed;

        private ActionCompleted monitor = null;

        public void setting(GameObject obj, Vector3 target, float speed, ActionCompleted monitor)
        {
            this.obj = obj;
            this.target = target;
            this.speed = speed;
            this.monitor = monitor;
            GameSceneController.GetInstance().Set_move(true);

            /*obj比target高,先移動target.z, 再移動target.y
              obj比target低,先移動target.y,再移動target.z
             */
            if (target.y < obj.transform.position.y)
            {
                Vector3 targetZ = new Vector3(target.x, obj.transform.position.y, target.z);
                ActionManager.get_instance().ApplyMoveToAction(obj, targetZ, speed, this);
            }
            else
            {
                Vector3 targetY = new Vector3(target.x, target.y, obj.transform.position.z);
                ActionManager.get_instance().ApplyMoveToAction(obj, targetY, speed, this);
            }
        }

        public void OnActionCompleted(UAction action)
        {
            //用回調函數調用下一個動作
            ActionManager.get_instance().ApplyMoveToAction(obj, target, speed, null);
        }

        void Update()
        {
            if (obj.transform.position == target)
            {
                GameSceneController.GetInstance().Set_move(false);
                if (monitor != null)
                {
                    monitor.OnActionCompleted(this);
                }
                Destroy(this);
            }
        }  
  • 設計一個裁判類,當遊戲達到結束條件時,通知場景控制器遊戲結束

    • 在上一版遊戲中,我用一個enum類型存儲遊戲的狀態,而這一次我們用發送message的方式通知控制器遊戲的狀態
    • 我把裁判類定義成一個public接口,其功能包括向控制器發送消息(是否繼續遊戲,是否終止)和檢查遊戲當前的狀態
    	  //裁判類,向控制器發送遊戲信息
    	public interface Judgement
    	{
    	 void Set_move(bool s);
    	 bool Is_moving();
    	 void Set_message(string s);
    	 string Is_message();
    	}
    
    • 發送消息
    scene.Set_message("Win!"); //scene是 GameSceneController對象
    scene.Set_message("Lose!");
    
    • 查詢狀態
    	if (message != "") {
        if (GUI.Button(new Rect(stw(2f), sth(6f), width, height), "Your Win!")){
                act.restart();
            } }
        else
        {  //通過接口實現動作
            if (!state.Is_moving())
           	 ......
    

遊戲傳送門

材料與渲染聯繫

  • 從 Unity 5 開始,使用新的 Standard Shader 作爲自然場景的渲染。
    • 閱讀官方 Standard Shader 手冊 。
    • 選擇合適內容,如 Albedo Color and Transparency,尋找合適素材,用博客展示相關效果的呈現

Standard Shader是一個Unity的內置着色器,具有一組全面的特性。可以爲物體渲染出具有 “真實世界” 的物理效果,如石頭、木頭、玻璃、塑料、金屬等。

在Material的standard欄中,我們可以調整Albedo(反射率)
在Rendering Mode中選擇transparency,調整透明度
在這裏插入圖片描述
調整Metallic的值,可以改變物體材料的金屬感,smotheness表示材料的光滑程度。一般情況下金屬的smothness值較高
在這裏插入圖片描述
我們製作幾個材料來演示效果:
在這裏插入圖片描述
玻璃效果的球體:
在這裏插入圖片描述
在這裏插入圖片描述

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