6 Star 45 Fork 15

京产肠饭/HKUnityTools

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

HKUnityTools介绍:

HKUnityTools 是我们团队在 Unity 项目中开发的工具集,涵盖编辑器和运行时功能,旨在优化工作流程并降低开发负担。若有任何疑问,欢迎联系 QQ : 511919078 微信 : JingChanChangFan

本项目部分模块基于:

  • QFramework v1.0.189
  • Dotween v1.2.765

HKUnityTools更新日志:https://kdocs.cn/l/caGHelWvXD0f

团队案例:https://kdocs.cn/l/csfyzM0GfoI9

(号外!我们团队位于青岛,专注于XR、虚拟仿真及数字化展项等项目开发,现诚邀开发者加入。感兴趣请私信或联系QQ和微信!)

Image text

HKUnityTools Gitee地址:传送门
QFramework Github地址:传送门
In-game Debug Console Github地址:传送门

初始设置(敲重点):

HKUnityTools 的扩展功能基于 QFramework 实现。在进行开发及测试时,默认采用 HK_DefaultArchitecture 框架。当在其他项目中引入 HKUnityTools 时,务必替换为对应项目的框架(Architecture),同时注册 HKUnityTools 的系统层、模型层和工具层,否则相关功能将无法正常使用

对于新建的 Unity 工程,可借助“自动化生成项目脚本模板”工具,依据 QFramework 的规则生成初始化模板,生成后在全局设置里更改当前框架(Architecture)。

1.全局设置:

提供专门的全局设置窗口,便捷管理和切换 HKUnityTools 所应用的框架(Architecture),并配置各类工具的启用状态。

使用方式:

  1. 在 Unity 编辑器的菜单栏中,依次点击 HKTools -> GlobalSettings...(全局设置)。
  2. 弹出的编辑器窗口将自动检测本工程中所有继承自 Architecture 的框架类,通过点击下拉菜单,选取当前项目所适用的 Architecture。
  3. 点击“设置为当前 Architecture”按钮,完成 HKTools 使用框架的重新设定,并自动对 HK_ArchitectureProvider.cs 脚本文件进行更新。

Image text

  1. 此外,亦可通过手动修改位于 Assets/HKTools/GlobalSettings/HK_ArchitectureProvider.cs 路径下的 HK_ArchitectureProvider 脚本文件,来设定对应的框架(Architecture)。
    /// <summary>
    /// HKTools 框架提供工具
    /// </summary>
    public static class HK_ArchitectureProvider
    {
        static IArchitecture architecture;

        /// <summary>  
        /// 获取当前项目的架构实例,确保在第一次访问时进行初始化。  
        /// </summary>  
        public static IArchitecture Architecture
        {
            get
            {
                // 懒加载架构实例  
                if (architecture == null)
                {
                    SetArchitecture();
                }
                return architecture;
            }
        }

        /// <summary>  
        /// 设置当前项目的架构实例。  
        /// </summary>  
        static void SetArchitecture()
        {
            // 修改此处,设定为当前项目 Architecture 框架
            architecture = HKTools.HK_DefaultArchitecture.Interface;
        }
    }

2.自动化生成项目脚本模板:

本工具是一款用于 Unity 编辑器的扩展工具,旨在根据QFramework框架规则,自动生成Unity项目的脚本模板和基础文件夹结构。可以帮助开发者快速搭建项目架构,提高效率,主要功能如下:

  • 快捷使用:
    • 在菜单栏中,找到 HKTools -> Auto Generate Template(自动化生成项目模板) 选项,并点击。
    • 可自定义 Architecture 框架名称,用于命名脚本文件;若未指定,则默认使用当前工程ProductName作为框架名。
    • 在打开的窗口中点击 “项目模板生成” 按钮,并在弹出的提示窗口中点击 “确认” 按钮,自动生成项目模板。
  • 自动生成文件夹结构:在项目的 Assets 目录下,自动创建 _Scripts 文件夹及其子文件夹,具体结构如下:
    • _Scripts
      • Commands
      • Events
      • Models
      • Systems
      • ViewControllers
  • 自动生成脚本模板:根据项目名称和预定义的模板,自动生成以下脚本文件:
    • 项目架构脚本:[项目名]_Architecture.cs,继承自 QFramework 的 Architecture,负责注册模型层、系统层,是整个项目的核心架构。
    • 控制器通用基类脚本:Controller.cs,视图层的基类,提供对项目架构的引用,方便在视图中使用架构内的功能。
    • 初始化数据模型层脚本:IInitModel.cs,定义初始化数据的模型层接口和实现类,存储和管理初始化数据,例如配置文件等。
    • 运行时数据模型层脚本:IRuntimeModel.cs,定义运行时数据的模型层接口和实现类,用于存储和管理运行时数据,例如各类状态、进度等。
    • 全局事件脚本:Events_Global.cs,用于声明全局范围内的事件和消息,方便事件的统一管理。
    • 音频管理系统层脚本:IAudioSystem.cs,定义音频管理系统接口和实现类,负责管理音频播放、音量控制等功能。
  • 注意事项:
    • 避免重复生成:工具会检测 Assets 根目录下是否已存在 _Scripts 或 _Script 文件夹,若存在则取消操作,以防止覆盖原有文件。
    • 项目名称规范:工具会将自定义的 Architecture 名称进行合法性过滤,移除数字开头及非法字符,若没有制定的 Architecture 名称,则将根据当前工程的 ProductName(项目名称)进行命名,请确保Unity工程项目名称已正确设置。

Image text


运行时功能:

1. HK_FreeCam:

功能描述:

HK_FreeCam 是一款轻量级的运行时摄像机控制系统,为开发调试阶段设计的场景漫游预览工具。主要功能包括:

  • 全自由度摄像机控制:支持 WASD 三维移动、鼠标右键视角旋转和滚轮视野缩放
  • 动态加速机制:按住 Shift 键可实现移动加速(默认加速倍率为 2x)
  • 俯仰角限制:防止摄像机翻转(默认俯仰角范围:-45° 至 +45°)
  • 即插即用:无需复杂配置,移除后无残留依赖

使用方式:

  • 将 HK_FreeCam.cs 脚本添加到某个物体或主摄像机上(MainCamera)。
  • 调整 HK_FreeCam 组件上的的参数,如下:
    参数名 类型 默认值 说明
    Move Speed float 10 移动速度
    Rotate Speed float 300 视角旋转灵敏度
    X Axis Range Vector2 (-45,45) 俯仰角度限制
  • 运行时,按住 W、A、S、D 键,进行前后左右移动。
  • 运行时,按住 Q、E 键进行上下移动。
  • 运行时,按住 Shift 键,进行移动加速。
  • 运行时,按住 鼠标右键并移动鼠标,进行视角旋转。
  • 运行时,滑动 鼠标滚轮,进行视野缩放。
  • 开发调试阶段后,可将 HK_FreeCam.cs 脚本移除。

外部依赖:



2. HK_TargetCam(基于 QFramework 架构):

功能描述:

HK_TargetCam 是一款多功能的Unity摄像机多目标管理系统,能够在项目中实现 Camera 在多个 Target 之间的平滑切换与精确控制。主要功能如下:

多目标切换,各目标类型及切换效果如下:

  • RotTarget:控制 Camera 围绕 Target 旋转、缩放,并可设置旋转边界。
  • AreaTarget:在 Target 设定的区域内,实现 Camera 的自由平移与缩放。
  • FollowTarget:Camera 跟随 Target 移动,同时支持围绕 Target 的旋转与缩放。
  • BirdViewTarget:在 Target 设定区域内,提供 Camera 的俯仰与缩放控制,并切换至正交视角。

运行时控制功能:

  • 通过 Command 指令,可进行切换目标。
  • 通过 Command 指令切换目标时,可配置以下参数:
    • Camera 缩放速度
    • Camera 移动速度
    • 俯仰角限制
    • 目标切换动画时间
    • 是否冻结操控
  • 通过 Event 事件,可订阅目标切换开始/完成事件。
  • 通过 Query 查询指令,可查询当前目标。
  • 支持闪现/眨眼效果的目标切换。
  • 支持可视化编辑,可在 Scene 视窗中进行目标编辑。

Image text

使用方式:

  • 在当前项目的 Architecture 中注册 IHK_TargetCamSystem。
public class XXX_Architecture : Architecture<XXX_Architecture>
{
    protected override void Init()
    {
        this.RegisterSystem<IHK_TargetCamSystem>(new HK_TargetCamSystem());
    }
}
  • 删除场景中默认的Main Camera,将 TargetCamera 预设体拖入场景中。
  • 在 Scene视窗右上角,开启Gizmos单选按钮(本工具可视化编辑部分,是基于Gizmos绘制的)。

Image text

  • 根据项目需求,在当前场景中添加 RotTarget、AreaTarget、FollowTarget、BirdViewTarget,可以通过拖拽预设体到场景中进行快速编辑。
  • 编辑 HK_RotTarget、HK_AreaTarget、HK_FollowTarget、BirdViewTarget 的目标类型(TargetType),可点击“根据物体名称,添加 Target 类型”按钮,将根据当前选中物体的名称自动添加相应的 TargetType,添加后即可在Inspector中选择,无需手动修改代码,简化操作流程。

Image text

  • 目标类型(TargetType)是本工具的核心属性之一。系统将根据此属性来进行目标切换。为确保工具的正常运行,请务必保证在同一场景下该属性的唯一性。若发现重复设置,系统将发出警告提示。

Image text

  • 对场景中各目标的 HK_RotTarget、HK_AreaTarget、HK_FollowTarget、HK_BirdViewTarget 等组件,调整其各项属性,如 FOV(视场角)、默认距离等核心参数,以满足项目需求。
  • 对场景中的 TargetCamera 物体的 HK_TargetCamera 组件,进行初始化参数调整。
  • 若 HK_TargetCamera 组件指定了 initTarget (初始化目标点),则运行后 TargetCamera 会自动切换到 initTarget 对应的目标。
  • 运行时,可发送 CMD_SetMoveAndZoomSpeed 指令(并传入对应参数)设置 Camera 默认的MoveSpeed(默认值为1.5)和ZoomSpeed(默认值为3)。
// 设置相机的移动速度和缩放速度
this.SendCommand(new CMD_SetMoveAndZoomSpeed(1.5f, 3));
  • 运行时,可发送 CMD_SetPitchAngle 指令(并传入对应参数)设置 Camera 的俯仰角范围。
// 设置相机的俯仰角范围
this.SendCommand(new CMD_SetPitchAngle(5, 85));
  • 运行时,可发送 CMD_SetTargetChangeTime 指令(并传入对应参数)设置 Camera 切换目标的运动市场。
// 设置相机切换目标的运动市场为2秒
this.SendCommand(new CMD_SetTargetChangeTime(2f));
  • 运行时,可发送 CMD_SetFreezeMode 指令(并传入true/false)对 TargetCamera 进行冻结/解冻。
// 冻结相机
this.SendCommand(new CMD_SetFreezeMode(true));
// 解冻相机
this.SendCommand(new CMD_SetFreezeMode(false));
  • 运行时,可发送 CMD_ChangeCamTarget 指令(并传入对应参数)进行 Camera 目标切换。
// 相机切换至 RotTarget_01
this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_01));
  • 可通过 SetUsingFlash 链式方法,设置相机目标切换为闪现方式(默认启用眨眼特效,若不启用则传入false)。
// 相机切换至 RotTarget_01,使用闪现的方式
this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_01).SetUsingFlash());
  • 运行时,可发送 Query_GetCurrentTarget 查询指令,查询当前目标。
// 获取当前相机的目标类型
HK_TargetEnum targetType = this.SendQuery(new Query_GetCurrentTarget());
  • 可订阅事件,在摄像机目标切换前后进行响应:
    • 订阅 Event_SwitchTargetBegin 事件,当目标切换开始时接收到该事件。
    • 订阅 Event_SwitchTargetEnd 事件,当目标切换完成后接收到该事件。
  • 具体用法,可参考 Test_UseTargetCam 脚本。
using UnityEngine;
using QFramework;
using DG.Tweening;
using HKTools;
using UnityEngine.UI;

/// <summary>
/// Camera多目标切换管理工具,测试脚本
/// </summary>
public class Test_UseTargetCam : HKTargetCam_BaseController
{
    // 相机状态及设置
    [SerializeField] Text tips_Txt;
    [SerializeField] Toggle toggle_FreezeCam;
    [SerializeField] Button btn_QueryTarget;
    [SerializeField] Slider slider_TargetChangeTime;
    [SerializeField] Text txt_TargetChangeTime;
    [SerializeField] Button btn_Ensure;

    // 正常切换方式的按钮
    [SerializeField] Button btn_RotTarget01;
    [SerializeField] Button btn_RotTarget02;
    [SerializeField] Button btn_RotTarget03;
    [SerializeField] Button btn_RotTarget04;
    [SerializeField] Button btn_AreaTarget01;
    [SerializeField] Button btn_AreaTarget02;
    [SerializeField] Button btn_BirdViewTarget01;
    [SerializeField] Button btn_FollowTarget01;

    // 闪现切换方式的按钮
    [SerializeField] Button btn_RotTarget01_Flash;
    [SerializeField] Button btn_RotTarget02_Flash;
    [SerializeField] Button btn_RotTarget03_Flash;
    [SerializeField] Button btn_RotTarget04_Flash;
    [SerializeField] Button btn_AreaTarget01_Flash;
    [SerializeField] Button btn_AreaTarget02_Flash;
    [SerializeField] Button btn_BirdViewTarget01_Flash;
    [SerializeField] Button btn_FollowTarget01_Flash;

    // 测试用的移动目标
    [SerializeField] Transform testMoveNPC;

    void Start()
    {
        // 设置相机的移动速度和缩放速度
        this.SendCommand(new CMD_SetMoveAndZoomSpeed(1.5f, 3));

        // 设置相机的俯仰角度范围,从5度到85度
        this.SendCommand(new CMD_SetPitchAngle(5, 85));

        toggle_FreezeCam.onValueChanged.AddListener(isOn =>
        {
            if (isOn)
            {
                // 冻结相机
                this.SendCommand(new CMD_SetFreezeMode(true));
            }
            else
            {
                // 解冻相机
                this.SendCommand(new CMD_SetFreezeMode(false));
            }
        });

        btn_QueryTarget.onClick.AddListener(() =>
        {
            // 获取当前相机的目标类型
            HK_TargetEnum targetType = this.SendQuery(new Query_GetCurrentTarget());
            HKDebug.Log("当前目标为:" + targetType.ToString());
        });

        txt_TargetChangeTime.text = slider_TargetChangeTime.value.ToString("0.00" + " 秒");
        slider_TargetChangeTime.onValueChanged.AddListener(value =>
        {
            txt_TargetChangeTime.text = value.ToString("0.00" + " 秒");
        });

        // 点击按钮,设置目标切换时间
        btn_Ensure.onClick.AddListener(() =>
        {
            var targetChangeTime = slider_TargetChangeTime.value;
            this.SendCommand(new CMD_SetTargetChangeTime(targetChangeTime));
        });

        btn_RotTarget01.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_01)));

        btn_RotTarget02.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_02)));

        btn_RotTarget03.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_03)));

        btn_RotTarget04.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_04)));

        btn_AreaTarget01.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.AreaTarget_01)));

        btn_AreaTarget02.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.AreaTarget_02)));

        btn_BirdViewTarget01.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.BirdViewTarget_01)));

        btn_FollowTarget01.onClick.AddListener(() =>
        {
            this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.FollowTarget_01));

            /*---------------------测试-----------------*/
            testMoveNPC.position = new Vector3(-15f, 1, 4.5f);
            testMoveNPC.DOMoveX(13f, 6f).SetEase(Ease.Linear).SetDelay(1f);
            /*------------------------------------------*/
        });

        btn_RotTarget01_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_01).SetUsingFlash()));

        btn_RotTarget02_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_02).SetUsingFlash()));

        btn_RotTarget03_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_03).SetUsingFlash()));

        btn_RotTarget04_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.RotTarget_04).SetUsingFlash()));

        btn_AreaTarget01_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.AreaTarget_01).SetUsingFlash()));

        btn_AreaTarget02_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.AreaTarget_02).SetUsingFlash()));

        btn_BirdViewTarget01_Flash.onClick.AddListener(() => this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.BirdViewTarget_01).SetUsingFlash()));

        btn_FollowTarget01_Flash.onClick.AddListener(() =>
        {
            this.SendCommand(new CMD_ChangeCamTarget(HK_TargetEnum.FollowTarget_01).SetUsingFlash());

            /*---------------------测试-----------------*/
            testMoveNPC.position = new Vector3(-15f, 1, 4.5f);
            testMoveNPC.DOMoveX(13f, 6f).SetEase(Ease.Linear).SetDelay(1f);
            /*------------------------------------------*/
        });

        // 注册 开始切换 Target 事件
        this.RegisterEvent<Event_SwitchTargetBegin>(args =>
        {
            HKDebug.Log($"开始 切换 Target:{args._targetEnum}");
        }).UnRegisterWhenGameObjectDestroyed(gameObject);

        // 注册 完成切换 Target 事件
        this.RegisterEvent<Event_SwitchTargetEnd>(args =>
        {
            HKDebug.Log($"完成 切换 Target:{args._targetEnum}");
            tips_Txt.text = $"当前 Target 为:{args._targetEnum}";
        }).UnRegisterWhenGameObjectDestroyed(gameObject);
    }
}

外部依赖:

  • Dotween
  • ActionKit

3. HK_RoamingCam(基于 QFramework 架构):

功能描述:

  • PC端、WebGL端、Android端虚拟展厅类体验相机控制管理工具;
  • 支持通过鼠标点击、手指触摸两种方式进行交互;
  • 视角控制分为:第一人称漫游、三维俯视漫游、鸟瞰正交漫游三种模式;
  • 第一人称漫游(RoamView):通过点击地面标识点进行位移(依赖Unity Navigation);
  • 鸟瞰正交漫游(BirdView):上帝视角进行观察,相机为 Orthographic
  • 三维俯视漫游(ThreeDView):上帝视角进行观察,相机为 Perspective

使用方式:

  • 在本项目的 Architecture 中注册 IHK_RoamingCamSystem;
  • 在场景中设置好Navigation Static,并进行 Navigation烘焙,生成合适的NavMesh;
  • 在场景中指定 RoamView 使用的 Point点位(附带HK_Point脚本),并设置好LookAtType;
  • 在场景中指定好 BirdView和ThreeDView 使用的 OverlookPos及RotAroundTarget;
  • 将HK_RoamPlayer预设体放入场景中,并进行初始化设置;
  • 具体用法,可参考Test_UIRoamCamCtrl 脚本;

外部依赖:

  • Dotween

4. HK_FirstPersonCam(基于 QFramework 架构)

功能描述:

  • PC端的第一人称视角控制相机;
  • 支持通过鼠标、键盘进行第一人称角色控制;

使用方式:

  • 在本项目的 Architecture 中注册 IHK_FirstPersonCamSystem;
  • 将场景中需碰撞的物体(如地面等),设置好碰撞体,并设置好Layer;
  • 将 FirstPersonPlayer 预设体,拖入场景中;
  • 在 FirstPersonPlayer 预设体的 HK_FirstPersonCtrl 组件中,设置好 GroundMask 层级;
  • 设置完成后即可通过鼠标、键盘进行操控,按住鼠标右键控制角色旋转,按WASD键控制角色移动;
  • 在表现层脚本中通过发送 CMD_ChangeFirstPersonPos 指令(并传入对应参数),可根据目标切换位置;
  • 参考 Test_FirstPlayerCamChangePos 进行位置切换设置;

外部依赖:

  • Dotween
  • ActionKit

5. HK_SimpleTaskSystem(基于 QFramework 架构):

功能描述:

HK_SimpleTaskSystem 是一个基于 QFramework 的简易任务管理系统,适用于 线性任务队列 的使用场景。使用枚举 (enum) 定义 任务队列(TaskQueue)和 任务(Task),可根据业务需求,自定义任务队列和任务步骤。主要功能特点如下:

  • 无外部配置:没有外部配置,在代码中通过枚举定义任务队列和任务;
  • 线性任务队列:任务按顺序执行,适用于按照线性步骤完成的简易任务流程;
  • 指令、查询及事件:
    • 通过指令(Command),初始化/驱动任务队列及任务
    • 通过查询(Query),获取任务队列的进度,或任务队列中所有的任务名
    • 通过事件(Event),监听任务队列及任务的状态变化

使用方式:

  • 注册任务系统:在当前项目的 Architecture 中注册 IHK_SimpleTaskSystem。
public class XXX_Architecture : Architecture<XXX_Architecture>
{
    protected override void Init()
    {
        RegisterSystem<IHK_SimpleTaskSystem>(new HK_SimpleTaskSystem());
    }
}
  • 自定义任务队列及任务:通过修改枚举类型 TaskQueueType 和 TaskType,定义自己的任务队列和任务(任务类型可新增)。
       /// <summary>
    /// 简易任务队列类型,只可对内部的枚举值进行新增或修改
    /// </summary>
    public enum STS_TaskQueueType
    {
        Queue1,
        Queue2,
    }

    /// <summary>  
    /// 任务队列1 相关任务,基于泛型使用,可新增或删除
    /// </summary>  
    public enum TaskQueue01
    {
        Step01_放置干扰天线支架,
        Step02_安装干扰天线,
        Step03_连接干扰天线与干扰源,
        Step04_放置抗干扰天线支架,
        Step05_安装抗干扰天线,
        Step06_连接抗干扰天线与电脑,
        Step07_将干扰天线对准抗干扰天线,
        Step08_放置标定天线,
    }

    /// <summary>  
    /// 任务队列2 相关任务,基于泛型使用,可新增或删除
    /// </summary>  
    public enum TaskQueue02
    {
        Step01_开启设备电源,
        Step02_初始化设备参数,
        Step03_运行设备自检,
        Step04_开始数据采集,
        Step05_保存采集结果,
    }
  • 初始化并开始任务队列:使用 CMD_STS_InitTaskQueue 指令,初始化并开始任务队列;
    Queue<TaskQueue01> taskQueue = new Queue<TaskQueue01>(new TaskQueue01[]
    {
        TaskQueue01.Step01_放置干扰天线支架,
        TaskQueue01.Step02_安装干扰天线,
        TaskQueue01.Step03_连接干扰天线与干扰源,
        TaskQueue01.Step04_放置抗干扰天线支架,
        TaskQueue01.Step05_安装抗干扰天线,
        TaskQueue01.Step06_连接抗干扰天线与电脑,
        TaskQueue01.Step07_将干扰天线对准抗干扰天线,
        TaskQueue01.Step08_放置标定天线,
    });

    // 初始化并开始 任务队列1 
    this.SendCommand(new CMD_STS_InitTaskQueue<TaskQueue01>(STS_TaskQueueType.Queue1, taskQueue));
  • 完成当前任务(按顺序):使用 CMD_STS_CompleteCurrentTask 指令,完成当前任务,任务将按照预先定义的顺序执行。(可传入延时时间,控制下个任务开始的时间)
    // 按顺序完成 任务队列1 当前任务
    this.SendCommand(new CMD_STS_CompleteCurrentTask(STS_TaskQueueType.Queue1));

    // 按顺序完成 任务队列1 当前任务,延时1.5秒后,开始下个任务
    this.SendCommand(new CMD_STS_CompleteCurrentTask(STS_TaskQueueType.Queue1, 1.5f));
  • 完成指定任务(按任务类型):使用 CMD_STS_CompleteAppointTask 指令,可通过任务类型完成当前任务,但仍要求按顺序执行,无法跳过未完成的任务。(可传入延时时间,控制下个任务开始的时间)
    // 完成步骤1
    this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step01_放置干扰天线支架));

    // 完成步骤1,延时1.5秒后,开始下个任务
    this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step01_放置干扰天线支架, 1.5f));
  • 查询任务队列所有任务名:使用 Query_STS_AllTaskNames 查询,可通过任务队列类型查询该队列所有的任务名。
    // 查询 任务队列1的所有任务名
    List<string> allTaskNames = this.SendQuery(new Query_STS_AllTaskNames(STS_TaskQueueType.任务队列1));
    allTaskNames.ForEach(taskName => HKDebug.Log(taskName));
  • 查询任务队列进度:使用 Query_STS_TaskQueue 查询,可通过任务队列类型查询该队列当前进度。
    // 查询 任务队列1的进度
    float progress = this.SendQuery(new Query_STS_TaskQueue(STS_TaskQueueType.任务队列1));
    HKDebug.Log($"任务队列1的进度为:{progress}");
  • 中断并终止任务队列:使用 CMD_STS_BreakUpTaskQueue 指令,中断并终止一个任务队列。
    // 中断 任务队列1
    this.SendCommand(new CMD_STS_BreakUpTaskQueue(STS_TaskQueueType.任务队列1));
  • 注册事件监听:提供以下 5 个事件,可根据需要进行注册,监听任务队列和任务的状态变化:
    • 任务队列开始事件:Event_STS_TaskQueueBegin
    • 任务队列结束事件:Event_STS_TaskQueueEnd
    • 任务队列中断事件:Event_STS_TaskQueueBreakUp
    • 任务开始事件:Event_STS_TaskStart
    • 任务完成事件:Event_STS_TaskFinish
    // 注册 任务队列开始 事件
    this.RegisterEvent<Event_STS_TaskQueueStart>(args =>
    {
        HKDebug.Log($"任务队列 开始:{args._taskQueueType}", LogColor.Blue);
    });

    // 注册 任务队列结束 事件
    this.RegisterEvent<Event_STS_TaskQueueFinish>(args =>
    {
        HKDebug.Log($"任务队列 结束:{args._taskQueueType}", LogColor.Blue);
    });

    // 注册 任务队列中断 事件
    this.RegisterEvent<Event_STS_TaskQueueBreakUp>(args =>
    {
        HKDebug.Log($"任务队列 中断:{args._taskQueueType}", LogColor.Yellow);
    });

    // 注册 任务开始 事件
    this.RegisterEvent<Event_STS_TaskStart>(args =>
    {
        HKDebug.Log($"任务 开始:{args._taskQueueType} : {args._taskName}", LogColor.Green);
    });

    // 注册 任务完成 事件
    this.RegisterEvent<Event_STS_TaskFinish>(args =>
    {
        HKDebug.Log($"任务 结束:{args._taskQueueType} : {args._taskName}", LogColor.Green);
    });
  • 在Unity编辑器下,运行时,可通过“HK_SimpleTaskViewer(简易任务系统查看器)”查看当前任务队列状态。

Image text

  • 具体用法,可参考 Test_UseSimpleTask 示例脚本。

示例代码:

/// <summary>
/// 简单版任务系统 演示测试脚本
/// </summary>
public class Test_UseSimpleTask : MonoBehaviour, IController
{
    public IArchitecture GetArchitecture()
    {
        return HK_ArchitectureProvider.Architecture;
    }

    void Start()
    {
        // 注册 任务队列开始 事件
        this.RegisterEvent<Event_STS_TaskQueueStart>(args =>
        {
            HKDebug.Log($"任务队列 开始:{args._taskQueueType}", LogColor.Blue);
        });

        // 注册 任务队列结束 事件
        this.RegisterEvent<Event_STS_TaskQueueFinish>(args =>
        {
            HKDebug.Log($"任务队列 结束:{args._taskQueueType}", LogColor.Blue);
        });

        // 注册 任务队列中断 事件
        this.RegisterEvent<Event_STS_TaskQueueBreakUp>(args =>
        {
            HKDebug.Log($"任务队列 中断:{args._taskQueueType}", LogColor.Yellow);
        });

        // 注册 任务开始 事件
        this.RegisterEvent<Event_STS_TaskStart>(args =>
        {
            HKDebug.Log($"任务 开始:{args._taskQueueType} : {args._taskName}", LogColor.Green);
        });

        // 注册 任务完成 事件
        this.RegisterEvent<Event_STS_TaskFinish>(args =>
        {
            HKDebug.Log($"任务 结束:{args._taskQueueType} : {args._taskName}", LogColor.Green);
        });
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.F1))
        {
            Queue<TaskQueue01> taskQueue = new Queue<TaskQueue01>(new TaskQueue01[]
            {
                TaskQueue01.Step01_放置干扰天线支架,
                TaskQueue01.Step02_安装干扰天线,
                TaskQueue01.Step03_连接干扰天线与干扰源,
                TaskQueue01.Step04_放置抗干扰天线支架,
                TaskQueue01.Step05_安装抗干扰天线,
                TaskQueue01.Step06_连接抗干扰天线与电脑,
                TaskQueue01.Step07_将干扰天线对准抗干扰天线,
                TaskQueue01.Step08_放置标定天线,
            });

            // 初始化并开始 任务队列1 
            this.SendCommand(new CMD_STS_InitTaskQueue<TaskQueue01>(STS_TaskQueueType.Queue1, taskQueue));
        }


        if (Input.GetKeyDown(KeyCode.F2))
        {
            Queue<TaskQueue02> taskQueue = new Queue<TaskQueue02>(new TaskQueue02[]
            {
                TaskQueue02.Step01_开启设备电源,
                TaskQueue02.Step02_初始化设备参数,
                TaskQueue02.Step03_运行设备自检,
                TaskQueue02.Step04_开始数据采集,
                TaskQueue02.Step05_保存采集结果,
            });

            // 初始化并开始 任务队列2
            this.SendCommand(new CMD_STS_InitTaskQueue<TaskQueue02>(STS_TaskQueueType.Queue2, taskQueue));
        }

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            // 中断 任务队列1
            this.SendCommand(new CMD_STS_BreakUpTaskQueue(STS_TaskQueueType.Queue1));
        }

        if (Input.GetKeyDown(KeyCode.Q))
        {
            // 查询 任务队列1的所有任务名
            List<string> allTaskNames = this.SendQuery(new Query_STS_AllTaskNames(STS_TaskQueueType.Queue1));
            allTaskNames.ForEach(taskName => HKDebug.Log(taskName));
        }

        if (Input.GetKeyDown(KeyCode.W))
        {
            // 查询 任务队列1的进度
            float progress = this.SendQuery(new Query_STS_TaskQueueProgress(STS_TaskQueueType.Queue1));
            HKDebug.Log($"任务队列1的进度为:{progress}");
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 按顺序完成 任务队列1 当前任务,延时1秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteCurrentTask(STS_TaskQueueType.Queue1, 1f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            // 完成步骤1,延时1.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step01_放置干扰天线支架, 1.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            // 完成步骤2,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step02_安装干扰天线, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            // 完成步骤3,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step03_连接干扰天线与干扰源, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            // 完成步骤4,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step04_放置抗干扰天线支架, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            // 完成步骤5,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step05_安装抗干扰天线, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha6))
        {
            // 完成步骤6,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step06_连接抗干扰天线与电脑, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha7))
        {
            // 完成步骤7,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step07_将干扰天线对准抗干扰天线, 0.5f));
        }

        if (Input.GetKeyDown(KeyCode.Alpha8))
        {
            // 完成步骤8,延时0.5秒开始下个任务
            this.SendCommand(new CMD_STS_CompleteAppointTask(STS_TaskQueueType.Queue1, TaskQueue01.Step08_放置标定天线, 0.5f));
        }
    }
}

外部依赖:

  • ActionKit

6. HK_TaskSystem(基于 QFramework 架构):

功能描述:

  • 任务管理系统(通过配置文件对任务流进行配置及编辑);
  • 可在Unity编辑器中对任务流进行编辑,编辑后在运行时进行使用。

使用方式:

  • 在当前项目的 Architecture 中注册 IHK_TaskSystem;
  • 本系统分三个层级:任务链 TaskList、任务 Task、条件 Condition;
  • 对外方法有四个:
    StartNewTaskList(string taskDataName) //开启 新的 任务链
    BreakOffTaskList() // 中断 当前 任务链
    AchieveCondition(HK_ConditionType condition) // 达成指定条件
    StopTaskAudio() // 停止当前播放的任务语音
    ImmediateFinishTaskList() // 立即完成当前任务连(主要用于开发测试)
  • 推荐使用Command指令来使用TaskSystem,四个对外方法分别对应四个Command:
    CMD_StartNewTaskList :开启新的任务链指令
    CMD_BreakOffTaskList :中断当前任务链指令
    CMD_AchieveCondition :达成指定条件指令(可传入延时时间,延时达成条件)
    CMD_StopTaskAudio :停止当前播放的任务语音指令
    CMD_ImmediateFinishTaskList :立即完成当前任务连(主要用于开发测试)
  • 可通过Query来查询某条件是否达成:
    Query_ConditionState : 查询某条件是否达成
  • 外部可监听事件有六个:
    Event_TaskListStart // 任务链开始 事件
    Event_TaskListFinish // 任务链结束 事件
    Event_TaskListBreadOff // 任务链中断 事件
    Event_TaskStart // 任务开始 事件
    Event_TaskFinish // 任务结束 事件
    Event_ConditionAchieve // 条件达成 事件

外部依赖:

  • ActionKit
  • AudioKit

示例代码:

public class Test_TaskUse : HK_TaskSystemController
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            this.SendCommand<CMD_BreakOffTaskList>();
        }
        if (Input.GetKeyDown(KeyCode.P))
        {
            this.SendCommand<CMD_StopTaskAudio>();
        }
        if (Input.GetKeyDown(KeyCode.F1))
        {
            this.SendCommand(new CMD_StartNewTaskList("到应聘公司"));
        }
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C1_1到电梯门口));
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            // 延时 1s 达成条件
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C1_2跟门卫打招呼, 1));
        }
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C2_1按电梯按键));
        }
        if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C2_2走到光圈位置));
        }
        if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C3_1选择指示标));
        }
        if (Input.GetKeyDown(KeyCode.F2))
        {
            this.SendCommand(new CMD_StartNewTaskList("参与面试"));
        }
        if (Input.GetKeyDown(KeyCode.Q))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C4_1回答问题1));
        }
        if (Input.GetKeyDown(KeyCode.W))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C4_2回答问题2));
        }
        if (Input.GetKeyDown(KeyCode.E))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C5_1做笔试题1));
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            this.SendCommand(new CMD_AchieveCondition(HK_ConditionType.C5_2做笔试题2));
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            bool isConditionFinish = this.SendQuery(new Query_ConditionState(HK_ConditionType.C1_1到电梯门口));
            Debug.Log("Condition_C1_1到电梯门口 是否完成:" + isConditionFinish);
        }
        if(Input.GetKeyDown(KeyCode.Backspace))
        {
            this.SendCommand<CMD_ImmediateFinishTaskList>();
        }
    }
}

7. HK_SimpleDialogSystem(基于 QFramework 架构):

功能描述:

  • 简易对话系统(通过CSV配置文件对话进行配置及编辑);
  • 在Excel中对对话流程进行编辑,编辑后另存为CSV文件,放在Resource文件夹下;
  • 需确保CSV文件为UTF-8编码格式;
  • 目前支持3D的对话UI,主要为适配VR开发;

使用方式:

  • 在本项目的 Architecture 中注册 IHK_SimpleDialogSystem;
  • 使用Command指令来使用HK_SimpleDialogSystem,三个指令分别为:
    CMD_StartNewDialog3D :开启新的3D对话指令
    CMD_EndCurDialog3D : 停止当前的3D对话指令
    CMD_PlayForwardDialog :继续推进对话指令
  • 外部可监听事件:
    Event_DialogStart // 对话开始 事件
    Event_DialogEnd // 对话结束 事件
    Event_OptionChoiced // 选项做出选择 事件

外部依赖:

  • Dotween

8. HK_Tips(基于 QFramework 架构):

功能描述:

  • 本工具是三维场景中,进行悬浮提示标签的便捷工具;
  • 可在场景中快速摆放编辑,运行时可通过点击的方式进行事件响应;

使用方式:

  • 在当前项目的 Architecture 中注册 IHK_SimpleTaskSystem;
public class XXX_Architecture : Architecture<XXX_Architecture>
{
    protected override void Init()
    {
        this.RegisterSystem<IHK_TipSystem>(new HK_TipSystem());
    }
}
  • 在场景中摆放Prefabs文件夹下的 HK_Tip 预设体,并进行编辑;
  • 运行时可点击 HK_Tip 标签,会自动发送点击事件 Event_HKTipClick;
  • 使用Command指令来进行整体控制:
    CMD_HideAllHKTips : 控制所有 HKTip 隐藏
    CMD_ShowAllHKTips : 控制所有 HKTip 显示
    CMD_SetAllHKTipActiveState : 控制所有 HKTip 激活状态
// 显示所有的 HKTip
this.SendCommand<CMD_ShowAllHKTips>();

// 隐藏所有的 HKTip
this.SendCommand<CMD_HideAllHKTips>();

// 禁用所有的 HKTip
this.SendCommand(new CMD_SetAllHKTipActiveState(false));

// 激活所有的 HKTip
this.SendCommand(new CMD_SetAllHKTipActiveState(true));
  • 外部可监听事件:
    Event_HKTipClick : HKTip点击事件
this.RegisterEvent<Event_HKTipClick>(args =>
{
    Debug.Log("点击的Tip名称为:" + args._tipName);
    Debug.Log("点击的Tip类型为:" + args._tipType);
}).UnRegisterWhenGameObjectDestroyed(gameObject);

外部依赖:

  • Dotween

9. HK_DebugTool:

功能描述:

HKDebug 工具通过对 Unity 内置 Debug 功能的扩展和封装,旨在提供更灵活、强大且高效的日志管理解决方案。通过使用 HKDebug,可以轻松控制和优化日志输出,提升调试效率和代码可维护性。以下是HKDebug的主要功能:

  • 日志颜色设置: 支持设置日志字体颜色,包括白色、红色、黄色、绿色、蓝色和青色。通过不同颜色区分日志类型,增强日志的可读性和辨识度。
  • 日志样式设置: 允许设置日志字体样式,包括普通、粗体、斜体和粗体斜体。通过样式的变化,进一步区分日志的重要性和类别,提升日志的视觉效果。
  • 日志类型:
    • 普通日志:使用 HKDebug.Log 方法输出普通日志,适用于一般的调试信息。
    • 警告日志:使用 HKDebug.LogWarning 方法输出警告日志,默认采用黄色粗体显示,提示潜在的问题。
    • 错误日志:使用 HKDebug.LogError 方法输出错误日志,默认采用红色粗体显示,标识严重的错误信息。
  • 日志时间戳: 根据配置是否启用该功能,若启用,则日志消息会自动附加当前时间戳(精确到毫秒),便于日志的时间追踪和问题排查。
  • 日志保存: (仅在Editor及Windows下可用)根据配置是否启用该功能,若启用,将自动日志信息保存到本地文件,默认保存路径为项目目录下的 HKLog 文件夹。每次启动项目时将创建一个新的日志文件,便于管理和分析历史日志。

使用方式:

  • 普通日志输出: HKDebug.Log 方法用于输出普通的日志消息,替代 Unity 原生的 Debug.Log 方法。支持指定日志的颜色和样式,提升信息的可读性。
  HKDebug.Log("这是默认白色普通日志");
  HKDebug.Log("这是黄色普通日志", LogColor.Yellow);
  HKDebug.Log("这是绿色粗斜体日志", LogColor.Green, LogStyle.BoldAndItalic);
  HKDebug.Log("这是蓝色粗体日志", LogColor.Blue, LogStyle.Bold);
  HKDebug.Log("这是青色普通日志", LogColor.Cyan);
  HKDebug.Log("这是红色普通日志",LogColor.Red);
  • 警告日志输出: HKDebug.LogWarning 方法用于输出警告日志消息,替代 Unity 原生的 Debug.LogWarning 方法。默认采用黄色粗体显示,便于快速识别潜在问题。
  HKDebug.LogWarning("这是一个警告日志");
  • 错误日志输出: HKDebug.LogError 方法用于输出错误日志消息,替代 Unity 原生的 Debug.LogError 方法。默认采用红色粗体显示,标识严重的错误信息。
  HKDebug.LogError("这是一个错误日志"); 

Image text

  • HKDebug配置:
    • 点击 HKTools/HKDebugSettings,打开 HKDebug 配置窗口,在该窗口中可对 HKDebug 进行设置。
    • 是否显示时间戳(默认关闭):通过 IsDebugTime 参数,设置打印日志时,是否包含时间信息。
    • 是否日志保存(默认关闭,仅支持Editor及Windows):通过 IsSave 及 IsSaveNormalLog 参数,设置是否启用日志保存功能及选择是否保存普通日志,需注意日志保存仅在 Editor 及 发布Windows时可用,若启用日志保存,则日志文件将自动保存在项目目录下的 HKLog 文件夹中,每次启动项目时,将生成一个新的日志文件,文件名包含启动时间,便于分类和管理,日志文件中不仅包含日志消息,还记录了系统和设备的详细信息,辅助后期调试。

Image text


10. HK_Video:

功能描述:

  • 在UGUI的视频播放的功能模块,对VideoPlayer进行了封装。

使用方式:

  • 包含完整版播放器 HK_VideoPanel 和 简易版播放器 HK_SimpleVideoPanel 两种。
  • 将 HK_VideoPanel 或 HK_SimpleVideoPanel 预设体拖拽入当前场景中进行使用(放置在Canvas下)。
  • 通过获取 HK_VideoPanel 或 HK_SimpleVideoPanel 脚本进行使用。
  • 调用对应脚本的 PlayAssignedVideoA() 方法,传入视频的URL或VideoClip进行播放。

外部依赖:


11. HK_SerialPortSystem(基于 QFramework 架构):

功能描述:

  • 串口通信管理系统层;
  • 可通过配置文件 HK_SerialConfig.json 在外部进行配置;
  • 本系统层工具使用时,Unity项目工程的 Api Compatibility Level 必须为.Net Framework;
  • 本系统层工具仅可应用于 Windows PC端;

使用方式:

  • 确认当前Unity项目工程的 Api Compatibility Level 选择了 .Net Framework,位置如下图:

Image text

  • 确认 StreamingAssets 文件夹下是否有 HK_SerialConfig.json 配置文件,可通过自动化工具生成该配置文件,或进行配置文件重置;

Image text

  • 修改 StreamingAssets/HK_SerialConfig.json 配置文件,调整串口配置;
    {
        "PortName": "COM3",
        "BaudRate": 9600,
        "Parity": "None",
        "DataBits": 8,
        "StopBits": "None"
    }
  • 在当前项目的 Architecture 中注册 IHK_SerialPortSystem;
    public class XXX_Architecture : Architecture<XXX_Architecture>
    {
        protected override void Init()
        {
            this.RegisterSystem<IHK_SerialPortSystem>(new HK_SerialPortSystem());
        }
    }
  • 通过调用 InitSerialPort 方法,并传入串口通信指令长度参数,进行初始化;
    this.GetSystem<IHK_SerialPortSystem>().InitSerialPort(6);
  • 通过调用 OpenSerialPort 方法,开启串口;
    this.GetSystem<IHK_SerialPortSystem>().OpenSerialPort();
  • 通过调用 CloseSerialPort 方法,关闭当前串口;
    this.GetSystem<IHK_SerialPortSystem>().CloseSerialPort();
  • 注册 Event_ReceiveSerialPortData 事件,接口串口通信数据;
    this.RegisterEvent<Event_ReceiveSerialPortData>(args =>
    {
        Debug.Log("接收到串口数据: " + args._serialPortData);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);

外部依赖:

  • ActionKit

12. HK_UGUITools:

HK_UIFramework(基于 QFramework 架构)

功能描述:

本UI框架旨在管理各种UI面板的打开、关闭及其层级、排序关系,本框架提供了一套机制,使得开发者可以方便地操控UI元素,确保界面层级按照预期显示,并且不同面板类型(全局面板和层级面板)能够和谐共存。

全局面板(Global Panel):

  • 全局性面板,通常涵盖应用的全局功能,例如顶部栏、全局设置窗口、确认窗口等。
  • 全局面板通常具有较高的显示优先级顺序 (Order 属性)。

层级面板(Hierarchy Panel):

  • 层级面板,通常覆盖整个应用界面,由栈来进行管理,例如软件的各层级页面等。
  • 层级面板以栈的形式管理,栈顶的面板总是当前活动面板。
  • 打开新的层级面板时,当前活动的层级面板会被暂停,新的面板成为活动面板。
  • 关闭栈顶层级面板时,之前被暂停的面板将重新变为活动状态。

使用方式:

  • 在当前项目的 Architecture 中注册 IHK_UISystem
public class XXX_Architecture : Architecture<XXX_Architecture>
{
    protected override void Init()
    {
        this.RegisterSystem<IHK_UISystem>(new HK_UISystem());
    }
}
  • 将UI_Root预设体拖入场景中,在ForDesign节点下编辑各个面板,并添加控制脚本(需继承HK_BasePanel)。
  • 编辑后的脚本作为预设体,存放在Project某目录下。
  • 若预设体实例发生修改,在Hierarchy中会显示“更新”按钮。

Image text

  • 编辑 HK_UIConfig,对各面板进行参数配置。

Image text

  • 可在 全局面板 及 层级面板 下设计子页面(子页面脚本需继承 HK_ChildPanelBase),并对子页面进行生命周期方法的同步管理。

Image text

HK_CollapsibleMenu(基于 QFramework 架构)

  • 折叠菜单UI预设,可直接推拽至Canvas下进行适用。
  • 通过改1、2、3级MenuItem的预设体,适配不同的UI。
  • MenuItem按钮点击后发送指令。

HK_UIOverride

  • 重写的UGUI Button组件:
    通过在Inspector面板中修改AudioType,播放对应的Button点击音效(需注册对应的音效播放事件)。
    通过在Inspector面板中修改AnimType,启用相应的Button动效(使用Dotween,可自行在脚本中修改)。
  • 重写的UGUI Toggle组件:
    通过在Inspector面板中修改AudioType播放对应的Toggle点击音效(需注册对应的音效播放事件)。
  • 重写的UGUI Dropdown组件:
    通过在Inspector面板中修改AudioPressType和AudioSelectType,播放对应的点击及选中音效(需注册对应的音效播放事件)。

HK_SlidePage2D

  • 2D轮播图工具,支持循环和往返两种切换模式。功能包含:
    • 自动轮播与手动拖动切换
    • 页码按钮联动
    • 左右切换按钮控制
    • 平滑动画过渡(基于DOTween)

HK_SlidePage3D

  • 3D轮播图工具,支持自适应屏幕布局与深度视觉差。功能包含:
    • 自动旋转与手动控制切换
    • 子物体深度排序与层级管理
    • 透视缩放及透明度渐变效果
    • 平滑旋转动画(基于DOTween)

HK_Curve2D

  • 自定义的UI组件,用于在UGUI中绘制2D曲线,并可控制曲线默认显示状态,以及沿不同方向生长出现。
  • HK_Curve2DCtrl中的SetCurveInitState(bool isShow)方法:设置曲线的默认显示状态。
  • HK_Curve2DCtrl中的PlayGrowAnim(CurveGrowAnimType animType)方法:调用曲线的生长动画(根据动画类型)。
  • 曲线的形状、纹理、颜色等编辑在 HK_Curve2D 脚本中。

HK_UIFramesSequence

  • 提供两个脚本工具进行序列帧播放:HK_SimpleFrameSequence、HK_FrameSequence。
  • HK_SimpleFrameSequence:简易的序列帧动画脚本工具,主要功能如下:
    • 支持UI Image和SpriteRenderer两种渲染组件。
    • 核心功能是通过帧数组驱动动画,支持自动/手动播放、循环模式切换和精确帧率控制。
    • 组件会自动检测渲染器类型,要求目标对象必须包含Image或SpriteRenderer组件。
    • 在Inspector中配置序列帧数组后,可通过勾选自动播放立即启动动画,或通过代码调用StartFramesAnim/StopFramesAnim控制播放。
    • 非循环模式播放完成后会停留在最后一帧,循环模式使用取模运算优化保证流畅性。
  • HK_FrameSequence:进阶版的序列帧动画脚本工具控制器,主要功能如下:
    • 支持三段式动画流程(初始动画→循环动画→结束动画)。
    • 提供循环间隔暂停功能,内置动画状态机自动处理阶段转换。
    • 必须包含循环序列帧,初始序列帧及结束序列帧为可选。
    • 自动播放时优先播放初始动画,停止时会触发结束动画(若存在)。
    • 循环阶段支持设置停顿间隔,采用协程实现精准计时。
    • 当同时存在初始和循环动画时,会自动衔接播放,适用于需要完整入场-展示-退场流程的复杂序列帧动画需求。

HK_CircularSlider

  • 基于 Unity 的自定义圆形滑块工具脚本,用于在游戏或应用中创建圆形滑块控件。
  • 该控件允许用户通过拖动来选择一个介于 0 到 1 之间的值,并且可以根据用户的设置进行顺时针或逆时针滑动。

13. HK_TcpCommunicateSystem(基于 QFramework 架构):

功能描述: 本系统层是一个Unity的网络通信系统(不支持WebGL),包含了Server端和Client端两个部分,使用 TCP 协议实现客户端和服务器之间的消息传递。该系统通过 QFramework 框架进行管理,提供了服务器端和客户端的启动、关闭及消息发送等功能。以下是系统的主要功能: 主要特性如下:

  • 多客户端支持:服务器端可以同时处理多个客户端连接。
  • 线程管理:使用多线程和 CancellationTokenSource 管理服务器和客户端的生命周期,确保资源的正确释放。
  • Server端功能:
    • 启动Server:监听指定端口,等待客户端连接。
    • 关闭Server:通知所有客户端即将断开连接,并关闭所有客户端连接。
    • 发送消息给所有客户端:向所有已连接的客户端发送消息。
    • 发送消息给指定客户端:通过IP和端口号或Socket向指定客户端发送消息。
    • 设置Debug状态:控制是否在控制台输出Debug信息。
  • Client端功能:
    • 启动Client:连接到指定的服务器IP和端口。
    • 关闭Client:通知服务器即将断开连接,并关闭客户端连接。
    • 发送消息给服务器:向服务器发送消息。
    • 设置Debug状态:控制是否在控制台输出Debug信息。
  • 事件和指令:通过 QFramework 的事件和指令,使用该系统层,并将接收到的消息传递到主线程,方便在 Unity 环境中进行处理。

使用方式:

  • 在本项目的 Architecture 中注册 Server端或Client端的系统层;

    public class XXX_Architecture : Architecture<XXX_Architecture>
    {
        protected override void Init()
        {
            // 注册 Client端系统层
            this.RegisterSystem<IHK_TcpClientSystem>(new HK_TcpClientSystem());
            // 注册 Server端系统层
            this.RegisterSystem<IHK_TcpServerSystem>(new HK_TcpServerSystem());
        }
    }
    
  • 通过指令开启 Server端;

    // 作为 Server端,开启
    this.SendCommand(new CMD_StartAsServer());
    
  • 通过指令给Client端发送消息;

    // 作为 Server端,给 所有的Client端 发送指令
    this.SendCommand(new CMD_SendMsg_ServerToAllClients("Hello Client"));
    
  • Server端订阅事件;

    // 当 Client端 连接时
    this.RegisterEvent<Event_ClientConnect>(args =>
    {
        HKDebug.Log($"Event:Client端 {args._address}:{args._port} 加入", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
    // 当 Client端 断开连接时
    this.RegisterEvent<Event_ClientDisConnect>(args =>
    {
        HKDebug.Log($"Event:Client端 {args._address}:{args._port} 退出", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
    // 作为 Server端,接收 Client端 发送的消息
    this.RegisterEvent<Event_FromClientMsg>(args =>
    {
        HKDebug.Log($"Event:Client端 {args._address}:{args._port} 发送消息 {args._msg}", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
  • 通过指令关闭 Server端;

    // 关闭 Server端
    this.SendCommand(new CMD_CloseServer());
    
  • 通过指令开启 Client端;

    // 作为 Client端,开启,并传入 Server端的Ip及端口号
    this.SendCommand(new CMD_StartAsClient("192.168.0.135", 8080));
    
  • 通过指令给Server端发送消息;

    // 作为 Client端,给 Server端发送指令
    this.SendCommand(new CMD_SendMsg_ClientToServer("Hello Server"));
    
  • Client端订阅事件;

    this.RegisterEvent<Event_ConnectToServer>(args =>
    {
        HKDebug.Log($"Event:连接入Server端", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
    this.RegisterEvent<Event_DisconnectToServer>(args =>
    {
        HKDebug.Log($"Event:与Server端断开连接", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
    this.RegisterEvent<Event_FromServerMsg>(args =>
    {
        HKDebug.Log($"Event:Server端 发送消息 {args._msg}", LogColor.Green);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
  • 通过指令关闭 Client端;

    // 关闭 Client端
    this.SendCommand(new CMD_CloseClient());
    

外部依赖:


14. HK_UdpCommunicateSystem(基于 QFramework 架构):

功能描述:

本工具是一个为Unity设计的UDP通信工具。提供了通过指令和事件,来进行发送、接收和广播UDP消息。该工具适用于需要实时通信的应用程序,例如多人VR或展厅多端通信应用。

主要功能及特性如下:

  • 启动和关闭UDP通信:
    • 启动 UDP 通信,并在指定的本地端口上监听。启动后,系统进入接收消息的状态。
    • 关闭 UDP 通信,释放相关资源。
  • 发送消息:向特定的远程端点发送消息。
  • 广播消息:在指定的端口上广播消息,无需确认。
  • 广播Ack消息:广播需要确认的消息,使用 ACK 机制确保消息成功发送。若收到确认,执行回调函数。
  • Ack消息机制:
    • 支持 ACK 和 RACK 消息处理,确保消息的可靠传输。ACK 消息在接收时会被识别并确认,RACK 消息用于确认 ACK 消息的接收。
    • 初始化需要关注的 ACK 消息列表,确保特定消息的确认。
  • 多线程支持:
    • 使用 多线程 处理消息的接收和 ACK 消息的重试机制,确保在后台线程中执行不阻塞主线程。
    • 使用 SynchronizationContext 确保在主线程中触发事件,适合 Unity 的单线程模型。

使用方式:

  • 在本项目的 Architecture 中注册 IHK_UdpSystem 系统层;

    public class XXX_Architecture : Architecture<XXX_Architecture>
    {
        protected override void Init()
        {
            this.RegisterSystem<IHK_UdpSystem>(new HK_UdpSystem());
        }
    }
    
  • 通过指令开启 UDP通信;

    // 传入端口号,开启UDP通信
    this.SendCommand(new CMD_UDP_Start(7878));
    
  • 通过指令初始化,需订阅的Ack消息;

    // 通过 List<string> 初始化本机订阅的Ack消息
    this.SendCommand(new CMD_UDP_InitAckList(new List<string>() { "模式1","模式2"}));
    
  • 通过指令广播消息;

    // 给本网段下所有主机的8787端口广播消息
    this.SendCommand(new CMD_UDP_BroadcastMsg("模式3", 8787));
    
  • 通过指令广播Ack消息,并传入消息发送成功的回调事件;

    // 给本网段下所有主机的8787端口广播消息
    this.SendCommand(new CMD_UDP_BroadcastAckMsg("模式2", 8787, () => HKDebug.Log("确认发送成功!")));
    
  • 订阅消息接收事件;

    // 订阅 广播消息 事件
    this.RegisterEvent<Event_UDP_ReceiveMsg>(args =>
    {
        HKDebug.Log("接收到UDP广播消息:" + args._msg);
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
    // 订阅 Ack广播消息 事件
    this.RegisterEvent<Event_UDP_ReceiveAckMsg>(args =>
    {
        if (args._ackMsg == "模式2")
        {
            HKDebug.Log("接收到 UDP 广播Ack消息:" + args._ackMsg);
        }
    }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
  • 通过指令关闭 UDP通信;

    // 关闭 Client端
    this.SendCommand(new CMD_UDP_Close());
    

外部依赖:


15. HK_SimpleQuiz:

  • (引入了QF框架)简单的考题功能,目前包含了:单选题、多选题、判断题,可通过Json或Excel文件对题库进行配置其中通过Excel配置的方式只支持PC端。

16. HK_FPSSystem(基于 QFramework 架构):

功能描述:

本工具是一个 FPS(每秒帧数)监控系统,可用于实时监测和优化 Unity 应用程序的性能。其主要功能包括:

  • 实时显示 FPS:在游戏或应用界面上显示当前的帧率,直观了解应用的运行表现。
  • 控制 FPS 显示:提供方法来显示或隐藏 FPS 监控,便于在开发过程中进行调试和性能分析。
  • 设置目标帧率:可设置应用程序的目标帧率,以实现性能优化和稳定性提升。

通过上述功能,能够辅助在不同设备和场景下监控和优化应用性能,确保获得流畅的体验。

使用方式:

  • 在本项目的 Architecture 中注册 HK_FPSSystem系统层;

    public class XXX_Architecture : Architecture<XXX_Architecture>
    {
        protected override void Init()
        {
            // 注册 Client端系统层
            this.RegisterSystem<IHK_FPSSystem>(new HK_FPSSystem());
        }
    }
    
  • 通过 CMD_ShowFPSDisplay() 指令,在应用界面上激活显示 FPS;

    this.SendCommand(new CMD_ShowFPSDisplay());
    
  • 通过 CMD_HideFPSDisplay() 指令,在应用界面上隐藏 FPS;

    this.SendCommand(new CMD_HideFPSDisplay());
    
  • 通过 CMD_SetTargetFrameRate() 指令,设置目标刷新率;

    // 关闭 垂直同步,将目标刷新率设置为 60
    if (Input.GetKeyDown(KeyCode.F3))
    {
        this.SendCommand(new CMD_SetTargetFrameRate(60, false));
    }
    
    // 开启 垂直同步,不限制目标刷新率
    if (Input.GetKeyDown(KeyCode.F4))
    {
        this.SendCommand(new CMD_SetTargetFrameRate(-1, true));
    }
    
  • 具体用法,可参考 Test_FPSSystem 脚本。

    public class Test_FPSSystem : MonoBehaviour, IController
    {
        public IArchitecture GetArchitecture()
        {
            return HK_ArchitectureProvider.Architecture;
        }
    
        void Update()
        {
            // 显示 当前刷新率
            if (Input.GetKeyDown(KeyCode.F1))
            {
                this.SendCommand(new CMD_ShowFPSDisplay());
            }
    
            // 隐藏 当前刷新率
            if (Input.GetKeyDown(KeyCode.F2))
            {
                this.SendCommand(new CMD_HideFPSDisplay());
            }
    
            // 关闭 垂直同步,将目标刷新率设置为 60
            if (Input.GetKeyDown(KeyCode.F3))
            {
                this.SendCommand(new CMD_SetTargetFrameRate(60, false));
            }
    
            // 开启 垂直同步,不限制目标刷新率
            if (Input.GetKeyDown(KeyCode.F4))
            {
                this.SendCommand(new CMD_SetTargetFrameRate(-1, true));
            }
        }
    }
    

外部依赖:


17. HK_StopwatchSystem(基于 QFramework 架构):

功能描述:

HK_StopwatchSystem 是一个多功能倒计时管理系统,为开发者提供精确的时序控制能力,主要功能如下:

  • 通过可配置的倒计时实例,支持灵活的开始、暂停、恢复、重启等操作,满足复杂的时间管理需求。
  • 采用数据绑定机制实时反馈剩余时间,并通过事件驱动架构实现状态变更的自动化通知。

使用方式:

  • 在本项目的 Architecture 中注册 HK_FPSSystem系统层;

    public class XXX_Architecture : Architecture<XXX_Architecture>
    {
        protected override void Init()
        {
            // 注册 Client端系统层
            this.RegisterSystem<IHK_StopwatchSystem>(new HK_StopwatchSystem());
        }
    }
    
  • 通过系统层实例化一个Stopwatch实例,传入时间、回调方法等参数,进行初始化;

    // 创建30秒倒计时
    stopwatch = this.GetSystem<IHK_StopwatchSystem>().CreateStopwatch(30, () =>
    {
        HKDebug.Log("倒计时结束");
    });
    
  • 可注册Stopwatch实例的 RemainingTime 响应式属性进行使用;

    // 绑定剩余时间显示(带初始值注册)
        stopwatch.RemainingTime.RegisterWithInitValue((value) =>
        {
            txt_RemainingTime.text = $"剩余时间:{value:F1}秒";
        }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
  • 可通过Stopwatch实例的 Start、Pause、Resume、Restart、Stop 方法,进行倒计时的控制;

    btn_Start.onClick.AddListener(() =>
    {
        stopwatch?.Start();
    });
    
    btn_Pause.onClick.AddListener(() =>
    {
        stopwatch?.Pause();
    });
    
    btn_Resume.onClick.AddListener(() =>
    {
        stopwatch?.Resume();
    });
    
    btn_Restart.onClick.AddListener(() =>
    {
        stopwatch?.Restart();
    });
    
    btn_Stop.onClick.AddListener(() =>
    {
        stopwatch?.Stop();
    });
    
  • 具体用法,可参考 Test_Stopwatch 脚本。

      public class Test_Stopwatch : MonoBehaviour, IController
      {
          public IArchitecture GetArchitecture()
          {
              return HK_ArchitectureProvider.Architecture;
          }
    
          [Header("UI Controls")]
          [SerializeField] Button btn_CreateStopwatch; // 创建新计时器
          [SerializeField] Button btn_Start;          // 开始计时
          [SerializeField] Button btn_Pause;          // 暂停计时
          [SerializeField] Button btn_Resume;         // 恢复计时
          [SerializeField] Button btn_Stop;           // 停止并重置
          [SerializeField] Button btn_Restart;        // 重新开始
    
          [Header("Display")]
          [SerializeField] Text txt_RemainingTime;    // 剩余时间显示文本
    
          // 当前活动的倒计时实例
          HK_Stopwatch stopwatch;
    
          void Awake()
          {
              // 初始化按钮交互逻辑
              btn_CreateStopwatch.onClick.AddListener(() =>
              {
                  // 创建新实例前清理旧计时器
                  stopwatch?.Stop();
                  stopwatch = null;
    
                  // 创建30秒倒计时(测试用例)
                  stopwatch = this.GetSystem<IHK_StopwatchSystem>().CreateStopwatch(30, () =>
                  {
                      HKDebug.Log("倒计时结束");
                  });
    
                  // 绑定剩余时间显示(带初始值注册)
                  stopwatch.RemainingTime.RegisterWithInitValue((value) =>
                  {
                      txt_RemainingTime.text = $"剩余时间:{value:F1}秒";
                  }).UnRegisterWhenGameObjectDestroyed(gameObject);
              });
    
              btn_Start.onClick.AddListener(() =>
              {
                  stopwatch?.Start();
              });
    
              btn_Pause.onClick.AddListener(() =>
              {
                  stopwatch?.Pause();
              });
    
              btn_Resume.onClick.AddListener(() =>
              {
                  stopwatch?.Resume();
              });
    
              btn_Restart.onClick.AddListener(() =>
              {
                  stopwatch?.Restart();
              });
    
              btn_Stop.onClick.AddListener(() =>
              {
                  stopwatch?.Stop();
              });
          }
      }
    

外部依赖:

  • ActionKit

18. HK_NetworkSystem(基于 QFramework 架构):

  • 对Unity的Nedecode进行封装,提供便捷的使用方式
  • 需确保在Package Manager中,已导入Netcode for GameObjects 包
  • 再将 HK_NetworkSystem 包导入本工程中进行使用

19. HK_SplitAnim:

  • 模型拆分动画控制功能,可在Scene视窗中对模型动画目标位置进行设置,方便进行管理。

20. HK_FileLoad:

  • (引入了QF框架,该模块仅可用于PC端)从电脑中读取图片、视频,并存储在StreamingAssets中。

21. HK_LoginRegister:

  • (引入了QF框架)用户注册登录功能模块,Server端是NodeJs的,客户端为Unity。

复用工具:

1. HKUtility(非Mono单例工具类):

1.1 IsClickUI:

  • 判断是否点击到UI上了,如果点在 UI 则返回 true,如果没点击到 UI 返回false。
    void OnMouseDown()
    {
        // 判断是否点击到UI,如果点击的是UI则返回
        if (HKUtility.Instance.IsClickUI())
            return;

        Debug.Log("点击到了GameObject");
    }

1.2 IsInTheFront:

  • 判断 物体B 是否在 物体A的前方,如果在前方,返回 true,如果在后方,返回 false

1.3 IsOnTheRight:

  • 判断 物体B 是否在 物体A的右边,如果在右边,返回 true,如果在左边,返回 false

2. HKMonoUtility(Mono单例工具类):

2.1 GetJsonFromStreamingAssets:

  • 从 StreamingAssets 中获取Json文件并解析,通过callback返回
    HKMonoUtility.Instance.GetJsonFromStreamingAssets<JsonData>("JsonDatas/TestData", jsonData =>
    {
        Debug.Log(jsonData.Name);
    });

2.2 GetJsonFromURL:

  • 从 URL 中获取Json文件并解析,通过callback返回

2.3 GetSpriteFromStreamingAssets

  • 从 StreamingAssets 中加载Sprite,通过callback返回
    HKMonoUtility.Instance.GetSpriteFromStreamingAssets("Image/Texture.png", sprite =>
    {
        GetComponent<Image>().sprite = sprite;
    });

编辑器功能:

1.1 HK_SmartCopy:

本工具模仿 Maya 中的智能复制功能,用于智能复制选中的游戏对象。通过新增位置、旋转和缩放的偏移量,允许用户快速创建连续的、增量复制的游戏对象。这一功能类似于Maya中的复制功能,使得一些排列和布局任务变得更加高效,使用方式如下:

  • Ctrl+Shift+D 进行复制操作,只能且必须选中一个物体
  • 对复制的物体进行位移、旋转、缩放调整操作。
  • 再次按 Ctrl+Shift+D 时,会根据记录的偏移量进行连续复制。
  • 如果当前选择的物体发生变动或者用户选择了不同的物体,工具会自动重启复制过程。
  • 工具操作及效果示意如下图所示:

Image text


1.2 HK_MakeGroup:

本工具模仿 Maya 中的打组功能,用于将选中的多个 Unity 游戏对象(GameObjects)打组操作。生成一个新的父对象,将所有选中的对象作为该新父对象的子对象,并将新父对象在层次视图中位置与第一个选中物体保持一致。使用方式如下:

  • 选择物体: 在层级(Hierarchy)窗口中,选中需要打组的多个物体(GameObjects)。
  • 执行打组操作:在 HKTools 菜单下,选择 MakeGroup(打组工具),或按下快捷键 Ctrl + GCmd + G
  • 查看结果: 此时会创建一个名为 Parent_Go 的新父对象,并按照预期层次结构和位置将选中的对象作为其子对象,如下图所示:

Image text


1.3 HK_ShortCutsExtension

  • Unity中部分MenuItem的快捷键拓展。

2.1 HK_TodoList(代办事项清单工具)

本工具提供了在Unity中进行代办事项清单管理的功能,使用方法如下:

  • 添加 Todo 注释:在编写代码时,可以在需要标记为待办事项的行添加注释,工具会自动识别这些注释并将其记录为 Todo 条目,默认支持的注释前缀如下:
    • //TODO
    • //Todo
    • //todo
    • // TODO
    • // Todo
    • // todo
  • 存储 Todo 条目:识别出的 Todo 条目将自动存储在 HKTodoList 中,方便集中管理和查看。
  • 全局刷新:点击 “全局刷新” 按钮,工具会遍历整个 Unity 工程中的所有脚本文件,识别并更新所有 Todo 条目。
  • 快捷跳转:在 HKTodoList 中点击 “打开脚本” 按钮,可以快速打开包含该 Todo 条目的代码脚本,并自动跳转到对应的行数,方便快速定位和处理。
  • 关键词自定义:可以修改 HK_TodoConstants 脚本中的 TodoKeyWords 和 SkipKeyWords,来自定义 Todo 条目识别的注释关键字,以及需要过滤的路径关键字,如下图所示:

Image text

  • 工具界面如下图所示:

Image text


2.2 HK_ResetName(重命名工具):

本工具提供了两大主要功能:替换选中物体名称中的特定字符串 和 对选中物体进行重命名。
该工具使得开发者可以更高效地管理游戏对象的命名,提高项目的组织和维护便利性。

  • 替换功能: 查找选中物体名称中的特定字符串,并将其替换为新的字符串。适用于需要对名称进行部分修改的场景。
  • 重命名功能: 对选中物体进行批量重命名,并按照用户设定的起始编号进行命名排序。适用于需要对大量对象进行统一命名的场景。

使用方式如下:

  • 选择目标物体: 在Unity编辑器的Hierarchy窗口中,选择需要操作的物体;
  • 选择操作模式: 在工具界面中,从“Replace”和“Rename”两种模式中进行选择;
    • Replace 模式:输入待查找的字符串和替换的字符串,工具将扫描所有选中物体的名称,并将符合条件的部分替换为新字符串。
    • Rename 模式:输入新的名称和起始编号,工具将对选中物体进行重命名,并按编号顺序进行排序。
  • Tips:如需将所有选中物体修改为统一命名,直接在Inspector界面的输入框中输入目标名称,将自动替换所有选中物体的名称为统一名称,无需使用本工具。
  • 工具界面如下图所示:

Image text Image text


2.3 HK_RandomRotOrScale(随机旋转缩放工具):

  • 对选中的物体进行随机旋转和缩放。

2.4 HK_DotweenEaseShow(Dotween动效预览工具):

  • (依赖Dotween)该工具可对Dotween内置Ease缓动动画进行预览,可查看所有缓动类型的动画曲线及相应预览动画。

2.5 HK_TagAndLayerView(标签与层级预览工具):

  • 场景中Tag和Layer的管理工具,对项目中所有的Tag标签及Layer层级进行显示,显示当前场景中对应Tag标签(或Layer层级)包含的物体数量,且可进行选择。

2.6 HK_TextureAndModelSetting(贴图、模型设置工具):

HK_TextureSetting:

  • 贴图批量化设置及压缩工具,可批处理图片的分辨率(调整为4的倍数),也可批量设置图片的压缩格式;
  • 目前只支持 Windows、WebGL、Android 目标平台);
  • 设置图片分辨率时,直接选择图片文件进行操作;
  • 设置压缩格式时,选择包含贴图的单一文件夹进行操作,工具只会压缩设置当前文件夹下的贴图;

HK_ModelImporter:

本工具用于自动处理FBX及OBJ模型文件的导入设置。自动化设置如下:

  • 当导入FBX或OBJ格式的模型文件时,该工具会自动激活并修改材质设置,将 Materials 的 Location 修改为 Use External Materials(Legacy),可简化材质管理流程。

HK_NormalMapImporter:

本工具用于在导入贴图时自动检测并设置法线贴图的 TextureType 为 Normal map。自动化设置如下:

  • 检查贴图文件名是否包含"_normal"、"_nrm"或"_n"等关键字。
  • 对贴图进行颜色特征采样,通过分析部分像素的颜色平均值,判断是否符合法线贴图的特征(R、G通道值接近0.5,B通道值接近1.0)。
  • 如果符合上述两个条件,则判定为法线贴图。

2.7 HK_HierarchySearch(查找物体工具):

  • 根据条件(名字、组件),对Hierarchy中选择的物体进行查询并重新选定。

2.8 HK_CreateGoByPath(基于路径创建工具):

本工具,可帮助用户在指定的路径上生成多个GameObject实例,并配置其位置偏移和旋转偏移。用户可以通过该工具快速在场景中布置物体,提高工作效率。使用方式如下:

  • 打开编辑窗口:打开Create Go By Path窗口:在Unity菜单栏中,选择HKTools -> CreateGoByPath,打开 HK_CreateGoByPath 窗口。
  • 生成路径:点击“生成 Path”按钮,在Scene视窗中生成路径。
  • 编辑路径:选择路径物体,在检查器窗口中的 HK_Path 组件中添加路径点(waypoints)。路径点可以直接在场景视图中通过拖动控制柄进行调整。

Image text

  • 重置坐标和路径点(可选操作):
    • 重置 Path 物体坐标轴:点击该按钮,将路径的位置设定到所有WayPoints的中心点。
    • 重置 Way Points 坐标:点击该按钮,重新对齐WayPoints到与路径对象的相对位置。
  • 配置参数:
    • 需生成的物体:选择一个要复制的模板GameObject或者Prefab。
    • 生成数量:设置要生成的物体数量。
    • 高度偏移:设置生成物体在Y轴的偏移量。
    • Y轴旋转偏移:设置生成物体的Y轴旋转。

Image text

  • 沿路径生成:确保在层次窗口中只选择具有 HK_Path 组件的路径对象,点击 “沿路径生成物体” 按钮,在路径上生成配置模板的实例对象
  • 删除生成的子物体:点击 “删除所有已生成物体” 按钮,将Path下所有已删除的物体进行删除操作。

3.1 HK_ReadOnly(Attribute):

  • 将脚本中的序列化变量,在Inspector面板中变为ReadOnly,只能看不能改。

3.2 HK_AutoSwitchToUTF8:

本工具是一个 Unity 编辑器扩展工具,旨在解决在 Unity 中导入或新建脚本时,因编码问题导致的中文字符乱码现象。
当在 Unity 中新建或导入脚本(例如 .cs 或 .csv 文件)时,若脚本的编码不是 UTF-8,可能会在 Inspector 面板预览或编辑脚本时出现中文乱码。为了自动解决这个问题,本工具会在资产导入过程中自动检测并转换脚本文件的编码。主要功能如下:

  • 自动检测新导入的脚本文件:当有新的资产导入到 Unity 中时,脚本会自动触发 OnPostprocessAllAssets 方法,对新导入的资产进行检测。
  • 筛选需要处理的文件:只对位于 Assets/ 目录下的 .cs 和 .csv 文件进行处理,确保不影响其他类型的资产。
  • 检测文件是否已处理:检测并转换过的脚本文件生成唯一标识符,并在 EditorPrefs 中记录已处理的文件,避免重复处理同一文件,提高效率。
  • 检测文件编码类型:根据文件的前两个字节判断文件的编码类型。如果文件的编码不是 UTF-8,则需要进行转换。
  • 转换文件编码为 UTF-8:非UTF-8的脚本,读取其文件的全部内容,使用原始编码解码,然后以 UTF-8 编码重新写入文件,确保文件的编码格式为 UTF-8。

Image text


3.3 HK_Foldup(Attribute):

  • 将脚本中的序列化变量,在Inspector面板中进行折叠收纳整理。

3.4 HK_Enum(Attribute):

  • 定制的可随机插入、删除的序列化的枚举类型。

4.1 HK_HierarchyPro:

HK_HierarchyPro 是一款用于增强Unity编辑器中Hierarchy(层级)面板显示功能的实用工具。通过该工具,开发者可以更直观地查看对象的状态、层级和组件信息,从而有效提高工作效率。该工具具备以下主要功能:

  • 显示Hierarchy列表的外边框及背景色:
    • 外边框绘制:在Hierarchy面板中为每个对象绘制外边框,清晰展示对象之间的层级关系。
    • 背景色区分:根据奇数行和偶数行绘制不同的背景色,增强视觉对比,方便快速浏览和定位。
  • Layer信息显示:
    • 在Hierarchy面板中显示每个对象所属的Layer层级名称(Default层级除外),方便开发者快速识别和管理对象的Layer设置。
    • 当Hierarchy面板宽度不足时,Layer信息会自动隐藏,保证界面整洁。
  • 激活状态切换:
    • 在Hierarchy面板中直接显示对象的激活状态切换按钮(即Active状态),无需展开Inspector面板即可快速启用或禁用对象。
  • 组件图标显示:
    • 在Hierarchy面板中显示特定组件的图标,如Canvas、Light、Camera、Collider等。通过图标直观了解对象包含的主要组件。
    • 在Hierarchy面板中显示自定义的MonoBehaviour组件图标,便于识别和管理自定义脚本组件。
    • 当显示组件数量较多时,可通过点击“•••”按钮分页查看更多组件图标。
  • 标记功能:
    • 通过快捷键Ctrl+M,对选中的对象进行标记或取消标记。
    • 被标记的对象会在Hierarchy面板中显示星型符号(★),方便开发者对关键对象进行临时标记和管理。
    • 注意事项:标记信息在场景关闭时会清空。

使用方式如下:

  • 在 HKTools/GlobalSettings...菜单中,可开启或关闭本工具,如下图所示。

Image text


4.2 HK_ProjectPro

HK_ProjectPro 用于在 Project 面板中为特定的文件夹显示自定义图标。这些文件夹包括但不限于脚本文件夹(Scripts)、预设体文件夹(Prefabs)、资源文件夹(Resources)等。该工具可以帮助开发者更直观地识别和管理项目中的不同类型文件夹,默认支持以下对应文件夹名称的图标显示(不区分大小写):

  • Scripts 文件夹:_Scripts, _Script, Scripts, Script
  • Prefabs 文件夹:_Prefabs, Prefabs, _Prefab, Prefab
  • Resources 文件夹:Resources
  • StreamingAssets 文件夹:Streamingassets
  • Scenes 文件夹:_Scenes, Scenes, _Scene, Scene
  • Materials 文件夹:Materials, Material, Mats, Mat, _Materials, _Material, _Mats, _Mat
  • UI 文件夹:UI, _UI, UIs, _UIs

使用方式如下:

  • 在 HKTools/Settings...菜单中,可开启或关闭本工具,如下图所示。

Image text


4.3 HK_InspectorPro

HK_InspectorPro 是一款用于增强Unity编辑器中 Inspector(监视器)面板显示功能的实用工具。主要功能如下:

  • 增强一 HK_CSharpInspector C#脚本预览增强:

    • 代码重新格式化:调整预览代码的词间距,使代码布局更加美观,便于开发者快速浏览和理解代码结构。
    • 行号显示:在代码左侧显示行号,方便开发者快速定位代码行,提升调试效率。
    • 字体优化:使用 Fira Code 等宽字体,提供更好的代码预览体验,确保字符间距一致,提升可读性。
    • 动态主题适配:根据Unity编辑器主题设定,分为浅色和深色主题,模仿 Visual Studio 的主题风格,对 C# 的关键字、常见类、常见结构体、自定义方法等进行颜色高亮,提升代码的可读性和可视化效果。
    • 动态主题自定义配置:在 HKTools/HK_InspectorProSettings/CSharpPreviewConfig 菜单中,可自定义关键词高亮的颜色,如下图所示:

    Image text

    • 增强前后对比如下图所示:

    Image text


4.4 HK_ScenePro

HK_ScenePro是一个用于增强 Unity 编辑器中 Scene 视图功能的工具。主要提供了类似于 Photoshop 中的标尺和参考线功能,方便开发者在 Scene 视图中进行UI或场景的精确布局和排版工作。主要功能如下:

  • 增强一 标尺及参考线功能:
    • 显示/隐藏标尺和参考线:使用快捷键 Ctrl + R 可以切换标尺和参考线的显示和隐藏状态。
    • 在 Scene 视图的顶部和左侧添加标尺,显示刻度,帮助您直观地了解场景中的位置和尺寸。
    • 参考线功能仅在 2D 模式或使用 正交摄像机 时可用。
    • 创建参考线:从标尺区域拖拽鼠标,可创建水平或垂直的参考线。
    • 移动参考线:拖动已有的参考线,可调整其位置。
    • 删除参考线:选中参考线后,按下 Delete 键即可删除。

Image text


5.1 HK_WebsiteCollection

  • Unity开发相关站点的集合。

MIT License Copyright (c) 2021 京产肠饭 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

Unity的工具集(基于QFramework和Dotween) 展开 收起
C# 等 3 种语言
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/JingChanChangFan/hk_-unity-tools.git
git@gitee.com:JingChanChangFan/hk_-unity-tools.git
JingChanChangFan
hk_-unity-tools
HKUnityTools
master

搜索帮助