MVC结构变种——第三章核心视图及控制器的整体逻辑
了一个新类型;只是一个声明创建实例时第一次访问静态属性 `Instance` 的时候:在 MainViewController.Instance 第一次被访问(即执行到 MainViewController.Instance.Init(...))时,才创建 MainViewController 实例。设置资源路径和回调。
各组件职责与交互详解
1. View类 (UI视图基类)
核心职责:
管理UI基础元素:GameObject、Transform、Canvas等
处理UI生命周期:Awake/OnEnable/OnDisable
实现UI通用功能:分辨率适配(SetSize)、多语言支持(SetText)
提供组件查找方法(GetComponent)
2. ViewController类 (视图控制器基类)
核心职责:
管理View的生命周期:Init/Open/Close
实现单例模式:通过泛型
T
保证每个控制器唯一处理UI渲染顺序:ResetSortOrder/SetNavToTop
管理UI状态:IsOpen/SetActive
关键流程:
3. ViewManager类 (视图管理中心)
核心职责:
集中初始化所有视图控制器
提供全局更新事件(OnUpdate)
管理全局UI渲染顺序(order计数器)
4. MainViewController/MainView (具体实现单一类型View及ViewController)
具体流程
初始化:
csharp // ViewManager初始化时 MainViewController.Instance.Init("UI/MainCanvas", true, false); //ViewController<T, V> 类中创建实例及初始化 public class ViewController<T, V> where T : new() where V : View, new() { static T instance = new T(); public static T Instance => instance; bool open_nav_view; public V view; public void Init(string resPath, bool isAddUpdateListerner = false, bool stopAI_OnOpen = false, bool open_nav = false) { view = new V(); view.Init(resPath, isAddUpdateListerner, Close, stopAI_OnOpen); this.open_nav_view = open_nav; GameEvent.ResetSortOrder += ResetSortOrder; }
创建
MainView
实例
MainViewController : ViewController<MainViewController, MainView>
只是定义了一个新类型;只是一个声明创建实例时第一次访问静态属性 `Instance` 的时候:
在 MainViewController.Instance 第一次被访问(即执行到 MainViewController.Instance.Init(...))时,才创建 MainViewController 实例。设置资源路径和回调
打开界面:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class SceneController : MonoBehaviour { public void Load(string next) { LoadingViewController.Instance.Open(); LoginViewController.Instance.Close(); StartCoroutine(LoadSceneAsync(next)); } IEnumerator LoadSceneAsync(string next) { …… //打开主页面板 MainViewController.Instance.Open(); } }
加载预制件资源(资源路径需要详细讲解)
public void Open() { if (view.gameObject == null) { //实例化该预制体,预制体路径存储在当前类型View参数中 //因为是MainViewController.Instance.Open();所以这里是MainView var go = ResourcesManager.Instance.Instantiate<GameObject>(view.resPath); Debug.Log("view.resPath" + view.resPath); …… view.canvas = go.GetComponent<Canvas>(); view.cs = go.GetComponent<CanvasScaler>(); } } public class ViewController<T, V> where T : new() where V : View, new() { public void Init(string resPath, bool isAddUpdateListerner = false, bool stopAI_OnOpen = false, bool open_nav = false) { view = new V(); view.Init(resPath, isAddUpdateListerner, Close, stopAI_OnOpen);//这里的view.init有viewManager控制,意思是在ViewManager执行初始化时,已经将对应路径通过对应Controller传参到对应View里面 } } using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class ViewManager { static ViewManager instance = new ViewManager(); public static ViewManager Instance => instance; public int order; public void Init() { …… MainViewController.Instance.Init("UI/MainCanvas", true, false); //对应路径通过对应Controller传参到对应View里面 }
初始化Canvas组件
触发OnEnable生命周期(在Open方法中)
public void Open() { if (view.gameObject == null) { …… SetActive(true);//在这里手动调用OnEnable生命周期 …… } else { //打开 SetActive(true); } }
业务操作:
csharp // 游戏逻辑中 MainViewController.Instance.UpdatePlayerHP(0.8f); csharp // MainViewController内部 public void UpdatePlayerHP(float v) { view.UpdatePlayerHP(v); // 调用MainView的具体实现 }
控制器调用视图的具体方法
全局更新:
csharp // MainView.OnEnable中注册 ViewManager.Instance.OnUpdate += Update; // MainView中实现 public override void Update() { // 每帧更新UI逻辑 }
更多推荐
所有评论(0)