MVC结构变种——第三章核心视图及控制器的整体逻辑
各组件职责与交互详解
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();所以这里是MainViewvar 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逻辑 }