改進飛碟(Hit UFO)游戲
要求
- 按 adapter模式 設計圖修改飛碟游戲
- 使它同時支持物理運動與運動學(變換)運動
實作
原專案:3D編程與游戲設計作業五
僅僅對其中的一些類進行改動就能實作,
飛碟預設
由于要求支持物理運動,因此飛碟的預設需要在原來的基礎上加上剛體:

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是自定義型別,用于存盤相關資訊,
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回收該飛碟進行下一次使用的時候會具有很大的速度,影響游戲體驗,如下圖(可以看到第三次綠色飛碟出現在右下角的時候具有很大的豎直速度,一閃而過):

由于physic增加了FixedUpdate,因此SSAction、DiskFlyAction也增加了一個空的FixedUpdate:
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修改,
private bool physic = false;
……
public void setPhysic(bool physic_){
physic = physic_;
}
SSActionManager
增加FixedUpdate:
……
if (action.enable) {
action.Update();
action.FixedUpdate();
}
……
UserGUI
在第一個界面增加了兩個按鈕,用于選擇是否是physic模式,
效果
physic模式:

原本運動學模式仍然正常運行:

源代碼:
GitHub
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/221288.html
標籤:其他
