Unity3D项目四:牧师与魔鬼(动作分离版)

基本介绍

动作管理是游戏的重要内容,全部都放在游戏对象里显得十分笨重,所以本次项目需要将动作从对象中提取出来写成单独的动作控制器。动作控制器来管理控制所有的游戏对象移动,通过场景控制器将需要移动的游戏对象和位置等信息传递给动作控制器,动作控制器负责实现具体的移动。当动作很多或是需要做同样动作的游戏对象很多的时候,使用动作管理器可以让动作很容易管理,也提高了代码复用性。

具体实现

完成ActionControllor.cs

  • ISSActionCallback(动作事件接口)

    使用了枚举变量定义动作类型,执行还是完成。

    定义了事件处理接口,动作组合类和动作管理类都需要实现这个接口,来实现接收其子动作的消息以实现动作的调度管理。当动作完成的时候会调用该接口通知管理者该动作完成。

    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);
    }
    
  • SSAction(动作基类)

    代表一个动作,继承了ScriptableObject,是不需要绑定GameObject的可编程基类,受到Unity管理。

    /*动作基类*/
    public class SSAction : ScriptableObject {public bool enable = true;                      //是否进行public bool destroy = false;                    //是否删除public GameObject gameobject;                   //动作对象public Transform transform;                     //动作对象的transformpublic ISSActionCallback callback;              //回调函数//防止用户自己new对象protected SSAction() { }                      public virtual void Start() {throw new System.NotImplementedException();}public virtual void Update() {throw new System.NotImplementedException();}
    }
    
  • SSMoveToAction(移动位置子类)

    继承动作基类,实现移动到指定位置的子类。

    /*子类 - 移动到指定位置*/
    public class SSMoveToAction : SSAction {public Vector3 target;  public float speed;public static SSMoveToAction GetSSAction(Vector3 _target, float _speed) {//让unity自己创建一个SSMoveToAction实例确保内存正确回收SSMoveToAction action = ScriptableObject.CreateInstance<SSMoveToAction>();action.target = _target;action.speed = _speed;return action;}//C#必须显示声明重写父类虚函数public override void Start() {//该动作建立时无需任何操作}public override void Update() {this.transform.position = Vector3.MoveTowards(this.transform.position, target, speed * Time.deltaTime);//动作完成,通知动作管理者或动作组合if (this.transform.position == target) {this.destroy = true;this.callback.SSActionEvent(this);      }}
    }
    
  • SequenceAction(组合动作类)

    组合类中实现回调函数的接口ISSActionCallback,动作列表中每一个动作完成之后通知组合动作类,并且所有动作完成后也会通知该这个类的上一层组合类,被组合的对象和组合对象属于同一种类型,之后我们的动作也都是通过组合动作实现的,这样的结构稳固而可延展,可以实现我们所需要的绝大部分动作管理。

    /*动作组合*/
    public class SequenceAction : SSAction, ISSActionCallback {public List<SSAction> sequence;    //动作的列表public int repeat = -1;            //-1就是无限循环做组合中的动作public int start = 0;              //当前做的动作的索引public static SequenceAction GetSSAcition(int repeat, int start, List<SSAction> sequence) {//让unity自己创建一个SequenceAction实例SequenceAction action = ScriptableObject.CreateInstance<SequenceAction>();action.sequence = sequence;action.repeat = repeat;action.start = start;return action;}public override void Start() {//对每个动作执行foreach (SSAction action in sequence) {action.gameobject = this.gameobject; action.transform = this.transform;action.callback = this;                 //每一个动作的回调函数为该动作组合action.Start();}}public override void Update() {if (sequence.Count == 0) return;if (start < sequence.Count) {sequence[start].Update();               //start在回调函数中递加}}//实现接口ISSActionCallbackpublic void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,int intParam = 0, string strParam = null, Object objectParam = null) {source.destroy = false;                     //可能会无限循环所以先不删除this.start++;                               //下一个动作if (this.start >= sequence.Count) {this.start = 0;if (repeat > 0) repeat--;               //repeat<0就不会再减小if (repeat == 0) {                      //动作组合结束this.destroy = true;                //删除this.callback.SSActionEvent(this);  //通知管理者}}}void OnDestroy() {//如果自己被删除则应该释放自己管理的动作   }
    }
    
  • SSActionManger(动作管理基类)

    负责管理所有的动作或动作组合,给他们绑定游戏对象并且控制动作的执行或者完成后删除,也实现了ISSActionCallback接口,用于接受动作是否完成的消息,不过在我们的游戏之中对象仅有移动位置这个动作,所以回调函数不需要做任何事情。

    /*动作管理基类*/
    public class SSActionManager : MonoBehaviour, ISSActionCallback {private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    //动作字典private List<SSAction> waitingAdd = new List<SSAction>();                       //等待执行的动作列表private List<int> waitingDelete = new List<int>();                              //等待删除动作的key的列表                protected void Update() {//获取动作实例将等待执行的动作加入字典并清空待执行列表foreach (SSAction ac in waitingAdd) {actions[ac.GetInstanceID()] = ac;                                       }waitingAdd.Clear();//对于字典中每一个pair,看是执行还是删除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);Object.Destroy(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();}public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,int intParam = 0, string strParam = null, Object objectParam = null) {}
    }
    
  • PADSceneActionManager(牧师与魔鬼场景的动作管理类)

    先与对应的场景控制器绑定,然后实现两个具体动作:

    1. 船移动:一个动作,从当前位置以speed的速率移动到endPos。
    2. 角色移动:两个动作,从当前位置以speed的速率移动到middlePos,再以speed的速率移动到endPos。
    /*本次游戏场景中动作管理类*/
    public class PADSceneActionManager : SSActionManager {public FirstControllor sceneController;private SequenceAction boatMove;private SequenceAction roleMove;protected void Start() {sceneController = (FirstControllor)SSDirector.GetInstance().CurrentScenceController;sceneController.actionManager = this;}protected new void Update() {base.Update();}public void moveBoat(GameObject boat, Vector3 endPos, float speed) {SSAction action1 = SSMoveToAction.GetSSAction(endPos, speed);boatMove = SequenceAction.GetSSAcition(0, 0, new List<SSAction> { action1 });this.RunAction(boat, boatMove, this);}public void moveRole(GameObject role, Vector3 middlePos, Vector3 endPos, float speed) {//两段移动SSAction action1 = SSMoveToAction.GetSSAction(middlePos, speed);SSAction action2 = SSMoveToAction.GetSSAction(endPos, speed);//repeat=1,start=0,两个动作roleMove = SequenceAction.GetSSAcition(1, 0, new List<SSAction> { action1, action2 });this.RunAction(role, roleMove, this);}
    }
    

    至此动作管理的代码都已实现。

修改已有代码

  • 将MoveCortrollor.cs删除,有了动作管理类就不再需要移动控制器了。

  • 将BoatModel和RoleModel中的与运动相关的方法删去,添加各自的speed。

  • 在FirstCortrollor类中加入动作管理类

    public PADSceneActionManager actionManager; //添加动作管理类

    并且修改MoveBoat和MoveRole,使用动作管理器来实现,场景控制器只负责传递游戏对象和位置信息。

新增裁判类

  • 将原来的check从用户接口中删除,check的实现从FirstCortrollor.cs中删除

  • 新增Check.cs

    using UnityEngine;namespace CheckApplication {public class Check : MonoBehaviour {public FirstControllor sceneController;protected void Start() {sceneController = (FirstControllor)SSDirector.GetInstance().CurrentScenceController;sceneController.gameStatusManager = this;}public int CheckGame() {//0-游戏继续,1-失败,2-成功int startPriests = (sceneController.startLand.GetRoleNum())[0];int startDevils = (sceneController.startLand.GetRoleNum())[1];int endPriests = (sceneController.endLand.GetRoleNum())[0];int endDevils = (sceneController.endLand.GetRoleNum())[1];if (endPriests + endDevils == 6) return 2;int[] boatNum = sceneController.boat.GetRoleNumber();//加上船上的人if (sceneController.boat.GetBoatSign() == 1) {startPriests += boatNum[0];startDevils += boatNum[1];}else {endPriests += boatNum[0];endDevils += boatNum[1];}if ((endPriests > 0 && endPriests < endDevils) || (startPriests > 0 && startPriests < startDevils)) {return 1;}return 0;}}
    }
    
  • 在FirstCortrollor中增加裁判:public Check gameStatusManager;

github项目地址->?

演示视频地址->?

视频与原版无任何差别。

再次感谢师兄的博客供参考学习->?

Unity3D项目四:牧师与魔鬼(动作分离版)相关推荐

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

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

  2. Unity3D游戏编程-牧师与恶魔 动作分离版

    Unity3D游戏编程-牧师与恶魔 动作分离版 文章目录 Unity3D游戏编程-牧师与恶魔 动作分离版 作业要求 项目配置 项目演示 视频演示 项目下载 文字说明 项目截图 实现过程和方法(算法) ...

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

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

  4. Unity实现牧师与魔鬼动作分离版

    牧师与魔鬼动作分离版 项目地址 动作管理器的设计 程序设计框架: 为了用一组简单的动作组合成复杂的动作,我们采用 cocos2d 的方案,建立与 CCAtion 类似的类. 通过门面模式(控制器模式) ...

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

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

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

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

  7. 基于Unity开发的牧师与魔鬼动作分离版游戏设计

    1 作业要求 牧师与魔鬼 动作分离版 设计一个裁判类,当游戏达到结束条件时,通知场景控制器游戏结束 2 实现细节 在原来代码的基础上,修改如下: 将UserGUI的sign成员变量和Controlle ...

  8. 牧师与魔鬼-动作分离版

    源码传送门 视频展示传送门,展示效果与第三次作业相同 运行说明:将Controllor.cs挂载Main Camera上,然后点击运行即可 1. 动作分离 目的:将物体的动作与空间属性分开来,从而降低 ...

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

    本次游戏实现参照课件的框架,将动作管理与游戏场景分离. 完全按照课件的思路实现 动作基类SSAction 简单动作MoveToAction 组合动作SequenceAction 动作管理基类SSAct ...

  10. 用Unity3D实现简单的牧师与魔鬼游戏(动作分离版)

    用Unity3D实现简单的牧师与魔鬼游戏(动作分离版) 项目地址 牧师与魔鬼游戏(动作分离版) 完成效果图 上次博客链接 牧师与魔鬼游戏 实现心得 这次作业是在上次作业的基础上完成的,具体做出的改变是 ...

最新文章

  1. linux docker 权限划分介绍 capabilities
  2. msvc/gcc:中用#pragma指令关闭特定警告(warning)
  3. 初识设计模式、软件设计的六大原则
  4. linux 占用内存 脚本,linux内存测试(占用)脚本
  5. java ueditor 图片上传加水印_Ueditor编辑器上传图片加水印【亲测可用】-帝国CMS整合...
  6. pyspark启动时卡住了
  7. win2008 mysql_mysql5.7.17在win2008R2的64位系统安装与配置实例
  8. DB2对年份的处理Year()
  9. mysql 表 页 行_Mysql之InnoDB行格式、数据页结构
  10. HTTP协议 (五) 代理
  11. 使用mybatis生成UUID
  12. keil5安装STC芯片包
  13. 【毕业设计】大数据疫情数据分析及可视化系统 - python
  14. [2020.12.6 解决docker容器乱码问题] 一劳永逸export env LANG=C.UTF-8永久支持中文,无需Dockerfile重建镜像
  15. python居然能语音控制电脑壁纸切换,只需60行代码
  16. 计算机图形学常用算法
  17. VLDB论文解读:阿里云超大规模实时分析型数据库AnalyticDB
  18. 番茄花园版侵权被禁,用户怎么办?
  19. 大坑:c++如何输入带空格的字符串?
  20. vr云游全景展示,用一部手机看遍各大景区

热门文章

  1. Android Studio打开Android Device Monitor提示An error has occurred. See the log file......
  2. word 文档中嵌入和链接OLE 对象|Packager-对象包装程序
  3. 怎么保证方舟服务器的稳定,方舟确保加入服务器运行最新怎么解决mod | 手游网游页游攻略大全...
  4. 计算机常用英语词汇700词(一)
  5. 2018-06-06-markdown-推荐markdown编辑器
  6. 说说超链接 target 属性的取值和作用?
  7. 《Node.js 极简教程》 东海陈光剑
  8. excel-常用函数
  9. 论“结婚生孩子要趁早”,否则真正的是“上有老下小”
  10. 如何查看远程计算机端口是否,怎么检查win7电脑3389端口是否被开启