Tencent / UnLua

A feature-rich, easy-learning and highly optimized Lua scripting plugin for UE.
Other
2.28k stars 619 forks source link

Cannot override function in runtime #716

Open BaconVN opened 4 months ago

BaconVN commented 4 months ago

I tried to override function from UnLua.Class() from runtime but it did not work, the game will only call the LUA function which was defined from the beginning

-- SummonActor.lua
local SummonActor = Unlua.Class()

function SummonActor:K2_Summon()
    print('Summon')
end

function SummonActor:Initialize(Initializer)
    self:K2_Summon = function()
        print('Overriden summon')
    end
    -- If I call self:K2_Summon here, it will print 'Overriden summon' correctly
end

return SummonActor

If I call K2_Summon on blueprint or C++. It wont call the override function. It still print 'Summon'. Did anyone know how to override function in runtime and it take effects on calls from blueprints or C++?

BaconVN commented 4 months ago

Following this article: https://ue5wiki.com/wiki/35271/

I assume that when the LUA script is bound to the UClass, it bind the POINTER function of the LUA script to the matching UFunction in the UClass. Which makes overriding in runtime impossible because the Blueprint/C++ will only calls the pointer of the old lua function instead of the new overrided one when the UFunction is called?

HuaNanHYC commented 3 months ago

UnLua将Lua函数覆写后,去调用Lua的函数时调用的是Lua文件里定义好的那个函数,在lua中执行修改相当于创建了新的函数,只作用于Lua中。

BaconVN commented 2 months ago

I see, so I made another helper script to solve this. Just in case anyone need to override or modify the function based on runtime. Basically you have to define all of the functions that will bind to the unreal environment from the beginning. The function in LUA that binds will be the thunk function and calls to it native LUA function. For example:

-- Define function you want to override from the beginning
function M:FunctionA()
  if(self.FunctionA_LuaNative) then
    self:FunctionA_LuaNative()
  end
  -- Run overridden here or above
end

function M:Tick(deltaTime)
  -- Change function content in runtime
  if(deltaTime % 2 == 0) then
    self.FunctionA_LuaNative = function()
      print('Even')
    end
  else
    self.FunctionA_LuaNative = function()
      print('Odd')
    end
  end
end

Those are just bare concept. Of course you have to make a list of overriding functions and automate this process yourself.