28.xLua热补丁-事件加减操作替换
28.1 知识点
准备工作
创建有事件成员的测试类
[Hotfix]
public class Lesson28_Test : MonoBehaviour
{
event UnityAction myEvent;
private void TestFunction1()
{
Debug.Log("我是C#中的函数TestFunction1");
}
private void TestFunction2()
{
Debug.Log("我是C#中的函数TestFunction2");
}
private void Start()
{
myEvent += TestFunction1;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
myEvent += TestFunction1;
}
if (Input.GetKeyDown(KeyCode.W))
{
myEvent -= TestFunction1;
}
if (Input.GetKeyDown(KeyCode.E))
{
myEvent += TestFunction2;
}
if (Input.GetKeyDown(KeyCode.R))
{
myEvent -= TestFunction2;
}
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log($"myEvent是不是空 {myEvent == null}");
//myEvent是不是空 True
//因为是把函数加到lua中处理了,没有加到myEvent中,所以myEvent一直是空
Action InvokeMyEvent = LuaManager.Instance.Global.Get<Action>("InvokeMyEvent");
InvokeMyEvent();
}
}
}
启动Lua脚本
LuaManager.Instance.Init();
LuaManager.Instance.DoLuaFile("Lesson28_xLua热补丁_事件加减操作替换");
Lesson28_Test test = this.gameObject.AddComponent<Lesson28_Test>();
事件加减操作替换
事件加减操作替换:当 C# 对事件做 += / -= 时,若做了 add_事件名 / remove_事件名 热补丁,实际不会改 C# 里事件字段,而是把 要增删的委托 交给 Lua 补丁逻辑处理(正文用表缓存委托再在 Lua 侧统一触发)。
-- 创建一个表来存储事件处理函数,会把C#对某个事件添加的函数添加到这个表中
local eventHandlers = {}
-- 事件加减操作热补丁替换 操作_事件名 把对事件的操作当成一个成员函数 会有一个委托变量作为参数
xlua.hotfix(CS.Lesson28_Test, {
-- add_事件名
add_myEvent = function(self, delegate)
print(delegate)
print("添加事件函数")
-- 将委托存储到表中
table.insert(eventHandlers, delegate)
-- 在事件加减操作重定向函数中不要把传入的委托往事件里存,以避免死循环
-- self:myEvent("+", delegate)--死循环
end,
-- remove_事件名 减操作
remove_myEvent = function(self, delegate)
print(delegate)
print("移除事件函数")
-- 在移除事件时从表中移除委托
for i, handler in ipairs(eventHandlers) do
-- 不能直接==判断 要比较地址
if tostring(handler) == tostring(delegate) then
table.remove(eventHandlers, i)
break
end
end
end
})
-- 触发所有C#加进来的函数
function InvokeMyEvent()
for i, handler in ipairs(eventHandlers) do
handler()
end
end
测试结果
按下Q和E可以给委托添加函数,WR移除,空格触发。但是是在Lua遍历函数表触发的,C#的委托变量始终为空
28.2 知识点代码
Lesson28_xLua热补丁_事件加减操作替换.lua
print('我是Lua脚本 Lesson28_xLua热补丁_事件加减操作替换')
print("*********知识点一 事件加减操作替换***********")
-- 创建一个表来存储事件处理函数,会把C#对某个事件添加的函数添加到这个表中
local eventHandlers = {}
-- 事件加减操作热补丁替换 操作_事件名 把对事件的操作当成一个成员函数 会有一个委托变量作为参数
xlua.hotfix(CS.Lesson28_Test, {
-- add_事件名
add_myEvent = function(self, delegate)
print(delegate)
print("添加事件函数")
-- 将委托存储到表中
table.insert(eventHandlers, delegate)
-- 在事件加减操作重定向函数中不要把传入的委托往事件里存,以避免死循环
-- self:myEvent("+", delegate)--死循环
end,
-- remove_事件名 减操作
remove_myEvent = function(self, delegate)
print(delegate)
print("移除事件函数")
-- 在移除事件时从表中移除委托
for i, handler in ipairs(eventHandlers) do
-- 不能直接==判断 要比较地址
if tostring(handler) == tostring(delegate) then
table.remove(eventHandlers, i)
break
end
end
end
})
-- 触发所有C#加进来的函数
function InvokeMyEvent()
for i, handler in ipairs(eventHandlers) do
handler()
end
end
Lesson28_xLua热补丁_事件加减操作替换
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using XLua;
public class Lesson28_xLua热补丁_事件加减操作替换 : MonoBehaviour
{
void Start()
{
LuaManager.Instance.Init();
LuaManager.Instance.DoLuaFile("Lesson28_xLua热补丁_事件加减操作替换");
Lesson28_Test test = this.gameObject.AddComponent<Lesson28_Test>();
}
}
[Hotfix]
public class Lesson28_Test : MonoBehaviour
{
event UnityAction myEvent;
private void TestFunction1()
{
Debug.Log("我是C#中的函数TestFunction1");
}
private void TestFunction2()
{
Debug.Log("我是C#中的函数TestFunction2");
}
private void Start()
{
myEvent += TestFunction1;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
myEvent += TestFunction1;
}
if (Input.GetKeyDown(KeyCode.W))
{
myEvent -= TestFunction1;
}
if (Input.GetKeyDown(KeyCode.E))
{
myEvent += TestFunction2;
}
if (Input.GetKeyDown(KeyCode.R))
{
myEvent -= TestFunction2;
}
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log($"myEvent是不是空 {myEvent == null}");
//myEvent是不是空 True
//因为是把函数加到lua中处理了,没有加到myEvent中,所以myEvent一直是空
Action InvokeMyEvent = LuaManager.Instance.Global.Get<Action>("InvokeMyEvent");
InvokeMyEvent();
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com