• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 3D游戲編程與設計——游戲對象與圖形基礎章節作業與練習

    標簽: Unity3d游戲開發

    3D游戲編程與設計——游戲對象與圖形基礎章節作業與練習

    自學資源

    • 結構類型

    結構類型(“structure type”或“struct type”)是一種可封裝數據和相關功能的值類型 。

    由于結構類型具有值語義,因此建議定義不可變的 結構類型。

    示例:

    public struct Coords
    {
        public Coords(double x, double y)
        {
            X = x;
            Y = y;
        }
        public double X { get; }
        public double Y { get; }
        public override string ToString() => $"({X}, {Y})";
    }
    
    1. 可以使用 readonly 修飾符來聲明結構類型不可變
    2. readonly 結構的所有數據成員都必須是只讀的
    3. 不能聲明無參數構造函數。
    4. 不能在聲明實例字段或屬性時對它們進行初始化。
    5. 結構類型的構造函數必須初始化該類型的所有實例字段。
    6. 結構類型不能從其他類或結構類型繼承,也不能作為類的基礎類型。 但是,結構類型可以實現接口。
    7. 不能在結構類型中聲明終結器。
    8. 可以在結構類型的聲明中使用 ref 修飾符。 ref 結構類型的實例在堆棧上分配,并且不能轉義到托管堆。
    • 枚舉類型

    枚舉類型 是由基礎整型數值類型的一組命名常量定義的值類型。

    enum Season
    {
        Spring,
        Summer,
        Autumn,
        Winter
    }
    

    默認情況下,枚舉成員的關聯常數值為類型 int;它們從零開始,并按定義文本順序遞增 1。 可以顯式指定任何其他整數數值類型作為枚舉類型的基礎類型。

    enum ErrorCode : ushort
    {
        None = 0,
        Unknown = 1,
        ConnectionLost = 100,
        OutlierReading = 200
    }
    
    1. 不能在枚舉類型的定義內定義方法。若要向枚舉類型添加功能,請創建擴展方法。
    2. 對于任何枚舉類型,枚舉類型與其基礎整型類型之間存在顯式轉換。
    • const關鍵字

    使用 const 關鍵字來聲明某個常量字段或常量局部變量。 常量字段和常量局部變量不是變量并且不能修改。

    const int X = 0;
    public const double GravitationalConstant = 6.673e-11;
    private const string ProductName = "Visual C#";
    

    作業內容

    1、基本操作演練【建議做】

    • 下載 Fantasy Skybox FREE, 構建自己的游戲場景

    主要分為天空盒與地圖的制作。

    天空盒的制作:

    創建一個文件夾為SkyBox,創建一個Material,將Shader改為Skybox/6 Sided或Cubemap并選擇剛剛下載的素材中的某一個素材為原料。

    然后將該SkyBox拖入到Window-Rendering-Lighting-Environment-Skybox Material中。

    在這里插入圖片描述

    地圖的制作:

    在對象欄右擊->3D Object->Terrain,新建一個地圖對象。

    使用Terrain的各項工具繪制地圖, 包括造山,造草,添加細節等等。

    將下載來的素材中的樹和草等細節添加到圖層中:

    在這里插入圖片描述

    在這里插入圖片描述

    整體效果:

    在這里插入圖片描述

    在這里插入圖片描述

    • 寫一個簡單的總結,總結游戲對象的使用
    1. Camera:是游戲的眼鏡,通過Camera來觀察游戲世界。
    2. Light:光源,用來照明或者添加陰影。
    3. Empty空對象:作為載體,掛載游戲腳本或成為其他對象的父對象等用途。
    4. Cube等3D object:搭建游戲世界的組成元素,通過設置其Transform等屬性來變換它們的位置、形態等。
    5. Terrain等:組成元素,又是編輯工具,例如Terrain本身是地圖,然后又附帶了繪制地圖的各項工具(造山、造草等)。

    2、編程實踐

    • 牧師與魔鬼 動作分離版
      • 【2019開始的新要求】:設計一個裁判類,當游戲達到結束條件時,通知場景控制器游戲結束

    項目要求:

    1. 使用專用的對象來管理運動。在本游戲中的運動即對象的移動,現在對象的移動由動作管理器接手,而不是上一個版本的MoveController,現在不再需要為每個對象都加上Move.cs。
    2. 設計一個裁判類,當游戲達到結束條件時,通知場景控制器游戲結束。游戲勝利與失敗的條件均由JudgeController接管,FirstController新增處理JudgeController反饋的JudgeCallback函數,而取消了Check函數。

    優點:代碼結構更健全,方便添加新動作。

    項目結構:

    1. 在上版本的MVC結構下,添加Actions,上版本中的MoveController和Move可以去除,由CCActionManager等來管理相關動作。
    2. 游戲中所有的移動(動作)都與FirstController分離開來,FirstController通過調用CCActionManager的函數來觸發動作。
    3. 判斷游戲狀態的功能從FirstController中分離開來,引入裁判JudgeController來處理游戲狀態事件。
    • Scripts/Actions

    在這里插入圖片描述

    • Scripts/Controllers

    在這里插入圖片描述

    • Scripts/Models

    在這里插入圖片描述

    • Scripts/Views

    在這里插入圖片描述

    代碼詳解:

    Actions:

    ISSActionCallback.cs

    ISSActionCallback是向其他函數通信的接口,當一個動作有了結果之后需要向另一個函數傳遞信息,可通過SSActionEvent回調。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public enum SSActionEventType : int { Started, Competed }
    
    public interface ISSActionCallback
    {
        //回調函數
        void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competed,int intParam = 0,string strParam = null,Object objectParam = null);
    }
    

    SSAction.cs

    SSAction是動作類的基類。gameObject為動作作用的實體對象。callback是回調接口,當動作類需要向別的類傳遞信息時,就通過ISSActionCallback接口來實現。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SSAction : ScriptableObject
    {
        public bool enable = true;
        public bool destroy = false;
    
        public GameObject gameObject { get; set; }
        public Transform transform { get; set; }
        public ISSActionCallback callback { get; set; }
    
        protected SSAction()
        {
    
        }
    
        public virtual void Start()
        {
            throw new System.NotImplementedException();
        }
    
        public virtual void Update()
        {
            throw new System.NotImplementedException();
        }
    }
    

    SSActionManager.cs

    SSActionManager是動作管理類的基類,作為動作生成、運行與銷毀的管理者。

    actions存儲正在運行中的動作。

    waitingAdd存儲即將運行的動作。

    waitingDelete存儲即將被刪除的動作。

    Update()每次會將waitingAdd中的動作加入到actions當中,然后遍歷運行actions中的動作,如果動作已經結束,則加入到waitingDelete中,最后將waitingDelete中的動作刪除并銷毀。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class SSActionManager : MonoBehaviour
    {
        // 動作集,以字典形式存在
        private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();
        // 等待被加入的動作隊列(動作即將開始)
        private List<SSAction> waitingAdd = new List<SSAction>();
        // 等待被刪除的動作隊列(動作已完成)
        private List<int> waitingDelete = new List<int>();
    
        protected void Update()
        {
            // 將waitingAdd中的動作保存
            foreach (SSAction ac in waitingAdd)
                actions[ac.GetInstanceID()] = ac;
            waitingAdd.Clear();
    
            // 運行被保存的事件
            foreach (KeyValuePair<int, SSAction> kv in actions)
            {
                SSAction ac = kv.Value;
                if (ac.destroy)
                {
                    waitingDelete.Add(ac.GetInstanceID());
                }
                else if (ac.enable)
                {
                    ac.Update();
                }
            }
    
            // 銷毀waitingDelete中的動作
            foreach (int key in waitingDelete)
            {
                SSAction ac = actions[key];
                actions.Remove(key);
                Destroy(ac);
            }
            waitingDelete.Clear();
        }
    
        // 準備運行一個動作,將動作初始化,并加入到waitingAdd
        public void RunAction(GameObject gameObject, SSAction action, ISSActionCallback manager)
        {
            action.gameObject = gameObject;
            action.transform = gameObject.transform;
            action.callback = manager;
            waitingAdd.Add(action);
            action.Start();
        }
    
        protected void Start()
        {
    
        }
    }
    

    CCMoveToAction.cs

    CCMoveToAction是移動動作類,將物體以一定速度移動到目的地。

    GetSSAction是生成目標SSAction的函數,使用工廠模式。

    每次調用Update()會使得對象向目的地運動一段距離。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class CCMoveToAction : SSAction
    {
        // 目的地
        public Vector3 target;
        // 速度
        public float speed;
    
        private CCMoveToAction()
        {
    
        }
    
        // 生產函數(工廠模式)
        public static CCMoveToAction GetSSAction(Vector3 target, float speed)
        {
            CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();
            action.target = target;
            action.speed = speed;
            return action;
        }
    
        public override void Start()
        {
    
        }
    
        public override void Update()
        {
            // 判斷是否符合移動條件
            if (this.gameObject == null || this.transform.localPosition == target)
            {
                this.destroy = true;
                this.callback.SSActionEvent(this);
                return;
            }
            // 移動
            this.transform.localPosition = Vector3.MoveTowards(this.transform.localPosition, target, speed * Time.deltaTime);
        }
    }
    

    CCSequenceAction.cs

    CCSequenceAction是組合動作類,包含一系列要進行的動作,并按順序運行這些動作。

    SSActionEvent是回調函數,因為CCSequenceAction是組合動作,因此需要獲得每個動作執行狀態的信息,當一個動作已經完成,就需要執行下一個動作,或者所有動作完成時銷毀自己。

    因此當CCSequenceAction中有一個動作完成時,就會調用SSActionEvent通知CCSequenceAction,如果仍有需要執行的動作,則執行下一個動作,否則所有動作已完成,需要銷毀自己,即調用callback.SSActionEvent通知其他類來處理。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class CCSequenceAction : SSAction, ISSActionCallback
    {
        // 動作序列
        public List<SSAction> sequence;
        // 重復次數
        public int repeat = -1;
        // 動作開始指針
        public int start = 0;
    
        // 生產函數(工廠模式)
        public static CCSequenceAction GetSSAction(int repeat, int start, List<SSAction> sequence)
        {
            CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction>();
            action.repeat = repeat;
            action.start = start;
            action.sequence = sequence;
            return action;
        }
    
        // 對序列中的動作進行初始化
        public override void Start()
        {
            foreach (SSAction action in sequence)
            {
                action.gameObject = this.gameObject;
                action.transform = this.transform;
                action.callback = this;
                action.Start();
            }
        }
         
        // 運行序列中的動作
        public override void Update()
        {
            if (sequence.Count == 0)
                return;
            if (start < sequence.Count)
            {
                sequence[start].Update();
            }
        }
    
        // 回調處理,當有動作完成時觸發
        public void SSActionEvent(SSAction source,
            SSActionEventType events = SSActionEventType.Competed,
            int Param = 0,
            string strParam = null,
            Object objectParam = null)
        {
            source.destroy = false;
            this.start++;
            if (this.start >= sequence.Count)
            {
                this.start = 0;
                if (repeat > 0)
                    repeat--;
                if (repeat == 0)
                {
                    this.destroy = true;
                    this.callback.SSActionEvent(this);
                }
            }
        }
    
        void OnDestroy()
        {
    
        }
    }
    

    CCActionManager.cs

    CCActionManager是動作管理者。

    isMoving標識當前是否正在運動,本游戲當有物體在運動時不允許用戶產生其他操作(除了重開),因此需要使用isMoving來記下當前狀態。

    moveBoatAction是船移動類,因為船只需要橫向移動,因此為單一動作,使用CCMoveToAction。

    moveRoleAction是人移動類,因為人需要在兩個方向上移動,是組合動作,因此使用CCSequenceAction。

    controller為當前與動作管理者關聯的控制器

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class CCActionManager : SSActionManager, ISSActionCallback
    {
        // 是否正在運動
        private bool isMoving = false;
        // 船移動動作類
        public CCMoveToAction moveBoatAction;
        // 人移動動作類(需要組合)
        public CCSequenceAction moveRoleAction;
        // 控制器
        public FirstController controller;
    
        protected new void Start()
        {
            controller = (FirstController)SSDirector.GetInstance().CurrentSenceController;
            controller.actionManager = this;
        }
    
        public bool IsMoving()
        {
            return isMoving;
        }
         
        // 移動船
        public void MoveBoat(GameObject boat, Vector3 target, float speed)
        {
            if (isMoving)
                return;
            isMoving = true;
            moveBoatAction = CCMoveToAction.GetSSAction(target, speed);
            this.RunAction(boat, moveBoatAction, this);
        }
    
        // 移動人
        public void MoveRole(GameObject role, Vector3 mid_destination, Vector3 destination, int speed)
        {
            if (isMoving)
                return;
            isMoving = true;
            moveRoleAction = CCSequenceAction.GetSSAction(0, 0, new List<SSAction> { CCMoveToAction.GetSSAction(mid_destination, speed), CCMoveToAction.GetSSAction(destination, speed) });
            this.RunAction(role, moveRoleAction, this);
        }
    
        // 回調函數
        public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competed,int intParam = 0, string strParam = null, Object objectParam = null)
        {
            isMoving = false;
        }
    }
    

    Controllers:

    JudgeController.cs

    JudgeController是裁判類,其會在每一幀判斷當前游戲是否已經結束,如果已經結束則通過mainController.JudgeCallback()通知主控制器處理。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class JudgeController : MonoBehaviour
    {
        public FirstController mainController;
        public LandModel leftLandModel;
        public LandModel rightLandModel;
        public BoatModel boatModel;
    
        void Start()
        {
            mainController = (FirstController)SSDirector.GetInstance().CurrentSenceController;
            this.leftLandModel = mainController.leftLandController.GetLandModel();
            this.rightLandModel = mainController.rightLandController.GetLandModel();
            this.boatModel = mainController.boatController.GetBoatModel();
        }
    
        void Update()
        {
            if (!mainController.isRuning)
                return;
            if (mainController.time <= 0)
            {
                mainController.JudgeCallback(false, "Game Over!");
                return;
            }
            this.gameObject.GetComponent<UserGUI>().gameMessage = "";
            // 判斷是否已經勝利
            if (rightLandModel.priestNum == 3)
            {
                mainController.JudgeCallback(false, "You Win!");
                return;
            }
            else
            {
                 /*
                 判斷是否已經失敗
                 leftPriestNum: 左邊牧師數量
                 leftDevilNum: 左邊惡魔數量
                 rightPriestNum: 右邊牧師數量
                 rightDevilNum: 右邊惡魔數量
                 若任意一側,牧師數量不為0且牧師數量少于惡魔數量,則游戲失敗
                 */
                int leftPriestNum, leftDevilNum, rightPriestNum, rightDevilNum;
                leftPriestNum = leftLandModel.priestNum + (boatModel.isRight ? 0 : boatModel.priestNum);
                leftDevilNum = leftLandModel.devilNum + (boatModel.isRight ? 0 : boatModel.devilNum);
                if (leftPriestNum != 0 && leftPriestNum < leftDevilNum)
                {
                    mainController.JudgeCallback(false, "Game Over!");
                    return;
                }
                rightPriestNum = rightLandModel.priestNum + (boatModel.isRight ? boatModel.priestNum : 0);
                rightDevilNum = rightLandModel.devilNum + (boatModel.isRight ? boatModel.devilNum : 0);
                if (rightPriestNum != 0 && rightPriestNum < rightDevilNum)
                {
                    mainController.JudgeCallback(false, "Game Over!");
                    return;
                }
            }
        }
    }
    

    FirstController.cs

    JudgeCallback()函數來處理裁判類的反饋信息。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class FirstController : MonoBehaviour, ISceneController, IUserAction
    {
        public CCActionManager actionManager;
        public LandModelController rightLandController;                        // 右岸控制器
        public LandModelController leftLandController;                         // 左岸控制器
        public RiverModel riverModel;                                              // 河流Model
        public BoatModelController boatController;                                  // 船控制器
        public RoleModelController[] roleControllers;                         // 人物控制器集合
        public bool isRuning;                                                      // 游戲進行狀態
        public float time;                                                         // 游戲進行時間
    
        public void JudgeCallback(bool isRuning, string message)
        {
            this.gameObject.GetComponent<UserGUI>().gameMessage = message;
            this.gameObject.GetComponent<UserGUI>().time = (int)time;
            this.isRuning = isRuning;
        }
    
        // 導入資源
        public void LoadResources()
        {
            // 人物初始化
            roleControllers = new RoleModelController[6];
            for (int i = 0; i < 6; i++)
            {
                roleControllers[i] = new RoleModelController();
                roleControllers[i].CreateRole(PositionModel.roles[i], i < 3 ? true : false, i);
            }
            // 左右岸初始化
            leftLandController = new LandModelController();
            leftLandController.CreateLand("left_land", PositionModel.left_land);
            rightLandController = new LandModelController();
            rightLandController.CreateLand("right_land", PositionModel.right_land);
            // 將人物添加并定位至左岸  
            foreach (RoleModelController roleModelController in roleControllers)
            {
                roleModelController.GetRoleModel().role.transform.localPosition = leftLandController.AddRole(roleModelController.GetRoleModel());
            }
            // 河流Model實例化
            riverModel = new RiverModel(PositionModel.river);
            // 船初始化
            boatController = new BoatModelController();
            boatController.CreateBoat(PositionModel.left_boat);
            // 數據初始化
            isRuning = true;
            time = 60;
        }
    
        // 移動船
        public void MoveBoat()
        {
            // 判斷當前游戲是否在進行,同時是否有對象正在移動
            if ((!isRuning) || actionManager.IsMoving())
                return;
            // 判斷船在左側還是右側
            Vector3 destination = boatController.GetBoatModel().isRight ? PositionModel.left_boat : PositionModel.right_boat;
            actionManager.MoveBoat(boatController.GetBoatModel().boat, destination, 5);
            // 移動后,將船的位置取反
            boatController.GetBoatModel().isRight = !boatController.GetBoatModel().isRight;
        }
    
        // 移動人物    
        public void MoveRole(RoleModel roleModel)
        {
            // 判斷當前游戲是否在進行,同時是否有對象正在移動
            if ((!isRuning) || actionManager.IsMoving())
                return;
    
            Vector3 destination, mid_destination;
            if (roleModel.isInBoat)
            {
                // 若人在船上,則將其移向岸上
                if (boatController.GetBoatModel().isRight)
                    destination = rightLandController.AddRole(roleModel);
                else
                    destination = leftLandController.AddRole(roleModel);
                if (roleModel.role.transform.localPosition.y > destination.y)
                    mid_destination = new Vector3(destination.x, roleModel.role.transform.localPosition.y, destination.z);
                else
                    mid_destination = new Vector3(roleModel.role.transform.localPosition.x, destination.y, destination.z);
                actionManager.MoveRole(roleModel.role, mid_destination, destination, 5);
                roleModel.isRight = boatController.GetBoatModel().isRight;
                boatController.RemoveRole(roleModel);
            }
            else
            {
                // 若人在岸上,則將其移向船
                if (boatController.GetBoatModel().isRight == roleModel.isRight)
                {
                    if (roleModel.isRight)
                    {
                        rightLandController.RemoveRole(roleModel);
                    }
                    else
                    {
                        leftLandController.RemoveRole(roleModel);
                    }
                    destination = boatController.AddRole(roleModel);
                    if (roleModel.role.transform.localPosition.y > destination.y)
                        mid_destination = new Vector3(destination.x, roleModel.role.transform.localPosition.y, destination.z);
                    else
                        mid_destination = new Vector3(roleModel.role.transform.localPosition.x, destination.y, destination.z);
                    actionManager.MoveRole(roleModel.role, mid_destination, destination, 5);
                }
            }
        }
    
        // 游戲重置
        public void Restart()
        { 
            // 對各數據進行初始化
            time = 60;
            leftLandController.CreateLand("left_land", PositionModel.left_land);
            rightLandController.CreateLand("right_land", PositionModel.right_land);
            for (int i = 0; i < 6; i++)
            {
                roleControllers[i].CreateRole(PositionModel.roles[i], i < 3 ? true : false, i);
                roleControllers[i].GetRoleModel().role.transform.localPosition = leftLandController.AddRole(roleControllers[i].GetRoleModel());
            }
            boatController.CreateBoat(PositionModel.left_boat);
            isRuning = true;
        }
    
        void Awake()
        {
            SSDirector.GetInstance().CurrentSenceController = this;
            LoadResources();
            this.gameObject.AddComponent<UserGUI>();
            this.gameObject.AddComponent<CCActionManager>();
            this.gameObject.AddComponent<JudgeController>();
        }
    
        void Update()
        {
            if (isRuning)
            {
                time -= Time.deltaTime;
                this.gameObject.GetComponent<UserGUI>().time = (int)time;
            }
        }
    }
    

    項目源代碼與視頻鏈接

    gitee源碼鏈接

    項目運行效果mp4

    運行效果:

    成功情況:

    在這里插入圖片描述

    失敗情況:

    在這里插入圖片描述

    3、材料與渲染聯系【可選】

    Albedo Color and Transparency

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

    我們常用Material來設置我們的游戲對象外觀。但是,外觀除了顏色RGB之外,還有一個透明度的選項,即Albedo Color and Transparency。

    創建五個球和五個材料,對于材料的color設置上,統一為RGB=0,0,0,變動的是A屬性。

    注意:需要將材料的設置里面的Rendering Mode改為Transparent。

    在這里插入圖片描述

    將材料賦給每個球,查看效果:

    在這里插入圖片描述

    Reverb Zones

    • 聲音
      • 閱讀官方 Audio 手冊
      • 用博客給出游戲中利用 Reverb Zones 呈現車輛穿過隧道的聲效的案例

    在一個3d對象上加入 Audio Reverb Zone 和 Audio Source組件,如下:

    在這里插入圖片描述

    接著,只需要去Asset Store上搜索需要的汽車聲效,然后將該聲音加入到Audio Source中即可。

    版權聲明:本文為weixin_43165605原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_43165605/article/details/109092473

    智能推薦

    3D游戲編程與設計 作業五

    3D游戲編程與設計 作業五 1、編寫一個簡單的鼠標打飛碟(Hit UFO)游戲 游戲內容要求: 游戲有 n 個 round,每個 round 都包括10 次 trial; 每個 trial 的飛碟的色彩、大小、發射位置、速度、角度、同時出現的個數都可能不同。它們由該 round 的 ruler 控制; 每個 trial 的飛碟有隨機性,總體難度隨 round 上升; 鼠標點中得分,得分規則按色彩、...

    3d游戲編程與設計

    目錄 1、簡答題 解釋游戲對象(object)和資源(asset)的區別和聯系 下載幾個游戲案例,分別總結資源、對象組織的結構(指資源的目錄組織結構與游戲對象樹的層次結構) 編寫一個代碼,使用 debug 語句來驗證 MonoBehaviour 基本行為或事件觸發的條件 查找腳本手冊,了解 GameObject,Transform,Component 對象 資源預設(Prefabs)與 對象克隆 ...

    3D游戲編程與設計10——游戲智能

    3、P&D 過河游戲智能幫助實現,程序具體要求: 實現狀態圖的自動生成 講解圖數據在程序中的表示方法 利用算法實現下一步的計算 參考:P&D 過河游戲智能幫助實現 狀態圖: 其中,每個狀態記錄了位于右岸的牧師與惡魔數量,P 代表牧師,D 代表惡魔,B 代表船在右邊。改變狀態的動作有五個:PP(兩個牧師過河)、PD(一個牧師和一個惡魔過河)、DD(兩個惡魔過河)、P(一個牧師過河)、...

    【3D游戲編程與設計】十 游戲智能

    【3D游戲編程與設計】十 游戲智能 坦克對戰游戲 AI 設計 游戲設計要求: 項目架構 軟件版本 文件組織 項目地址 感知-思考-行動模型設計思路 感知 思考 行動 游戲設計實現 游戲效果 坦克對戰游戲 AI 設計 游戲設計要求: 從商店下載游戲:“Kawaii” Tank 或 其他坦克模型,構建 AI 對戰坦克。具體要求 使用“感知-思考-行為”模...

    Unity:游戲對象與圖形基礎-作業與練習

    游戲對象與圖形基礎-作業與練習 github地址 1、基本操作演練 下載天空和skybox, 構建自己的游戲場景 從Asset Store下載skybox然后導入 制作天空盒 在Assets中右擊->Create->Material 將shader改為Skybox/6 sided并把對應的圖片放進去 創建地圖 在對象欄右擊->3D Object->Terrain,新建一個地...

    猜你喜歡

    3D 游戲編程與設計 - 空間與運動

    簡答并用程序驗證 1 游戲對象運動的本質是什么? 游戲對象運動的本質是變換游戲對象自身的坐標。 在游戲開發中,我們可以通過矩陣變換的方式實現游戲對象的變換,比如: 2 請用三種方法以上方法,實現物體的拋物線運動 (如,修改Transform屬性,使用向量Vector3的方法…) 方法一 通過 Translate 方法實現。 在二維坐標系中,物體的拋物線運動方程為: x=vxty=vy...

    3D Game Programming Design(四):游戲對象與圖形基礎(訪問者模式)

    我們聊回上一次做的小游戲,分析下我寫的Model有什么缺陷 上一篇的鏈接:https://blog.csdn.net/keven2148/article/details/79760734 GameController了解三種游戲物體并有他們的引用,三種物體想要獲得其他的屬性(例如Man的excuse需要知道boat和land的空位數組)可以通過GameController來引用,而不用顯式相互引用...

    3D游戲編程與設計第八次作業

    作業內容 血條(Health Bar)的預制設計。具體要求如下 分別使用 IMGUI 和 UGUI 實現 使用 UGUI,血條是游戲對象的一個子元素,任何時候需要面對主攝像機 分析兩種實現的優缺點 給出預制的使用方法 1.使用 IMGUI 實現 本來只做了一個不會跟隨物體移動的,但發現有人做出了可以跟隨物體移動的血條,就參考了這位作者,參考博客的鏈接在文末給出。我覺得最主要的部分就是將3D坐標轉換...

    3D游戲編程與設計第四次作業

    作業內容 1.編寫一個簡單的鼠標打飛碟(Hit UFO)游戲 這次的作業最重要的是單例模式和工廠模式。 單例模式:確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例,這個類稱為單例類,它提供全局訪問的方法。是對象創建型模式。 模板如下: 實現單例模式最主要的思想是: 構造函數是私有的; 私有靜態變量存放單一實例; 公有靜態函數獲得該實例,如有需要則創建。 使用上面的模板,就可以創建任...

    numpy知識點大全及如何用python作圖

    這篇文章轉載的初衷是,我在搜索這類操作的時候,要不就是很早的文章,要不就是只寫了一部分功能,如果想完成什么的話,需要把文章東拼西湊起來很麻煩。 這個教程的作者是 Justin Johnson. 作者背景: I am a PhD student in the Stanford Vision Lab, advised by Professor Fei-Fei Li . I...

    精品国产乱码久久久久久蜜桃不卡