Replace the blueprint with Lua, keep it in a consistent way with the blueprint, and switch seamlessly. Accessing UObject's properties and methods with reflection and without the need to generate glue code, more simple and easy to expand.
Android, iOS, Mac, Windows, Linux are supported now.
- lua : Lua is a powerful, efficient, lightweight, embeddable scripting language
- luasocket : Network support for the Lua language
- Tencent LuaPanda : Pandora Lua Debugger for VS Code
Clone Bluelua to your project's Plugins folder, regenerate project solution and build.
-
ILuaImplementableInterface
All C++ classes that can be used with LUA subclasses need to be inherited from this interface and the corresponding methods are called in the corresponding virtual functions, the main types of overrideing are as follows:
All C++ classes (or blueprint classes) need to override two important
BlueprintNativeEvent
:ShouldEnableLuaBinding
: should use lua subclass on this C++/Blueprint class.OnInitBindingLuaPath
: return corresponding lua file pathIt's optional to override
OnInitLuaState
: return custom FLuaState wrapper, default use of global lua state-
Class
AActor
, seeLuaImplementableActor.h
- Call
OnInitLuaBinding
inBeginPlay
- Call
OnReleaseLuaBinding
inEndPlay
- Call
OnProcessLuaOverrideEvent
inProcessEvent
- Call
-
Class
UUserWidget
, seeLuaImplementableWidget.h
- Call
OnInitLuaBinding
inNativeConstruct
- Call
OnReleaseLuaBinding
inNativeDestruct
- Call
OnProcessLuaOverrideEvent
inProcessEvent
The UUserWidget class also has a special place where the
LatentAction
owned by the class is not affected by the pause, so you also need to overrideNativeTick
and callLatentActionManager
in the virtual function to handle allLatentAction
objects. SeeTickActions
inLuaImplementableWidget.h
- Call
-
Class
UObject
, seeRPGAnimNotifyState.h
in Demo LuaActionRPG- Call
OnReleaseLuaBinding
inBeginDestroy
- Call
OnProcessLuaOverrideEvent
inProcessEvent
- Because the Uobject class does not have an initialized virtual function that can be overrided, so it can call
OnInitLuaBinding
the first time theProcessEvent
is called, as shown in the demo
- Call
-
Class
UGameInstance
, seeRPGGameInstanceBase.h
in Demo LuaActionRPG- Call
OnInitLuaBinding
inInit
- Call
OnReleaseLuaBinding
inShutdown
- Call
OnProcessLuaOverrideEvent
inProcessEvent
- Call
-
-
keyword
Super
When you use Lua to subclass c++ classes or blueprints, there is a temporary global object called Super represent the parent UObject that you can access it's properties and methods. It's only avaliable when lua file is loaded(
luaL_loadbuffer
), so you need to cache it's reference in your lua file likelocal MyParent = Super
and useMyParent
in your lua -
CastToLua
When you have a UObject in lua and want to know if the object has a lua subclass, you can call
CastToLua
on that object likelocal LuaObject = OtherObject:CastToLua()
, it returns a lua table represent the lua object ifOtherObject
has a lua subclass.CastToLua
works like cast in blueprint: -
Modular lua subcalss
All lua subclass should implement in modular table and methods should declare with : not ., see see
GameInstance.lua
in Demo LuaActionRPGlocal m = {} function m:func() end return m
-
inheritance in lua
You can use lua metatable to implement inheritance like you do in C++ or blueprint, see PlayerCharacter.lua and Character.lua in Demo LuaActionRPG
-
When a UFUNCTION expose to blueprint, it can has a alias, like
BeginPlay
in blueprint, it actually calledReceiveBeginPlay
. so when you override this function in lua you should useReceiveBeginPlay
notBeginPlay
.
- LuaActionRPG: Epic's ActionRPG demo in lua implementation, still work in progress
- BlueluaDemo: benchmark and test
- expose lua file reader to project, do not assume lua files under ProjectContent folder
- hot reload lua
- optimize OnProcessLuaOverrideEvent when find lua function