Code Monkey home page Code Monkey logo

2dexplorer's Introduction

2D 探索游戏

游戏规则

操纵主角在地图上避开机关的攻击, 找到出口.

开发笔记

开发过程中对某些模块的使用心得.

项目结构

文件目录

仅描述 Assets 文件夹.

  • Audios: 音频文件
  • GameFramework: 导入的 GameFramework
  • Materials: 大部分材质球
  • Plugins: 插件
  • Prefabs: 预制体
  • Resources: 仅 DOTween 使用
  • Scenes: 场景
  • Scripts: 脚本
  • Settings: 记录游戏设置的 ScriptableObject
  • Shaders: 用 ShaderGraph 制作的 shader
  • Sprites: 2D Sprite
  • Tiles: 瓦片模板和画板(编辑器用)

代码结构

该游戏核心代码程序集定义在Scripts的根目录下, Editor 里是另一个程序集. 通过定义程序集的方式将项目中的代码切割为不同的编译对象, 减少代码变更时的编译代价, 同时也能强化各个模块的独立性, 明确依赖关系.

  • CharCtrl: 角色控制. 操控刚体和按键映射
  • DI: 依赖注入相关. 定义场景中的类的绑定关系
  • Editor: 编辑器相关, 为某些类添加辅助功能
  • EditorTool: 简化编辑器代码的一些工具
  • Effect: 特效实现
  • Entity: 实体. 如主角, 炮塔, 子弹
    • Decorator: 修饰实体的组件, 如引力场
  • Game: 游戏过程总的管理中心, 包括游戏状态的管理
  • TileDataIO: 瓦片数据输入输出, 管理瓦片数据的序列化, 也包括瓦片所对应的外部 GO.
  • Tiles: 瓦片类
  • TileTool: 瓦片地图相关的一些工具类
  • Unitilities: Unitilities 所在目录

引入的非官方包和插件

  • ZenJect GitHub链接 本地插件路径: 围绕 Unity 的控制反转依赖注入模块

    • 摆脱简单单例模式带来的依赖顺序问题
    • 提供一个比 Awake() 更早的依赖注入, 对场景静态物体而言相当于增加了一个比 Awake()更早的事件
    • 面向接口的绑定关系
  • DOTween 官网链接 本地插件路径: 一个灵活而方便的动画过渡过程控制插件

    • 将空间变换, Material 属性变化, Rigidbody 运动过程等常用的动画过渡过程(下称 Tween )实现为扩展方法, 可以直接用一个方法触发
    • Tween 提供丰富控制参数, 如过渡方式
    • Tween 提供完善的控制方法和回调函数, 包括 Kill(), OnComplete(callback)
    • 易于实现连续动画过程, 或称序列 Sequence
  • UnityGameFramework GitHub链接 本地插件路径: 一个包含常见业务逻辑和设计模式的框架

    • 有限状态机IFsm<T>实现了由状态机实例管理被管理的目标对象, 状态类仅实现逻辑不记录额外信息的状态机模式.
    • 事件系统实现了一个线程安全的事件订阅-发布机制, 使用整型 id 进行事件绑定
  • Unitilities GitHub链接 本地路径: 由 @LovelyCatHyt 制作的 Unity 的一些工具类

    • 很多零碎的小东西, 但也有比较独立的模块
    • 使用 git submodule 实现源码级依赖
    • 随本项目的开发而不定期更新

2dexplorer's People

Contributors

lovelycathyt avatar

Stargazers

 avatar Tworan avatar

Watchers

James Cloos avatar  avatar Tworan avatar

2dexplorer's Issues

Tilemap External GameObject Manager

提供一个外部接口, 能够访问在场景运行前就存在的, 与某些瓦片位置相对应的 GO.
由于外部的 GO 通常没有放在瓦片地图物品下, 不具备具体的层次的概念, 因此可以直接构建一个面向整个网格地图的代理类, 提供一个坐标点上一整层的瓦片数据的访问接口.
至少应该提供:

  • 储存多层瓦片数据的结构体
  • Set/GetTile
  • 自动记录/被动记录GO与具体位置瓦片的绑定关系. 注意仅考虑外部物体, 不考虑由 Tilemap 实例化的物体.

More Animations

实现若干动画:

  • 0. 炮塔瞄准动画

这种动画是实时更新的无状态动画, 因此直接写具体的计算公式就行.

  • 1. 炮塔发射动画
  • 2. 检查点触发/关闭动画
  • 3. 子弹攻击动画

上述动画1~3都属于单次触发, 不存在打断的动画.
但是从动画实现的角度看, 炮塔动画和检查点动画都是控制所挂载的GO, 而子弹攻击可以简单生成一个用完即毁的GO.

Add camera zone controller

能够控制摄像机所处的区域.
比较简单的实现是, 设定一个包含一大片矩形区域的 Trigger, 主角进入后修改摄像机的限制范围.
两个依赖: 主角和摄像机. 主角可以在OnTriggerEnter2D里获取/检测, 而摄像机可以直接 Zenject 注入.

Settings Manager

Settings 显然是全局的. 应该使用一个非 UnityEngine.Object 的类来管理, 用 Zenject 进行跨场景数据保留.

UI System

具体的需求项目:

  • 暂停/恢复按钮, 退出游戏按钮
    - [ ] 可以随时召唤的在场景中固定位置(和大小?)的标签
  • 设置项目, 虽然目前只有音量相关的可以设置
  • #14
  • ListView: 列表视图, 能管理列表元素, 但也可以做一个普通的没代码的模板, 然后由具体的业务来处理具体的问题.

类结构: 无法确定, 大部分情况直接在 Inspector 里指定 UnityEvent 也差不多

Add GameState to manager global state changes

需要管理游戏全局的一些关键状态, 并分发事件
状态列表:

  • NotEntered 未进入游戏
  • Loading 正在载入地图
  • InGame 游戏中
  • Paused 暂停
  • Saving 正在保存地图
    - [ ] [可选]Quiting 正在退出游戏

事件列表:

  • onGameStart
  • onBeforeLoading
  • onLoadFinished
  • onBeforeSave
  • onSaveFinished
  • onBeforePause
  • onPauseFinished

Fix collision relevant problems

已知问题:

  • 子弹撞墙不会自毁, 允许与 Default 的碰撞可以解决问题, 但此时 AttractField 也会吸引子弹
  • 重载地图后 CameraBoundsSetter 不能正常触发
    原因是重载后的碰撞盒范围重置了 2333
  • 尽管 Trigger 恰好相接触, 但仍然存在临界状态: 主角从A刚进入B, 但没完全进入又返回A, 此时摄像机范围取了B的范围, 实际主角在A区

Show HP as Sprite

以 sprite 的形式显示血条. 这样比较创新.
具体而言, 可以在球上画一个环(或者扇形), 环的比例表示血量.

Add Sounds

AudioManager 应该支持的功能:

  • AudioManager 应该是非 MonoBehavior 的一个类, 通过 Zenject 注入
  • 分频道控制音频
    • int id 索引频道, 但可以用字符串获取频道的 id
    • 频道音量
    • [可选] 频道最大音源数目
      - [ ] [可选] 频道混音器参数
  • 使用 ScriptableObject 保存音频参数

More turrets

更多的炮塔类型
为了实现灵活设计炮塔原型, 可以将目前的炮塔拆解成几个抽象模块:

  • Detector: 检测玩家. 可以有不同的检测方法, 比如射线, IsTrigger 的碰撞体, 定时(这个似乎也能再提出来一个模块)
  • TurretAnim: 炮塔特效: 比较独立, 可以接收事件控制瞄准动画, 待机动画
  • Gun: 执行发射操作, 可以定制不同的子弹发射行为: 发射数目, 发射方向, 是否延时发射子弹序列等等
  • BulletFactory: 子弹工厂. 这个可以是一个全局唯一的实体, 然后为了能在inspector操作, 可以用一个enum或string指定?

如果想更进一步提高灵活性, 可以将上面所有的组件都做成可动态配置的. 但是这个工作量可能直接 double 了 :(
实现一个炮塔工厂, 完成自动注入如何?
但是炮塔似乎也没有必要做太高的灵活性, 提供若干个模板已经足够了, 因此在Tile上让Tilemap来实例化, 然后加个 ZenjectAutoInjector 应该能保证依赖及时注入. 至于炮塔参数随游戏进程动态变化, 大可以做个全局的控制, 有 Zenject 的情况下不是什么大问题.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.