关于动作分离。可以通过对游戏对象增加可执行的动作,可以划分出很多的基础动作,如上船,下船,前进后退等。所以我们可以通过提取基础动作,然后使用类的方法来执行游戏对象的动作,同时通过配备动作管理者,让其去调度游戏对象执行动作。
动作管理者-SSActionManager
通过创教类来管理动作的集合,动作做完自动回收。并且展示了集合对象的使用方法。并且要执行start()方法。

publicclass 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>();
    protectedvoidUpdate() {
        foreach (SSAction ac in waitingAdd) {
            actions[ac.GetInstanceID()] = ac;
        }
        waitingAdd.Clear();
        foreach (KeyValuePair<int, SSAction> kv in actions) {
            SSAction ac = kv.Value;
            if (ac.destory) {
                waitingDelete.Add(ac.GetInstanceID());
            } elseif (ac.enable) {
                ac.Update();
            }
        }
        foreach(int key in waitingDelete) {
            SSAction ac = actions[key];
            actions.Remove(key);
            DestroyObject(ac);
        }
        waitingDelete.Clear();
    }

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

protectedvoidStart() {}
}

组合动作实现-CCSequeneceAction
SequenceAction继承了ISSActionCallback,因为组合动作是每一个动作的顺序完成,它管理这一连串动作中的每一个小的动作,所以当小的动作完成的时候,也要发消息告诉它,然后它得到消息后去处理下一个动作。SequenceAction也继承了SSAction,因为成个组合动作也需要游戏对象,也需要标识是否摧毁,也会有一个组合动作的管理者的接口,组成动作也是动作的子类,只不过是让具体的动作组合起来做罢了。
public class CCSequenceAction : SSAction, ISSActionCallback {

public List<SSAction> sequence;
    public int repeat = - 1 ;
    public int start = 0 ;

public static CCSequenceAction GetSSAction ( int repeat, int start, List<SSAction> sequence) {
        CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction> ();
        action.repeat = repeat;
        action.sequence = sequence;
        action.start = start;
        return action;
    }

public override void Update () {
        if (sequence.Count == 0 ) return ;
        if (start < sequence.Count) {
            sequence [start].Update ();
        }
    }

public void SSActionEvent (SSAction source, SSActionEventType events = SSActionEventType.Completed, int Param = 0 , string strParam = null , Object objectParam = null ) {
        source.destory = false ;
        this .start++;
        if ( this .start >= sequence.Count) {
            this .start = 0 ;
            if (repeat > 0 ) repeat--;
            if (repeat == 0 ) {
                this .destory = true ;
                this .callback.SSActionEvent( this );
            }
        }
    }
    // Use this for initialization
    public override void Start () {
        foreach (SSAction action in sequence) {
            action.gameobject = this .gameobject;
            action.transform = this .transform;
            action.callback = this ;
            action.Start();
        }
    }

void OnDestory() {}
}

牧师与魔鬼动作管理实现
CCMoveToAction(移动动作实现) 以speed的速度向target目的地移动
public class CCMoveToAction : SSAction {
    public Vector3 target;
    public float speed;

public static CCMoveToAction GetSSAction (Vector3 target, float speed) {
        CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();
        action.target = target;
        action.speed = speed;
        return action;
    }

public override void Update () {
        this .transform.position = Vector3.MoveTowards ( this .transform.position, target, speed * Time.deltaTime);
        if ( this .transform.position == target) {
            this .destory = true ;
            this .callback.SSActionEvent ( this );
        }
    }

public override void Start () {}
}

SSActionManager(动作管理基类)
管理SequenceAction和SSAction,可以给它们传递游戏对象,让游戏对象做动作或是一连串的动作,控制动作的切换。SSActionManager继承了ISSActionCallback接口,通过这个接口,当动作做完或是连续的动作做完时候会告诉SSActionManager,然后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 >();
    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.destory) {
                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();
    }

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

protected void Start () {}
}

SSAction (动作基类) 
SSAction是所有动作的基类。SSAction继承了ScriptableObject代表SSAction不需要绑定GameObject对象,且受Unity引擎场景管理
public class SSAction : ScriptableObject {

public bool enable = true ;
    public bool destory = false ;

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

protected SSAction () {}

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

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

SSDirector 
最后SSDirector接收到游戏对象需要移动的时候,只要传给MySceneActionManager相应的参数和游戏对象就可以进行移动啦 
public enum State { WIN, LOSE, PAUSE, CONTINUE , START };
public class SSDirector : System.Object {private static SSDirector _instance;public int totalSeconds = 60;public int leaveSeconds;public bool onCountDown = false;public string countDownTitle = "Start";public ISceneController currentSceneController { get; set; }public State state { get; set; }public bool running { get; set; }// get instance anytime anywhere!public static SSDirector getInstance() {if (_instance == null) {_instance = new SSDirector ();}return _instance;}public int getFPS() {return Application.targetFrameRate;}public void setFPS(int fps) {Application.targetFrameRate = fps;}public IEnumerator DoCountDown() {while (leaveSeconds > 0) {yield return new WaitForSeconds (1f);leaveSeconds--;}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

FirstController.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class FirstController : MonoBehaviour, IUserAction, ISceneController {public CCActionManager actionManager;List<GameObject> LeftObjList = new List<GameObject>();List<GameObject> RightObjList = new List<GameObject>();GameObject[] boat = new GameObject[2];GameObject boat_obj, leftShore_obj, rightShore_obj;Vector3 LeftShorePos = new Vector3(-12, 0, 0);Vector3 RightShorePos = new Vector3(12, 0, 0);Vector3 BoatLeftPos = new Vector3(-4, 0, 0);Vector3 BoatRightPos = new Vector3(4, 0, 0);void Awake() {SSDirector director = SSDirector.getInstance();director.setFPS(60);director.currentSceneController = this;director.currentSceneController.LoadResources();director.leaveSeconds = director.totalSeconds;}void Start () {SSDirector.getInstance().state = State.PAUSE;SSDirector.getInstance().countDownTitle = "Start";actionManager = GetComponent<CCActionManager>() as CCActionManager;}void Update() {check();}public void LoadResources() {GameObject priest_obj, devil_obj;Camera.main.transform.position = new Vector3(0, 0, -20);leftShore_obj = Instantiate(Resources.Load("prefabs/Shore"), LeftShorePos, Quaternion.identity) as GameObject;rightShore_obj = Instantiate(Resources.Load("prefabs/Shore"), RightShorePos, Quaternion.identity) as GameObject;leftShore_obj.name = "left_shore";rightShore_obj.name = "right_shore";boat_obj = Instantiate(Resources.Load("prefabs/Boat"), BoatLeftPos, Quaternion.identity) as GameObject;boat_obj.name = "boat";boat_obj.transform.parent = leftShore_obj.transform;for (int i = 0; i < 3; ++i) {priest_obj = Instantiate(Resources.Load("prefabs/Priest")) as GameObject;priest_obj.name = i.ToString();priest_obj.transform.position = new Vector3(-16f + 1.5f * Convert.ToInt32(priest_obj.name), 2.7f, 0);priest_obj.transform.parent = leftShore_obj.transform;LeftObjList.Add(priest_obj);devil_obj = Instantiate(Resources.Load("prefabs/Devil")) as GameObject;devil_obj.name = (i + 3).ToString();devil_obj.transform.position = new Vector3(-16f + 1.5f * Convert.ToInt32(devil_obj.name), 2.7f, 0);devil_obj.transform.parent = leftShore_obj.transform;LeftObjList.Add(devil_obj);}}public void click() {GameObject gameObj = null;if (Input.GetMouseButtonDown(0) && (SSDirector.getInstance().state == State.START || SSDirector.getInstance().state == State.CONTINUE)) {Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)) gameObj = hit.transform.gameObject;}if (gameObj == null) return;else if (gameObj.name == "0" || gameObj.name == "1" || gameObj.name == "2"|| gameObj.name == "3" || gameObj.name == "4" || gameObj.name == "5")MovePeople(gameObj);else if(gameObj.name == "boat") MoveBoat();}void MovePeople(GameObject people) {int shoreNum, seatNum;if (people.transform.parent == boat_obj.transform.parent && (boat[0] == null || boat[1] == null)) {seatNum = boat[0] == null ? 0 : 1;if (people.transform.parent == leftShore_obj.transform) {shoreNum = 0;for (int i = 0; i < LeftObjList.Count; i++) {if (people.name == LeftObjList[i].name) {Debug.Log (actionManager);actionManager.getOnBoat(people, shoreNum, seatNum);LeftObjList.Remove(LeftObjList[i]);}}} else {shoreNum = 1;for (int i = 0; i < RightObjList.Count; i++) {if (people.name == RightObjList[i].name) {actionManager.getOnBoat(people, shoreNum, seatNum);RightObjList.Remove(RightObjList[i]);}}}boat[seatNum] = people;people.transform.parent = boat_obj.transform;} else if (people.transform.parent == boat_obj.transform) {shoreNum = boat_obj.transform.parent == leftShore_obj.transform ? 0 : 1;seatNum = (boat[0] != null && boat[0].name == people.name) ? 0 : 1;actionManager.getOffBoat(people, shoreNum);boat[seatNum] = null;if(shoreNum == 0) {people.transform.parent = leftShore_obj.transform;LeftObjList.Add(people);} else {people.transform.parent = rightShore_obj.transform;RightObjList.Add(people);}}}void MoveBoat() {if (!(boat[0]==null && boat[1] == null)) {actionManager.moveBoat(boat_obj);boat_obj.transform.parent = boat_obj.transform.parent == leftShore_obj.transform ? rightShore_obj.transform : leftShore_obj.transform;}}public void check() {int left_d = 0, left_p = 0, right_d = 0, right_p = 0;foreach (GameObject element in LeftObjList) {if (element.tag == "Priest") left_p++;if (element.tag == "Devil") left_d++;}foreach (GameObject element in RightObjList) {if (element.tag == "Priest") right_p++;if (element.tag == "Devil") right_d++;}for (int i = 0; i < 2; i++) {if (boat[i] != null && boat_obj.transform.parent == leftShore_obj.transform) {if (boat[i].tag == "Priest") left_p++;else left_d++;}if (boat[i] != null && boat_obj.transform.parent == rightShore_obj.transform) {if (boat[i].tag == "Priest") right_p++;else right_d++;}}if ((left_d > left_p && left_p != 0) || (right_d > right_p && right_p != 0) || SSDirector.getInstance().leaveSeconds == 0)SSDirector.getInstance().state = State.LOSE;else if (right_d == right_p && right_d == 3) SSDirector.getInstance().state = State.WIN;}public void Pause() {SSDirector.getInstance().state = State.PAUSE;}public void Resume() {SSDirector.getInstance().state = State.CONTINUE;}public void Restart() {Application.LoadLevel(Application.loadedLevelName);SSDirector.getInstance().state = State.START;}
}

魔鬼与牧师动作分离版相关推荐

  1. 魔鬼与牧师——动作分离版

    首先回顾一下牧师与魔鬼的小游戏的要求: 在河的一边有三个牧师和三个恶魔.他们都想去这条河的另一边,但是只有一条船,而且这条船每次只能载两个人.一定有一个人把船从一边开到另一边.在flash游戏中,你可 ...

  2. 牧师与魔鬼——动作分离版

    牧师与魔鬼--动作分离版 在上周的作业中,牧师与魔鬼游戏中的各个事件,都是写在Director中,并且都是继承Monobehavior的.在这周动作分离的设计中,我将上船.下船以及船的移动都分离出来. ...

  3. Unity实战之牧师与魔鬼(动作分离版)

    Unity实战之牧师与魔鬼(动作分离版) 项目链接 整体描述 本次项目在第一版牧师与魔鬼的基础上,将动作从场记中分离出来,并设计一个裁判类实时监测游戏进行的情况.这样改进的优点有很多: 降低了不同功能 ...

  4. Unity牧师与魔鬼小游戏(动作分离版)

    Unity牧师与魔鬼小游戏(动作分离版) 前言 这是中大计算机学院3D游戏编程课的一次作业,在这里分享一下设计思路. 主要代码上传到了gitee上,请按照后文的操作运行. 项目地址:https://g ...

  5. unity编程实践-牧师与魔鬼动作分离版

    作业要求 牧师与魔鬼 动作分离版 [2019开始的新要求]:设计一个裁判类,当游戏达到结束条件时,通知场景控制器游戏结束 目标:建立动作管理器,使动作抽象出来,可以应用到任何游戏对象上,以此提高代码复 ...

  6. 3D游戏设计-牧师与魔鬼_动作分离版

    天空盒 天空盒 前情提要 3D游戏设计-牧师与魔鬼 游戏改进 将每个需要移动的游戏对象的移动方法提取出来,建立一个动作管理器来管理这些移动方法. 优点: 程序更能适应需求变化 对象更容易被复用 程序更 ...

  7. 【3D游戏编程与设计】四 游戏对象与图形基础 : 构建游戏场景+牧师与魔鬼 动作分离版

    [3D游戏编程与设计]四 游戏对象与图形基础 : 构建游戏场景+牧师与魔鬼 动作分离版 基本操作演练 下载 Fantasy Skybox FREE, 构建自己的游戏场景 下载 Fantasy Skyb ...

  8. unity实现牧师与魔鬼2.0(动作分离版) 基本操作演练

    unity实现牧师与魔鬼2.0(动作分离版)& 基本操作演练 & 材料与渲染联系 基本操作演练 下载 Fantasy Skybox FREE, 构建自己的游戏场景 在Window-&g ...

  9. 牧师与魔鬼 动作分离版

    1.基本操作演练 下载 Fantasy Skybox FREE 在unityAssetStore中下载Fantasy Skybox FREE 构建游戏场景: GameObject->3D Obj ...

最新文章

  1. 【Java基础】四种Java引用类型
  2. java最终考核项目(实现商品管理系统)
  3. Synchronize异常释放锁
  4. PyQt5 笔记7 -- 多个类共享信号
  5. ABAP如何调用OCX
  6. Asp.Net操作Cookie总结
  7. 判断 小程序 是否 滚动到页面底部 scrolltolower_微信小程序长列表性能优化——recycle-view
  8. python接口自动化(四)--接口测试工具介绍(详解)
  9. android课程设计实训目的,汽车专业实习目的与意义
  10. win11小键盘怎么设置 Windows11小键盘的设置方法
  11. 计算机网络ppt_计算机网络--女娲补天
  12. python备份文件
  13. springcloud中文手册API
  14. windows如何卸载服务
  15. photoshop7.0绿色迷你免安装版
  16. PX4 mixer load
  17. Python 计算两点之间的距离
  18. ACM Plan UVa - 10102 The path in the colored field
  19. QThread: Destroyed while thread is still running的处理方法
  20. SequoiaDB巨杉数据库成为唯一入选 “硅谷2016 大数据地形图”中国厂商, 企业级市场超越MongoDB等海外产品

热门文章

  1. UCOSii和Linux的区别和联系
  2. 计算机发展简史 计算机的发展历史介绍
  3. OLTP 和 OLAP 的区别?
  4. 防火墙规则应用同一子网计算机,防火墙基础(一)
  5. 凸轮挺杆仿真(Simulink)
  6. Java mail Exchange Service
  7. PHP——get和post请求他人接口
  8. 解决file.delete()无法删除部分文件的问题
  9. 基本DOS命令---3.修改文件夹和文件属性
  10. java自定义环境变量