主要場景和上次是同樣的,主要是在場記中添加了一個選擇,場景中的空遊戲對象GameObject添加的場記多了一個選項來選擇是否使用物理引擎。
![]()
![]()
![]()
此次按照Adapter模式重寫了飛碟的控制邏輯,其中RoundController其實就是場記FirstSceneController。上一次我是經過CCActionManager的實例來調用使飛碟運動的方法,此次將方法分離,使用接口IActionManager來發射飛碟,場記與具體運動控制器並不直接鏈接。
![]()
![]()
首先按照需求,咱們須要添加接口類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按鈕已經加載出來 } }
底層運動管理也是不須要重寫的,須要重寫的主要是用戶層的運動管理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; } }
此次主要的任務還有寫一個基於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; } }
添加具體的物理運動管理類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