Unity3D - 5 打飛碟 - 添加物理運動版

打飛碟小遊戲 - 物理運動版

效果圖

主要場景和上次是同樣的,主要是在場記中添加了一個選擇,場景中的空遊戲對象GameObject添加的場記多了一個選項來選擇是否使用物理引擎。
物理引擎選擇
打飛碟-1
打飛碟-2

遊戲組織結構

此次按照Adapter模式重寫了飛碟的控制邏輯,其中RoundController其實就是場記FirstSceneController。上一次我是經過CCActionManager的實例來調用使飛碟運動的方法,此次將方法分離,使用接口IActionManager來發射飛碟,場記與具體運動控制器並不直接鏈接。
新設計
文件組織結構

代碼組織結構

  1. 首先按照需求,咱們須要添加接口類IActionManager,它主要用於連接場記和運動管理器,使飛碟運動和判斷因此飛碟都已經被回收。git

    namespace Interfaces
        {
            public interface ISceneController
            {
                void LoadResources();
            }
    
            public interface UserAction
            {
                void Hit(Vector3 pos);
                void Restart();
                int GetScore();
                bool RoundStop();
                int GetRound();
            }
    
            public enum SSActionEventType : int { Started, Completed }
    
            public interface SSActionCallback
            {
                void SSActionCallback(SSAction source);
            }
    
            public interface IActionManager
            {
                void PlayDisk(Disk disk);
                bool IsAllFinished(); //主要爲了防止遊戲結束時場景還有對象可是GUI按鈕已經加載出來
            }
        }
  2. 底層運動管理也是不須要重寫的,須要重寫的主要是用戶層的運動管理CCActionManager,主要就是添加繼承的接口和重寫繼承的接口的函數。github

    public class CCActionManager : SSActionManager, SSActionCallback, IActionManager
        {
            int count = 0;//記錄全部在移動的碟子的數量
            public SSActionEventType Complete = SSActionEventType.Completed;
    
            public void PlayDisk(Disk disk)
            {
                count++;
                Complete = SSActionEventType.Started;
                CCMoveToAction action = CCMoveToAction.getAction(disk.speed);
                addAction(disk.gameObject, action, this);
            }
    
            public void SSActionCallback(SSAction source) //運動事件結束後的回調函數
            {
                count--;
                Complete = SSActionEventType.Completed;
                source.gameObject.SetActive(false);
            }
    
            public bool IsAllFinished() //主要爲了防止遊戲結束時場景還有對象可是GUI按鈕已經加載出來
            {
                if (count == 0) return true;
                else return false;
            }
        }
  3. 此次主要的任務還有寫一個基於Unity物理引擎的運動控制類,我以爲是使用剛體屬性以及施加力來實現。首先須要寫一個用戶層的物理運動管理CCPhysisActionManager,其實基本和CCActionManager是同樣的,只要區別是底層使用的是CCPhysisAction來實例化運動對象。ide

    public class CCPhysisActionManager : SSActionManager, SSActionCallback, IActionManager
        {
            int count = 0;//記錄全部在移動的碟子的數量
            public SSActionEventType Complete = SSActionEventType.Completed;
    
            public void PlayDisk(Disk disk)
            {
                count++;
                Complete = SSActionEventType.Started;
                CCPhysisAction action = CCPhysisAction.getAction(disk.speed); //實例化爲物理運動對象
                addAction(disk.gameObject, action, this);
            }
    
            public void SSActionCallback(SSAction source) //運動事件結束後的回調函數
            {
                count--;
                Complete = SSActionEventType.Completed;
                source.gameObject.SetActive(false);
            }
    
            public bool IsAllFinished() //主要爲了防止遊戲結束時場景還有對象可是GUI按鈕已經加載出來
            {
                if (count == 0) return true;
                else return false;
            }
        }
  4. 添加具體的物理運動管理類CCPhysisAction,一樣是繼承自SSAction,在Start初始化的時候添加剛體屬性,而且添加X軸上持續的速度ForceMode.VelocityChange,因爲重力加速度太大致使畫面上飛碟速度太大,只能使用流氓方法添加持續向上的一半的重力使重力加速度減少爲g/2。而後當遊戲對象到達地面時,因爲飛碟工廠的存在,必定要銷燬對象的剛體屬性不然速度會累積。函數

    public class CCPhysisAction : SSAction
        {
            public float speedx;
            // Use this for initialization
            public override void Start ()
            {
                if (!this.gameObject.GetComponent<Rigidbody>())
                {
                    this.gameObject.AddComponent<Rigidbody>();
                }
                this.gameObject.GetComponent<Rigidbody>().AddForce(Vector3.up * 9.8f * 0.6f, ForceMode.Acceleration);
                this.gameObject.GetComponent<Rigidbody>().AddForce(new Vector3(speedx, 0, 0), ForceMode.VelocityChange);
            }
    
            private CCPhysisAction()
            {
                
            }
            public static CCPhysisAction getAction(float speedx)
            {
                CCPhysisAction action = CreateInstance<CCPhysisAction>();
                action.speedx = speedx;
                return action;
            }
    
            // Update is called once per frame
            override public void Update ()
            {
                if (transform.position.y <= 3)
                {
                    Destroy(this.gameObject.GetComponent<Rigidbody>());//若是不移除剛體屬性會致使前面添加的速度屬性累積。
                    destroy = true;
                    CallBack.SSActionCallback(this);
                }
            }
        }
小結:物理運動引擎能夠簡化咱們使用數學方法模擬複雜物理運動的難度,而且能夠順帶添加一些簡單的物理碰撞效果,好比在物理運動下發射的兩個飛碟就可能發生碰撞。
GITHUB
相關文章
相關標籤/搜索