改進飛碟(Hit UFO)遊戲
要求
- 按 adapter模式 設計圖修改飛碟遊戲
- 使它同時支持物理運動與運動學(變換)運動
實現
原項目:3D編程與遊戲設計做業五
僅僅對其中的一些類進行改動就能實現。
git
飛碟預設
因爲要求支持物理運動,所以飛碟的預設須要在原來的基礎上加上剛體:
github
Adapter的實現
adapter是經過不一樣的狀態選擇不一樣的接口,在本做業中是選擇不一樣的動做實現方式(物理/運動學),發現與以前的flyActionController的功能相似,所以把它改寫成Adapter:編程
public class Adapter : SSActionManager { public DiskFlyAction fly; public PhysisFlyAction fly_; public void DiskFly(GameObject disk, int mode, mes information) { int leftOrRight = 1; if (disk.transform.position.x > 0){ leftOrRight = -1; } if(mode == 2){ fly = DiskFlyAction.GetSSAction(leftOrRight, information.angle, information.speed); this.StartAction(disk, fly); } else{ fly_ = PhysisFlyAction.GetSSAction(leftOrRight, information.speed); this.StartAction(disk, fly_); } } }
經過mode控制運動類型,而後分別調用DiskFlyAction和PhysisFlyAction,這裏用到的information是自定義類型,用於存儲相關信息。ide
public struct mes{ public float speed; public float angle; }
PhysisFlyAction && SSAction && DiskFlyAction
PhysisFlyAction類,代碼以下:函數
public class PhysisFlyAction : SSAction { private bool start_position; public float force; public static PhysisFlyAction GetSSAction(int pos, float force_){ PhysisFlyAction action = CreateInstance<PhysisFlyAction>(); if(pos == 1){ action.start_position = true; } else{ action.start_position = false; } action.force = force_; return action; } // Start is called before the first frame update public override void Start() { Rigidbody disk = gameobject.GetComponent<Rigidbody>(); gameobject.GetComponent<Rigidbody>().useGravity = true; if(gameobject.GetComponent<Rigidbody>().position.y <= 3){ if(start_position){ gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(0.4f,0.2f,0)*force*15f, ForceMode.Impulse); } else{ gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(-0.4f,0.2f,0)*force*15f, ForceMode.Impulse); } } } // Update is called once per frame public override void Update() { } public override void FixedUpdate() { if (transform.position.y <= -10f) { Debug.Log(transform.position.y); gameobject.GetComponent<Rigidbody>().useGravity = false; gameobject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0); this.enable = false; } } }
整體與物理學運動實現相似,可是這裏用到了FixedUpdate。
這個類設計的小細節有對重力的改變,在start中,開啓了重力,在一個初始力和重力的做用下,飛碟進行拋體運動,當飛碟運動到咱們攝像機視線以外(這裏是FixedUpdate中提到的-10f)時,則關閉重力。由於若是不關閉重力,飛碟仍然會繼續下落,而後等到DiskFactory回收該飛碟進行下一次使用的時候會具備很大的速度,影響遊戲體驗,以下圖(能夠看到第三次綠色飛碟出如今右下角的時候具備很大的豎直速度,一閃而過):
this
因爲physic增長了FixedUpdate,所以SSAction、DiskFlyAction也增長了一個空的FixedUpdate:spa
public class SSAction : ScriptableObject { …… public virtual void FixedUpdate() { throw new System.NotImplementedException(); } …… } public class DiskFlyAction : SSAction { …… public override void FixedUpdate() { } …… }
FirstController && Interfaces
FirstController的改動有:
增長了一個bool變量,用於記錄是物理運動仍是運動學變換運動,爲了經過UserGUI改變這個變量,還增長了一個setPhysic函數,而且同時在Interfaces中加上方便UserGUI修改。
.net
private bool physic = false; …… public void setPhysic(bool physic_){ physic = physic_; }
SSActionManager
增長FixedUpdate:設計
…… if (action.enable) { action.Update(); action.FixedUpdate(); } ……
UserGUI
在第一個界面增長了兩個按鈕,用於選擇是不是physic模式。3d
效果
physic模式:
本來運動學模式仍然正常運行: