作业内容
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属性去掉勾选: