欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity 之 ToLua框架中UI.Dropdown组件动态添加Options

程序员文章站 2022-06-12 20:54:22
...

前言

最近使用ToLua框架使用Unity中的Dropdown组件,其他属性都还好和在C#中使用的形式差不多,只是修改成了Lua的语法习惯就可以了,但是我有个需求,是要需要实现动态添加Dropdown中的Options,这个就很做起来废了半天劲,后来发现是被坑了,本文就说说在ToLua框架中使用Dropdown动态添加Options。

一,在C#中动态添加Options

1.获取Dropdown组件,然后动态添加options:

  //创建Dropdown自定义预制体,并获取其组件
   Dropdown dropDown= GetPoolItem(rowRoot, "CreateRoom_Dropdown").GetComponent<Dropdown>();
   Dropdown.OptionData data = new Dropdown.OptionData();
   data.text = "下拉选项1";
   dropDown.options.Add(data);

或者你也可以这么写:

	List<Dropdown.OptionData> listOptions = new List<Dropdown.OptionData>();       
    listOptions.Add(new Dropdown.OptionData("下拉选项2"));
    listOptions.Add(new Dropdown.OptionData("下拉选项3"));
    dropDown.AddOptions(listOptions);

2.其他属性获取简介推荐查看:
Unity 之 UGUI Dropdown组件使用简析


二,在Lua中动态添加Options

1.首先要在CustomSettings中添加_GT(typeof(Dropdown.OptionData))
Unity 之 ToLua框架中UI.Dropdown组件动态添加Options
2.在工程中点击Lua --> Generate All 重新打出Warp包
Unity 之 ToLua框架中UI.Dropdown组件动态添加Options
3.然后你在工程LuaFramework --> Source --> Generate 目录下可以找到名字为UnityEngine_UI_Dropdown_OptionDataWrap的C#文件,然后看下Register方法,开始使用:

	public static void Register(LuaState L)
	{
		L.BeginClass(typeof(UnityEngine.UI.Dropdown.OptionData), typeof(System.Object));
		L.RegFunction("New", _CreateUnityEngine_UI_Dropdown_OptionData);
		L.RegFunction("__tostring", ToLua.op_ToString);
		L.RegVar("text", get_text, set_text);
		L.RegVar("image", get_image, set_image);
		L.EndClass();
	}

4.使用Lua动态添加添加Options

在文件头做个引用

local OptionData = UnityEngine.UI.Dropdown.OptionData 

按照C#中写的步骤使用Lua的形势写:

function CreateDropdown(ctrlNodel,rowParent)
	-- 这里改成你自己的获取组件的方式
	local newDorpDown = resMgr:LoadPrefab(PrefabsPath.."CreateRoom_Dropdown",rowParent):GetComponent("Dropdown");
	-- 这是一个错误写法 正确需要用.调用
	local data = OptionData:New();
	data.text = "下拉选项1";
	newDorpDown.options:Add(data);
end

按照这个流程写是没有问题的,如果你这时候运行后成功设置了options属性了,那么你就不用往下看了;如果你没有运行成功,请你断点调试或者在代码中间打几个日志。经查:我发现代码是在local data = OptionData:New();这行就执行出了问题,就没有向下执行了。


三,在Lua中使用需要注意的

不知道为什么在New的时候执行逻辑会有问题,上面介绍过了,在UnityEngine_UI_Dropdown_OptionDataWrap
这个类里面,Lua中调用的New方法实际上走的是C#中的_CreateUnityEngine_UI_Dropdown_OptionData这个方法,看上面Register这个方法这样写的:

L.RegFunction("New", _CreateUnityEngine_UI_Dropdown_OptionData);

所以我去查看这个方法:


	[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
	static int _CreateUnityEngine_UI_Dropdown_OptionData(IntPtr L)
	{
		try
		{
			int count = LuaDLL.lua_gettop(L);

			if (count == 0)
			{
				UnityEngine.UI.Dropdown.OptionData obj = new UnityEngine.UI.Dropdown.OptionData();
				ToLua.PushObject(L, obj);
				return 1;
			}
			else if (count == 1 && TypeChecker.CheckTypes<UnityEngine.Sprite>(L, 1))
			{
				UnityEngine.Sprite arg0 = (UnityEngine.Sprite)ToLua.ToObject(L, 1);
				UnityEngine.UI.Dropdown.OptionData obj = new UnityEngine.UI.Dropdown.OptionData(arg0);
				ToLua.PushObject(L, obj);
				return 1;
			}
			else if (count == 1 && TypeChecker.CheckTypes<string>(L, 1))
			{
				string arg0 = ToLua.ToString(L, 1);
				UnityEngine.UI.Dropdown.OptionData obj = new UnityEngine.UI.Dropdown.OptionData(arg0);
				ToLua.PushObject(L, obj);
				return 1;
			}
			else if (count == 2)
			{
				string arg0 = ToLua.CheckString(L, 1);
				UnityEngine.Sprite arg1 = (UnityEngine.Sprite)ToLua.CheckObject(L, 2, typeof(UnityEngine.Sprite));
				UnityEngine.UI.Dropdown.OptionData obj = new UnityEngine.UI.Dropdown.OptionData(arg0, arg1);
				ToLua.PushObject(L, obj);
				return 1;
			}
			else
			{
				return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: UnityEngine.UI.Dropdown.OptionData.New");
			}
		}
		catch (Exception e)
		{
			return LuaDLL.toluaL_exception(L, e);
		}
	}

这是框架个自动生成的方法啊,看起来没问啊,,,有不带参数的,一个参数的,两个参数的校验,并且有异常校验,简直是完美啊。然而为什么我上面的调用不好用呢,有些想不明白。

我尝试使用一个参数的形式调用:

function CreateDropdown(ctrlNodel,rowParent)
	-- 这里改成你自己的获取组件的方式
	local newDorpDown = resMgr:LoadPrefab(PrefabsPath.."CreateRoom_Dropdown",rowParent):GetComponent("Dropdown");
	local data = OptionData:New("下拉选项1");
	newDorpDown.options:Add(data);
end

结果运行起来还是不好使,两个参数的我也尝试了,结果当然还是不行。
我开始怀疑这个自动生成的这Warp文件执行的有问题啊,我在下图位置加了个日志:
Unity 之 ToLua框架中UI.Dropdown组件动态添加Options
运行起来果然有问题,我写的调用的无参数的然而输出的参数个数却是1个:

local data = OptionData:New();

Unity 之 ToLua框架中UI.Dropdown组件动态添加Options
同理我尝试了传一个参数调用,输出的参数个数是2个,事实证明当我使用OptionData:New();这种形式调用的时候,会默认传递一个参数,,,

默认参数,,,嗯,,,思考了下,学习Lua的时候使用冒号(:)调用的时候就会传递一个self啊,,,然后我尝试使用(.)来调用,,,结果就真的没问题了,真是坑啊,,,还是自己没有使用明白啊,,,以此来博文,来加深下印象,希望可以帮到遇到相关问题的你。


修改后调用代码如下:

function CreateDropdown(ctrlNodel,rowParent)
	-- 这里改成你自己的获取组件的方式
	local newDorpDown = resMgr:LoadPrefab(PrefabsPath.."CreateRoom_Dropdown",rowParent):GetComponent("Dropdown");
	local data = OptionData.New("下拉选项1");
	newDorpDown.options:Add(data);
end