Patrick-Kill / emo

一个基于 xasset & Xlua 的轻量客户端业务开发框架

Home Page:https://github.com/xasset/emo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

emo

emo是一个轻量的基于xasset和xLua的gameplay开发框架。借助它可以让你的业务开发或者benchmark节省不少时间。

功能概览

emo 目前主要为 Unity 项目提供了一个基础的 Lua 业务开发环境,主要提供了:

  • 基于 xasset 的资源管理环境,利用最新的BuildRule对预制件和lua脚本进行打包
  • 基于 xLua 的 lua 开发环境,并通过基于 xasset 的 LuaManager 接管了对应的 lua 文件加载机制
  • 基于 LuaPanda 的 lua 调试环境,在 VSCode 中调试 lua 代码非常方便
  • 基于 LuaProfiler的 lua 性能测试环境,可以直接在 Unity 的 Profiler 中分析 lua 代码的性能开销
  • 面向状态的 lua 业务开发框架,将游戏的生命周期抽象为其对应的 GameState,让程序业务更有条理
  • 在 lua 层提供了业务层同步编码,但底层提供异步资源加载的 View 组件,在减少同步可能导致的卡顿的同时,降低了业务编码难度

未来,emo 也会会逐步引入代码热更、网络通信、版本更新,序列化等机制,感兴趣的可以先期待下。

操作指南

启动运行

emo 把 Main 场景,作为程序入口。Main 场景是一个简单的初始场景,位于 Assets 目录,如下:

启动后,通过挂载在场景中游戏对象 Main 上的 Main.cs 让 LuaManager.cs 进行初始化。

初始化主要是给 Lua 环境设置自定义加载器,在常规编辑器环境下,底层是直接通过系统 IO 库读取文件的二进制,在真实的AB加载环境下,则通过 xasset 提供的接口获取目标文件的二进制。

初始化后,LuaManager 会载入 Main.lua,并通过 Main.cs 把 cs 这边的一些主要的事件转发到 Main.Lua,至此,cs 程序的生命周期就与 Lua 环境对接上了。

业务开发

emo 的业务开发以 Lua 为主,所有 Lua 代码放在 Assets 目录的 Lua 目录下。在 Lua 层,做业务开发的时候主要需要关注以下三个基础类型:

1.View

View 是游戏视图的抽象,主要对外提供了创建/关闭/刷新等接口。View 提供了同步编写业务代码,但又在底层进行异步资源加载的机制。目前,工程中主要实现了以下 View:

  • MessageBox 通用对话框 View,可以设置标题、文本,按钮名称事件等
  • LoadingView 带进度条的 View,用来展示读条状态

下面是 MessageBox 和 LoadingView 的使用范例:

local LoadingView = require 'Logic/Views/LoadingView'
local MessageBox = require 'Logic/Views/MessageBox'
-- ...
function M:OnEnter()
    self.loading = false   

    MessageBox.Show({
        title = 'Prepare to Loading',
        text = '2',
        ensureFunc = function()
            MessageBox.Close()
        end,
        cancelFunc = function()
            MessageBox.Close()
        end,
        closeFunc = function() 
            self.frames = 0
            self.loading = true
        end
    }) 
end

function M:Update()
    if self.loading then
        self.frames = self.frames + 1
        local progress = self.frames / maxframe
        LoadingView.SetProgress(progress, string.format('LOADING ... %.2f%%', progress * 100))
        if self.frames == maxframe then
            self.loading = false
        end
    end
end
-- ...

以上代码位于 Assets/Lua/Logic/States/Loading.lua.bytes , 运行效果如下图:

2.Action

Action 主要用来处理一些需要更新并有完成条件的业务。

Action 主要需要关注以下接口:

  • completed 完成后回调
  • updater 每帧调用如果完成返回 true,没完成返回false

对于一个延时调用的 Action 可以这样构造:

function WaitForSeconds(seconds, completed, updated)
    return Action.new(function(action)
        if updated then
            updated(action)
        end
        return action.elasped >= seconds
    end, completed)
end

3.GameState

GameState 描述了程序在某个时间应在做什么,是对游戏生命周期中某个时间的抽象表示。通常,游戏的生命周期可以抽象为多个 GameState,例如:初始化、读条、主界面、副本等。

目前,在 emo 中,主要实现了以下状态:

  • Initialize 系统初始化,UIRootView创建
  • Loading 读条,处理版本更新,预加载等

如果需要添加新的GameState,也请仿照上面的 GameState 来实现,实现一个具体的 GameState 主要需要关注以下接口:

  • OnEnter 进入这个状态该做什么
  • OnUpdate 停留在这个状态每帧要做什么
  • OnExit 退出这个状态该做什么

以 Initialize 为例,进入状态的时候,主要是把 UIRoot 创建出来,代码如下:

local M = class('Initialize', GameState)

function M:OnEnter()
    local view = View.new()
    view.onloaded = function(view) 
        Game.ChangeState(GameStateID.Loading)
    end
    view:Load(Res.prefab_uiroot)
end

function M:OnExit()
end

return M

上面的代码表示,当 UIRoot 加载出来后就切换当前游戏状态到 Loading 状态,状态切换的过程主要做了两件事:进入要切换的状态,和退出被切换的状态,代码如下:

function Game.ChangeState(newStateID)
    local stateName = GameStateNames[newStateID]
    local state = Game.states[newStateID]
    if not state then
        state = require("Logic/States/" .. stateName).new()
        Game.states[newStateID] = state 
    end
    local lastState = Game.state 
    if lastState then
        lastState:Exit()
    end
    Game.state = state 
    if state then
        state:Enter()
    end 
    print("[Game]ChangeState", stateName)
end

GameState 主要是为了让我们的程序结构变得更有条理也更好维护,对此如果还有疑惑,或许开头那句话句话会对你有帮助:“GameState 描述了程序在某个时间应在做什么,是对游戏生命周期中某个时间的抽象表示”

资源打包

基于 BuildRules 的资源打包策略

emo 使用的是 xasset 框架中最新的 BuildRule 来进行资源打包,主要对工程中的 Lua 和 Prefab 添加了对应的打包规则,如下图所示:

如果要添加新的规则,比较快捷的方式是,向上图中一样,在Project视图中选中目标文件夹,然后右键按需选择执行要应用的规则。

其它事项

请参考 :https://github.com/xasset/xasset

Lua 调试

请参考:https://github.com/Tencent/LuaPanda

Lua 性能测试

对于 Lua 的性能测试,emo 主要是集成了 tolua 的 LuaProfiler,可以直接在 Unity 的 Profiler 中查看 lua 的性能开销,Windows 和 Mac 都能用,感觉这样比较方便,运行效果如下:

下面的代码展示了如何在 Unity 的 Profiler 中开启对 lua 的性能开销分析

require('LuaPanda').start('127.0.0.1', 8818)
require('Init') 

local profiler

function AttachProfiler()
    print("[Main]AttachProfiler")
    if not profiler then
        profiler = require("Profiler")
        profiler:start()
    end
end

function DetachProfiler()
    print("[Main]DetachProfiler")
    if profiler then
        profiler:stop()
        profiler = nil
    end
end

function Main()
    AttachProfiler() -- 在 Unity 的 Profiler 中开启针对 lua 的性能开销分析
    Game.Init()
end

对于 Unity 项目的 lua 的性能开销分析,也还有一个对 Windows 开发用户比较好的工具,如果感兴趣,可以去看看这个:https://github.com/ElPsyCongree/LuaProfiler-For-Unity

更多框架

About

一个基于 xasset & Xlua 的轻量客户端业务开发框架

https://github.com/xasset/emo

License:MIT License


Languages

Language:C# 99.8%Language:C++ 0.2%Language:Shell 0.0%