Unity开发——C#反射与泛型使用

25 篇文章 1 订阅
15 篇文章 0 订阅
一、GetList<T1>();

在 ClassB脚本里获取 ClassA类 里的所有 T1类型 的字段,并放到列表中,然后返回结果列表

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System;
using System.Reflection;//使用泛型
using System.Collections.Generic;

public class ClassB : MonoBehaviour
{
    private ClassA classA;
    ...

    //获取 ClassB类 里的所有 T1类型 的字段,并放到列表中,返回结果列表
    private List<T1> GetList<T1>()
    {
        FieldInfo[] fieldInfos = classA.GetType().GetFields();
        List<T1> getLsits = new List<T1>();
        foreach (FieldInfo item in fieldInfos)
        {
            if (item.FieldType == typeof(T1))
            {
                T1 temp = (T1)item.GetValue(classA);
                getLsits.Add(temp);
            }
        }
        return getLsits;
    }
 
    ...
}
二、GetList<T1>();应用:ObjAddListener();

使用GetList<T1>();方法,依次添加监听事件;

public class ClassB : MonoBehaviour
{
    ...

    private List<Slider> testSliders;
    private List<TMP_Dropdown> testDrop;
    private List<TMP_InputField> testInput;

    ...

    private void ObjAddListener()
    {
        testDrop = GetList<TMP_Dropdown>();
        foreach (var drop in testDrop)
        {
            drop.onValueChanged.AddListener((int index) => GetDropValue(index, drop));
        }

        testSliders = GetList<Slider>();
        foreach (Slider slider in testSliders)
        {
            slider.onValueChanged.AddListener((float value) => SliderChange(value,slider));
        }

        testInput= GetList<TMP_InputField>();
        foreach(TMP_InputField input in testInput)
        {
            input.onEndEdit.AddListener(delegate { OnEndEditInput(input); });
        }
    }

    private void GetDropValue(int value, TMP_Dropdown drop) {}
    private void SliderChange(float value, Slider slider){}
    private void OnEndEditInput(string value, TMP_InputField input){}
 
    ...
}
 三、GetSingleData<T1,T2>(T1 sourceDatas, T2 targetObj, string name);

将sourceDatas里字段名为name的值赋值给targetObj对象;

(目标不能直接赋值)

public class ClassB : MonoBehaviour
{
    ...

    /// <summary>
    /// 将sourceDatas里字段名为name的值赋值给targetObj;
    /// </summary>
    /// <typeparam name="T1">泛型1</typeparam>
    /// <typeparam name="T2">泛型2</typeparam>
    /// <param name="sourceDatas">源数据/查找目标对象的源地址</param>
    /// <param name="targetObj">目标对象</param>
    /// <param name="name">字段名</param>
    private void GetSingleData<T1,T2>(T1 sourceDatas, T2 targetObj, string name)
    {
        //源数据
        FieldInfo info1 = sourceDatas.GetType().GetField(name);
        float temp = (float)info1.GetValue(sourceDatas);
        float newValue;
        if (name == "xxx")
        {
            newValue = temp * 100;
            name = "xxxSlider";
        }
        else
        {
            newValue = temp * 10;
            name = name + "Slider";
        }

        //目标Slider
        FieldInfo info2 = targetObj.GetType().GetField(name);
        Slider targetSlider = (Slider)info2.GetValue(targetObj);
        targetSlider.value = newValue;
    }
 
    ...
}
四、SetSingleData<T1,T2>(T1 sourceObj, T2 target, string name);

根据sourceDatas里字段名为name的值,直接设置目标对象里字段名为name的值;

(目标可直接赋值)

public class ClassB : MonoBehaviour
{
    ...

    /// <summary>
    /// 根据sourceDatas里字段名为name的值。设置目标对象里字段名为name的值;
    /// </summary>
    /// <typeparam name="T1">泛型1</typeparam>
    /// <typeparam name="T2">泛型2</typeparam>
    /// <param name="sourceObj">源对象</param>
    /// <param name="target">目标对象</param>
    /// <param name="name">字段名</param>
    private void SetSingleData<T1,T2>(T1 sourceObj, T2 target, string name)
    {
        //源Slider
        FieldInfo fieldInfo1 = sourceObj.GetType().GetField(name);
        Slider temp = (Slider)fieldInfo1.GetValue(sourceObj);
        float newValue;
        int num = name.Length;
        if (name == "yyySlider")
        {
            newValue = temp.value / 100;
            name = "yyyValue";
        }
        else
        {
            newValue = temp.value / 10;
            name = name.Remove(num - 6);
        }
        //目标存储值
        FieldInfo info2 = target.GetType().GetField(name);
        info2.SetValue(target, newValue);
    }

    ...
}
五、GetSingleData<T1,T2>(T1 sourceDatas, T2 targetObj, string name);应用:GetSliderDatas();
public class ClassB : MonoBehaviour
{
    ...

    private void GetSliderDatas()
    {
        FieldInfo[] fieldInfos = ClassC.instance.zzzConfig.GetType().GetFields();
        foreach (FieldInfo item in fieldInfos)
        {
            if (item.FieldType == typeof(float))
            {
                GetSingleData(ClassC.instance.zzzConfig, classA, item.Name);
            }
        }
    }

    ...
}
六、SetSingleData<T1,T2>(T1 sourceObj, T2 target, string name);应用:SetSliderDatas();
public class ClassB : MonoBehaviour
{
    ...

    private void SetSliderDatas()
    {
        FieldInfo[] fieldInfos = ClassA.GetType().GetFields();
        foreach (FieldInfo item in fieldInfos)
        {
            if (item.FieldType == typeof(Slider))
            {
                switch (item.Name)
                {
                    case "aaaSlider":
                    case "bbbSlider":
                    case "cccSlider":
                        break;
                    default:
                        SetSingleData(classA, ClassB.instance.zzzConfig, item.Name);
                        break;
                }
            }
        }
    }

    ...
}
七、相关类脚本
(1)ClassA:UI对象集合类
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ClassA
{
    public TMP_Dropdown aa;
    public TMP_Dropdown bb;
    public TMP_InputField ccInput;
    public TMP_InputField ddInput;
    public TMP_InputField eeInput;
    ...
    public Slider xxxSlider;
    public Slider yyySlider;
    public Slider cccSlider;
    public Slider aaaSlider;
    ...

    public SetPanelObjs(Transform aaaTrans, Transform bbbTrans, Transform cccTrans, Transform dddTrans, Transform eeeTrans, Transform fffTrans)
    {
        aaaSlider = aaaTrans.Find("aaa/Slider").GetComponent<Slider>();
        
        ...

        bb = bbbTrans.Find("bb/Dropdown").GetComponent<TMP_Dropdown>();
        
        ...

        ccInput = cccTrans.Find("cc/InputField").GetComponent<TMP_InputField>();

        ...
    }
}
(2)ClassC:数据应用类
using System;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class ClassC : MonoBehaviour
{
    public static ClassC instance;
    public ZzzConfig zzzConfig;
    
    ...

    private void GetSetInitialDatas()
    {
        zzzConfig.versionDatas = "Existence of Datas";
        zzzConfig.aaValue = 2;
        zzzConfig.bbbValue = SettingAccuracy(bb.value);
        zzzConfig.cc = 2;
        ...
    }

    ...

    public void Update()
    {
        if (isOk)
        {
            ...
            mmm.active = Convert.ToBoolean(zzzConfig.mmValue);
            vv.value = zzzConfig.vvv;
            uuu.value = zzzConfig.uu;
            sss.value = zzzConfig.sss;
            ...
        }
    }

    ...
}
(3)ZzzConfig:数据类
using System;

[Serializable]
public class ZzzControlConfig 
{
    ...
    public string versionDatas;
    public int sssValue;
    public string dddValue;
    public float mmmValue;
    ...
}
(4)ClassB:数据处理类
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System;
using System.Reflection;//使用泛型
using System.Collections.Generic;

public class ClassB : MonoBehaviour
{

    public Transform aa;
    public Transform bb;
    private Transform cc; 

    ...    

    private ClassA classA;
    private List<Slider> testSliders;
    private List<TMP_Dropdown> testDrop;
    private List<TMP_InputField> testInput;
    ...

    void Awake()
    {   
        ...
        classA= new ClassA(aa, bb, cc, dd, ee, ff);
        ...
    }

    ...

    private void Checkout()
    {
        if (ZzzControl.instance.isOk) { ClosePanel(); }
        else
        {
            Debug.Log("Failed");
            StartCoroutine(ApplicationOfFailure());
        }
    }

    ...

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值