3D遊戲編程與設計第五次作業

作業內容

1.改進飛碟(Hit UFO)遊戲:

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

適配器模式:將一個接口轉換成客戶希望的另一個接口,使接口不兼容的那些類可以一起工作。

新增加的文件有三個
1.適配器:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Adapter : MonoBehaviour, MyActionManager
{
    public FlyActionManager flyManager;
    public PhysicalActionManager physicalManager;
    public void playDisk(GameObject disk, float angle, float power, bool isPhysical)
    {
        if (isPhysical)
        {
            physicalManager.UFOFly(disk, angle, power);
        }
        else
        {
            flyManager.UFOFly(disk, angle, power);
        }
    }
    // Use this for initialization
    void Start()
    {
        flyManager = gameObject.AddComponent<FlyActionManager>() as FlyActionManager;
        physicalManager = gameObject.AddComponent<PhysicalActionManager>() as PhysicalActionManager;
    }

}

主要是根據傳進來的參數isPhysical來判斷是調用運動學的函數還是動力學的函數。

2.動力學管理器:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicalActionManager : SSActionManager
{
    public PhysicalUFOAction fly;                            //飛碟飛行的動作
    protected void Start()
    {
    }
    //飛碟飛行
    public void UFOFly(GameObject UFO, float angle, float power)
    {
        fly = PhysicalUFOAction.GetSSAction(UFO.GetComponent<DiskData>().direction, angle, power);
        this.RunAction(UFO, fly, this);
    }
}

3.動力學飛行動作:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhysicalUFOAction : SSAction
{
    private Vector3 start_vector;                              //初速度向量
    public float power;
    // Start is called before the first frame update
    public override void Start()
    {
        gameobject.GetComponent<Rigidbody>().velocity = power / 35 * start_vector;
        gameobject.GetComponent<Rigidbody>().useGravity = true;
    }

    // Update is called once per frame
    public override void Update()
    {
        
    }

    public override void FixedUpdate()
    {

        //判斷是否超出範圍
        if (this.transform.position.y < -10)
        {
            this.destroy = true;
            this.callback.SSActionEvent(this);
        }
    }

    public static PhysicalUFOAction GetSSAction(Vector3 direction, float angle, float power)
    {
        //初始化物體將要運動的初速度向量
        PhysicalUFOAction action = CreateInstance<PhysicalUFOAction>();
        if (direction.x == -1)
        {
            action.start_vector = Quaternion.Euler(new Vector3(0, 0, -angle)) * Vector3.left * power;
        }
        else
        {
            action.start_vector = Quaternion.Euler(new Vector3(0, 0, angle)) * Vector3.right * power;
        }
        action.power = power * 2.5f;
        return action;
    }
}

這裏值得注意的是,動力學的動作,最好是調用FixedUpdate函數,此函數調用的時間間隔是固定的,而Update函數是在每一幀調用,但是不同設備每一幀的間隔時間不一樣,所以處理剛體的時候最好是用此函數。

出於多了一個動力學的動作,所以在SSActionManager文件中,新增加一個FixedUpdate函數:

protected void FixedUpdate()
    {
        foreach (SSAction ac in waitingAdd)
        {
            actions[ac.GetInstanceID()] = ac;
        }
        waitingAdd.Clear();

        foreach (KeyValuePair<int, SSAction> kv in actions)
        {
            SSAction ac = kv.Value;
            if (ac.destroy)
            {
                waitingDelete.Add(ac.GetInstanceID());
            }
            else if (ac.enable)
            {
                ac.FixedUpdate();
            }
        }
        foreach (int key in waitingDelete)
        {
            SSAction ac = actions[key];
            actions.Remove(key);
            DestroyObject(ac);
        }
        waitingDelete.Clear();
    }

代碼基本與Update函數是一樣的,唯一不同的是這裏調用的是ac.FixedUpdate(),而Update函數調用的是ac.Update()

新增加的接口函數:

public interface MyActionManager
{
    void playDisk(GameObject UFO, float angle, float power, bool isPhysical);
}

這個類是在FirstController中實例化action_manager中用到。

然後爲了能讓飛碟使用動力學的函數調用,因此需要給每種飛碟添加Rigidbody的屬性。首先點擊預製,然後點擊Open Prefab
在這裏插入圖片描述
然後在Inspector中找到Add Component->Physics->Rigidbody
在這裏插入圖片描述
在這裏插入圖片描述

在運行遊戲前,可以點擊Main Camera選擇是否用動力學的方法運行:
在這裏插入圖片描述

在錄製視頻過程中發現兩兩架飛碟會發生碰撞,爲此我們還得給飛碟預製添加Box Collider屬性,並把Is Trigger屬性去掉勾選:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

項目傳送門

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章