Giter Club home page Giter Club 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  avatar

Watchers

 avatar  avatar  avatar

2dexplorer's Issues

Add GameState to manager global state changes

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

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

事件列表:

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

Show HP as Sprite

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

More Animations

实现若干动画:

  • 0. 炮塔瞄准动画

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

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

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

Tilemap External GameObject Manager

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

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

Add Sounds

AudioManager 应该支持的功能:

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

Settings Manager

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

Add camera zone controller

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

More turrets

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

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

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

Fix collision relevant problems

已知问题:

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

UI System

具体的需求项目:

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

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

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.