作業內容
1.改進飛碟(Hit UFO)遊戲:
適配器模式:將一個接口轉換成客戶希望的另一個接口,使接口不兼容的那些類可以一起工作。
新增加的文件有三個
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屬性去掉勾選: