3D遊戲編程與設計做業六

改進飛碟(Hit UFO)遊戲

要求

  1. 按 adapter模式 設計圖修改飛碟遊戲
  2. 使它同時支持物理運動與運動學(變換)運動

實現

原項目: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模式:
在這裏插入圖片描述
本來運動學模式仍然正常運行:
在這裏插入圖片描述


源代碼:

GitHub

相關文章
相關標籤/搜索