Unity3D学习笔记(5) 飞碟(Disk)运动与物理兼容版

先简单了解一下适配器模式。

适配器模式

适配器模式通过将类自己的接口包裹在一个已存在的类中使得因接口不兼容而不能在一起工作的类能在一起工作,有两种类型的适配器模式:

对象适配器模式

在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
这里写图片描述

类适配器模式

这种适配器模式下,适配器继承自已实现的类(一般多重继承)。
这里写图片描述


描述

按adapter模式魔改飞碟(Disk)基础版(仅使用射线,动作管理),使它同时支持物理运动与运动学(变换)运动
这里写图片描述

设计

这里写图片描述
对动作管理运用类适配器模式,设计运动学适配器CCActionManager和物理运动适配器PhysiscActionManager,PhysiscActionManager与CCActionManager的不同仅仅在于将Update改成FixedUpdate。
适配器模式的多态的设计要用到接口。这两个适配器实现了同一接口ActionManager。
ActionManager提供了一个简单动作方法,用于执行抛出飞碟的动作。

ActionManager

public interface ActionManager{
    void singleRunAction (GameObject gameObject, int speedLevel);
}

由于PhysiscActionManager要用到FixedUpdate方法,所以要对SSAction(作用)、SSActionManager(作用)添加FixedUpdate,方法与Update相同,除了把其中包含的Update换成FixedUpdate。

SSAction

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

public enum SSActionEventType : int { Started, Competeted }

public interface ISSActionCallback {
    void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null);
}

public class SSAction : ScriptableObject {

    public bool enable = true;
    public bool destroy = false;

    public GameObject gameobject { get; set; }
    public Transform transform { get; set; }
    public ISSActionCallback callback{ get; set; }

    protected SSAction () {}

    //Use this for initialization
    public virtual void Start () {
        throw new System.NotImplementedException ();
    }

    // Update is called once per frame
    public virtual void Update () {
        throw new System.NotImplementedException ();
    }

    // FixedUpdate
    public virtual void FixedUpdate () {
        throw new System.NotImplementedException ();
    }
}

SSActionManager

public class SSActionManager : MonoBehaviour
{
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();
    private List<SSAction> waitingAdd = new List<SSAction>();
    private List<int> waitingDelete = new List<int>();

    // Use this for initialization
    void Start() {

    }

    // Update is called once per frame
    protected void Update() {
        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.Update();
        }

        foreach (int key in waitingDelete) {
            SSAction ac = actions [key];
            actions.Remove (key);
            DestroyObject (ac);
        }
        waitingDelete.Clear();
    }

    // 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();
    }

    public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager) {
        action.gameobject = gameobject;
        action.transform = gameobject.transform;
        action.callback = manager;
        waitingAdd.Add(action);
        action.Start();
    }
}

在写继承时要注意C#的一个语法规定,继承的父类SSActionManager要写在最前面,后面跟着实现的接口,因为C#只支持单继承,但可以实现多个接口。

CCActionManager

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

public class CCActionManager : SSActionManager, ActionManager, ISSActionCallback {

    public DiskFactory diskFactory;

    void Start() {
        diskFactory = DiskFactory.getInstance();
    }

    public new void Update() {
        base.Update ();
    }

    public new void FixedUpdate() {

    }

    public void singleRunAction(GameObject gameObject, int speedLevel) {
        this.RunAction (gameObject, FlyDisk.GetSSAction (speedLevel), this);
    }

    #region ISSActionCallback implementation
    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null){

    }
    #endregion
}

PhysiscActionManager

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

public class PhysicsActionManager : SSActionManager, ActionManager, ISSActionCallback {

    public DiskFactory diskFactory;

    void Start() {
        diskFactory = DiskFactory.getInstance();
    }

    public new void Update() {

    }

    public new void FixedUpdate() {
        base.FixedUpdate ();
    }

    public void singleRunAction (GameObject gameObject, int speedLevel) {
        this.RunAction (gameObject, FlyDisk.GetSSAction (speedLevel), this);
    }

    #region ISSActionCallback implementation
    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null){

    }
    #endregion
}

其他代码

https://gitee.com/Ernie1/unity3d-learning/tree/hw5/hw5

猜你喜欢

转载自blog.csdn.net/z_j_q_/article/details/80040424