赞
踩
本项目将整合之前Unity程序基础小框架专栏在Unity 3D模型展示项目基础上进行整合,并记录了集成过程中对原脚本的调整过程。增加了Asset Bundle+ILRuntime热更新技术流程。
效果展示
1.通过框架中的BasePanel.cs
脚本进行UI事件的注册。
BasePanel.cs
的脚本将寻找UI控件并完成事件的注册,使得注册事件变得异常简单。
/// <summary>
/// 找到子对象的对应控件
/// </summary>
/// <typeparam name="T"></typeparam>
private void FindChildrenControl<T>() where T : UIBehaviour
{
T[] controls = this.GetComponentsInChildren<T>();
for (int i = 0; i < controls.Length; ++i)
{
string objName = controls[i].gameObject.name;
Debug.Log("面板获取:"+objName);
if (controlDic.ContainsKey(objName))
controlDic[objName].Add(controls[i]);
else
controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
//如果是按钮控件
if (controls[i] is Button)
{
(controls[i] as Button).onClick.AddListener(() =>
{
OnClick(objName);
});
}
//如果是单选框或者多选框
else if (controls[i] is Toggle)
{
(controls[i] as Toggle).onValueChanged.AddListener((value) =>
{
OnValueChanged(objName, value);
});
}
}
}
要实现自己的事件逻辑,只需要进行重写以下方法。
/// <summary>
/// 显示自己
/// </summary>
public virtual void ShowMe()
{
}
/// <summary>
/// 隐藏自己
/// </summary>
public virtual void HideMe()
{
}
public virtual void OnClick(string btnName)
{
}
protected virtual void OnValueChanged(string toggleName, bool value)
{
}
完整代码如下
/// <summary>
/// 面板基类
/// 帮助我门通过代码快速的找到所有的子控件
/// 方便我们在子类中处理逻辑
/// 节约找控件的工作量
/// </summary>
public class BasePanel : MonoBehaviour
{
//通过里式转换原则 来存储所有的控件
private Dictionary<string, List<UIBehaviour>> controlDic = new Dictionary<string, List<UIBehaviour>>();
// Use this for initialization
public virtual void Awake()
{
FindChildrenControl<Button>();
FindChildrenControl<Image>();
FindChildrenControl<Text>();
FindChildrenControl<Toggle>();
FindChildrenControl<Slider>();
FindChildrenControl<ScrollRect>();
FindChildrenControl<InputField>();
}
/// <summary>
/// 显示自己
/// </summary>
public virtual void ShowMe()
{
}
/// <summary>
/// 隐藏自己
/// </summary>
public virtual void HideMe()
{
}
public virtual void OnClick(string btnName)
{
}
protected virtual void OnValueChanged(string toggleName, bool value)
{
}
public static Transform FindTheChild(GameObject goParent, string childName)
{
Transform searchTrans = goParent.transform.Find(childName);
if (searchTrans == null)
{
foreach (Transform trans in goParent.transform)
{
searchTrans = FindTheChild(trans.gameObject, childName);
if (searchTrans != null)
{
return searchTrans;
}
}
}
return searchTrans;
}
/// <summary>
/// 得到对应名字的对应控件脚本
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="controlName"></param>
/// <returns></returns>
protected T GetControl<T>(string controlName) where T : UIBehaviour
{
if (controlDic.ContainsKey(controlName))
{
for (int i = 0; i < controlDic[controlName].Count; ++i)
{
if (controlDic[controlName][i] is T)
Debug.Log(controlDic);
return controlDic[controlName][i] as T;
}
}
return null;
}
/// <summary>
/// 找到子对象的对应控件
/// </summary>
/// <typeparam name="T"></typeparam>
private void FindChildrenControl<T>() where T : UIBehaviour
{
T[] controls = this.GetComponentsInChildren<T>();
for (int i = 0; i < controls.Length; ++i)
{
string objName = controls[i].gameObject.name;
Debug.Log("面板获取:"+objName);
if (controlDic.ContainsKey(objName))
controlDic[objName].Add(controls[i]);
else
controlDic.Add(objName, new List<UIBehaviour>() { controls[i] });
//如果是按钮控件
if (controls[i] is Button)
{
(controls[i] as Button).onClick.AddListener(() =>
{
OnClick(objName);
});
}
//如果是单选框或者多选框
else if (controls[i] is Toggle)
{
(controls[i] as Toggle).onValueChanged.AddListener((value) =>
{
OnValueChanged(objName, value);
});
}
}
}
}
业务应用:将MainBaseUI.cs
继承BasePanel.cs
脚本,给按钮BtnClose
、BtnReset
、BtnSet
注册事件,按钮的命名一定要和脚本中的名称对应上,否则注册不上。
在MainBaseUI.cs
重写BasePanel.cs
基类的OnClick
事件
public override void OnClick(string btnName)
{
if (btnName== "BtnClose")
{
Debug.Log("关闭");
}
else if (btnName == "BtnReset")
{
Debug.Log("重置");
}
else if (btnName == "BtnSet")
{
animator.SetBool("isout", !animator.GetBool("isout"));
}
}
Toggle
UI注册事件设置标注隐藏显示
public override void OnValueChanged(string toggleName, bool value)
{
if (toggleName == "MemoToggle")
{
SwitchOperation.Instance.hideInfo(value);
}
}
MainBaseUI.cs
注册事件完整脚本代码
public class MainBaseUI : BasePanel
{
public static MainBaseUI Instance;
private Animator animator;
public override void Awake()
{
Instance = this;
base.Awake();
}
public void InitData() {
Debug.Log("初始化信息!");
animator = this.GetComponent<Animator>();
}
[FormerlySerializedAs("taskPrefabs")]
[Tooltip("Prefab of the object. Prefab must have a Info component. May be an empty game object or a full avatar.")]
public GameObject taskPrefabs;
public Transform taskParentTransform;
// Start is called before the first frame update
void Start()
{
}
public override void OnClick(string btnName)
{
if (btnName== "BtnClose")
{
Debug.Log("关闭");
}
else if (btnName == "BtnReset")
{
Debug.Log("重置");
}
else if (btnName == "BtnSet")
{
animator.SetBool("isout", !animator.GetBool("isout"));
}
}
public override void OnValueChanged(string toggleName, bool value)
{
if (toggleName == "MemoToggle")
{
SwitchOperation.Instance.hideInfo(value);
}
}
// Update is called once per frame
void Update()
{
}
}
2.通过框架中的ResMgr.cs
脚本进行开关预制体初始化。
在MyGameManager.cs
脚本中将预制体的路径传入即可
ResMgr.GetInstance().Load<GameObject>("Prefabs/Switch");
由于现在是动态加载预制体,所以要控制一下出现的位置(parentObj
)以及进行加载后预制体命名,完整代码如下
public class MyGameManager : MonoBehaviour
{
public GameObject parentObj;
// Start is called before the first frame update
void Start()
{
var tempDD = ResMgr.GetInstance().Load<GameObject>("Prefabs/Switch");
tempDD.transform.SetParent(parentObj.transform);
tempDD.name = "Switch";
}
}
下一篇将物体自由观察通过Cinemachine
进行实现。
关于框架资源包,评论处留下你的邮箱地址。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。