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

前言

最近使用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))
CustomSettings
2.在工程中点击Lua --> Generate All 重新打出Warp包
Generate
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文件执行的有问题啊,我在下图位置加了个日志:
日志
运行起来果然有问题,我写的调用的无参数的然而输出的参数个数却是1个:

local data = OptionData:New();

调用
同理我尝试了传一个参数调用,输出的参数个数是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

猜你喜欢

转载自blog.csdn.net/Czhenya/article/details/105552049