• Unity之MVC思想(通过普通方法和使用MVC思想完成同一个小案例:掌握MVC简单框架)


    请添加图片描述

    @作者 : SYFStrive

    @博客首页 : 点击跳转HomePage

    📌:个人社区(欢迎大佬们加入) 👉:社区链接🔗

    💃:坚持锻炼💪

    🔗:点击直接阅读文章
    请添加图片描述
    在这里插入图片描述
    相关专栏

    👉 Unirt~UI简单框架(🔥)


    对MVC思想简单说明

    1. MVC思想就是一种让View(视图(UI界面))、Data(数据)之间分离,通过中介Controller(管理逻辑脚本)进行交互的一种框架思想,目的是为了减少代码的耦合性。

    2. MVC全名是Model View Controller,是模型(Model)👉 视图(View)👉 控制器(Controller)的缩写,是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

    3. M 👉 V 👉 C

      1、M(模型) 处理应用程序数据逻辑的部分 👉 通常模型对象负责在数据库中存取数据。
      2、V(视图) 是应用程序中处理数据显示的部分 👉 通常视图是依据模型数据创建的。
      3、C(控制器) 是应用程序中处理用户交互的部分 👉 通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据(管理相关逻辑)。

    4. 注意:1、Unity~MVC是一种非必须UI系统开发框架 2、主要用于开发游戏UI系统逻辑

    5. 优点:降低耦合性,方法修改,逻辑更清晰

    6. 缺点(1、有一定的性能消耗(如今的电脑配置基本可以忽略))

    普通方法与MVC思想脚本进行对比

    普通方法脚本如👇:

    代码少、体积小、逻辑复杂😥

    在这里插入图片描述
    MVC思想脚本如👇:

    脚本分开管理逻辑更加清晰😀

    在这里插入图片描述

    使用的UI预制体

    在这里插入图片描述

    最后效果

    在这里插入图片描述

    使用普通方法完成案例

    图示如👇:

    在这里插入图片描述

    1、PlayerGradeManager

    using UnityEngine;
    using UnityEngine.UI;
    
    public class PlayerGradeManager : MonoBehaviour
    {
        //正常写法 通常四部走 获取对应组件 👉 添加事件 👉 更新信息 👉 动态显示
        
        //1、获取对应组件
        public Text txtLev;
        public Button playerBut;
    
        private static PlayerGradeManager playerGradeManageG;
        public static PlayerGradeManager PlayerGradeManageG { get => playerGradeManageG; }
    
        //2、添加事件
        private void Start()
        {
            playerBut.onClick.AddListener(() =>
            {
                //打开角色面板的逻辑
               PlayerInfoManager.ShowMe();
            });
        }
    
        //3、更新信息
        public void UpdateInfo()
        {
            //获取玩家数据 更新数据
            //获取数据方法 1、网格请求 2、json 3、xml 4、2进制 5、PlayerPrefs公共类
    
            //这里通过PlayerPrefs来获取本地存储的玩家信息  更新信息界面上
            txtLev.text = "等级:" + PlayerPrefs.GetInt("LevValue", 1).ToString();
        }
    
        //4、动态显示
        public static void ShowMe()
        {
            if (PlayerGradeManageG == null)
            {
                GameObject res = Resources.Load("UI/PlayerGrade");
    
                GameObject obj = Instantiate(res);
    
                //设置他的位置
                obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
    
                //获取自身脚本
                playerGradeManageG = obj.GetComponent();
            }
    
            //创建完后显示
            PlayerGradeManageG.gameObject.SetActive(true);
    
            //更新面板后同步数据
            PlayerGradeManageG.UpdateInfo();
        }
        public static void HideMe()
        {
            //方式一 :直接删除
            //if (playerGradeManager != null)
            //{
            //    Destroy(playerGradeManager.gameObject);
            //    playerGradeManager = null;
            //}
    
            //方式二 :隐藏
            PlayerGradeManageG.gameObject.SetActive(false);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    2、PlayerInfoManager

    using UnityEngine;
    using UnityEngine.UI;
    
    public class PlayerInfoManager : MonoBehaviour
    {
       //正常写法 通常四部走
       
       //1、获取对应组件
       public Text playerAttack;
       public Text hp;
       public Text defense;
       public Text txtLev;
       public Button upgrade;
       public Button hideBag;
    
       private static PlayerInfoManager playerInfo;
    
       //2、添加事件
       private void Start()
       {
           upgrade.onClick.AddListener(() =>
           {
               Debug.Log("sasd");
               //升级相关逻辑
               UpLev();
    
           });
    
           hideBag.onClick.AddListener(() =>
           {
               //隐藏面板
               HideMe();
           });
       }
       //3、更新信息
       private void UpdateInfo()
       {
           //获取玩家数据 更新数据
           //获取数据方法 1、网格请求 2、json 3、xml 4、2进制 5、PlayerPrefs公共类
    
           //这里通过PlayerPrefs来获取本地存储的玩家信息  更新信息界面上
           txtLev.text = PlayerPrefs.GetInt("LevValue",1).ToString();
           playerAttack.text = PlayerPrefs.GetInt("AttackValue", 888).ToString();
           hp.text = PlayerPrefs.GetInt("HpValue", 888).ToString();
           defense.text = PlayerPrefs.GetInt("DefenseValue", 888).ToString();
       }
       //4、动态显示
       public static void ShowMe()
       {
           if (playerInfo == null)
           {
               GameObject res = Resources.Load("UI/PlayerInfo");
    
               GameObject obj = Instantiate(res);
    
               //设置他的位置
               obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
    
               //获取自身脚本
               playerInfo = obj.GetComponent();
           }
    
           //创建完后显示
           playerInfo.gameObject.SetActive(true);
    
           //更新面板后同步数据
           playerInfo.UpdateInfo();
       }
       public static void HideMe()
       {
           //方式一 :直接删除
           //if (playerGradeManager != null)
           //{
           //    Destroy(playerGradeManager.gameObject);
           //    playerGradeManager = null;
           //}
    
           //方式二 :隐藏
           playerInfo.gameObject.SetActive(false);
       }
    
       //升级相关逻辑
       private void UpLev()
       {
           //获取数据
           int LevValueInt = PlayerPrefs.GetInt("LevValue", 1);
           int AttackValueInt= PlayerPrefs.GetInt("AttackValue", 888);
           int HpValueInt = PlayerPrefs.GetInt("HpValue", 888);
           int DefenseValueInt = PlayerPrefs.GetInt("DefenseValue", 888);
           //更新磁盘里面的数据
           int add = 50;
           LevValueInt += add;
           AttackValueInt += add;
           HpValueInt += add;
           DefenseValueInt += add;
    
           PlayerPrefs.SetInt("LevValue", LevValueInt);
           PlayerPrefs.SetInt("AttackValue", AttackValueInt);
           PlayerPrefs.SetInt("HpValue", HpValueInt);
           PlayerPrefs.SetInt("DefenseValue", DefenseValueInt);
    
           //同步面板数据
           UpdateInfo();
    
           //同步PlayerGradeManager~UI界面的数据
           PlayerGradeManager.PlayerGradeManageG.UpdateInfo();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108

    3、UI_Evenemt (UI事件)

    using UnityEngine;
    
    public class UI_Evenemt : MonoBehaviour
    {
        private bool isShowBag;
    
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.B))
            {
                //显示隐藏面板
                isShowBag = !isShowBag;
                if (isShowBag)
                    PlayerGradeManager.ShowMe();
                else
                    PlayerGradeManager.HideMe();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用MVC思想完成案例

    图示如👇:

    在这里插入图片描述

    1、Controller

    PlayerGradeController

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    //MVC中的C 👉 1、Controller负责相关逻辑 👉 2、界面事件监听等 处理对应的业务逻辑 👉 3、界面更新
    public class PlayerGradeController : MonoBehaviour
    {
        //在Controller获取View 简单理解?? C控制V
        private PlayerGradeView playerGradeView;
    
        private static PlayerGradeController playerGradeControllerC=null;
    
        public static PlayerGradeController PlayerGradeControllerC { get => playerGradeControllerC;}
    
    
        private void Start()
        {
            //获取View脚本 👉 第一次更新界面  👉 监听事件处理相关逻辑
    
            //获取View脚本
            playerGradeView = GetComponent();
            //更新界面
            playerGradeView.UpdateInfo(ModeData.Instance);
            //事件监听
            playerGradeView.playerBut.onClick.AddListener(() =>
            {
                PlayerInfoController.ShowMe();
            });
            //添加委托事件
            ModeData.Instance.AddEvent(UpdateInFo);
        }
    
    
        //见面的显示与隐藏
        public static void ShowMe()
        {
            if (playerGradeControllerC == null)
            {
                //实例化UI对象
                GameObject res = Resources.Load("UI/PlayerGradeS");
                GameObject obj = Instantiate(res);
                //设置其位置到Canvas
                obj.transform.SetParent(GameObject.Find("Canvas").transform,false);
                //判断是否实例过
                playerGradeControllerC = obj.GetComponent();
            }
    
            playerGradeControllerC.gameObject.SetActive(true);
        } 
        public static void HideMe()
        {
            //方式一 :直接删除
            //if (playerGradeManager != null)
            //{
            //    Destroy(playerGradeManager.gameObject);
            //    playerGradeManager = null;
            //}
    
            //方式二 :隐藏
            if(playerGradeControllerC != null)
                playerGradeControllerC.gameObject.SetActive(false);
        }
    
        //更新同步数据
        private void UpdateInFo(ModeData function)
        {
            playerGradeView.UpdateInfo(function);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    PlayerInfoController

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    //MVC中的C 👉 1、Controller负责相关逻辑 👉 2、界面事件监听等 处理对应的业务逻辑  👉 3、界面更新……
    public class PlayerInfoController : MonoBehaviour
    {
        //在Controller获取View 简单理解 👉 C控制V
        private PlayerInfoView playerInfoView;
    
        private static PlayerInfoController playerInfoControllerC=null;
    
        public static PlayerInfoController PlayerInfoControllerC { get => playerInfoControllerC; }
    
    
        private void Start()
        {
            //获取View脚本 👉  第一次更新界面  👉 监听事件处理相关逻辑
    
            //获取View脚本
            playerInfoView = GetComponent();
            //更新界面
            playerInfoView.UpdateInfo(ModeData.Instance);
            //添加委托事件
            ModeData.Instance.AddEvent(UpdateInFo);
            //事件监听
            playerInfoView.upgrade.onClick.AddListener(() =>
            {
                ModeData.Instance.UpLev();
            });
            playerInfoView.hideBag.onClick.AddListener(() =>
            {
                HideMe();
            });
        }
    
    
        //见面的显示与隐藏
        public static void ShowMe()
        {
            if (playerInfoControllerC == null)
            {
                //实例化UI对象
                GameObject res = Resources.Load("UI/PlayerInfoS");
                GameObject obj = Instantiate(res);
                //设置其位置到Canvas
                obj.transform.SetParent(GameObject.Find("Canvas").transform, false);
                //判断是否实例过
                playerInfoControllerC = obj.GetComponent();
            }
    
            playerInfoControllerC.gameObject.SetActive(true);
        }
    
        private static void HideMe()
        {
            //方式一 :直接删除
            //if (playerGradeManager != null)
            //{
            //    Destroy(playerGradeManager.gameObject);
            //    playerGradeManager = null;
            //}
    
            //方式二 :隐藏
            if (playerInfoControllerC != null)
                playerInfoControllerC.gameObject.SetActive(false);
        }
    
        //更新同步数据
        private void UpdateInFo(ModeData function)
        {
            playerInfoView.UpdateInfo(function);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    2、ModelData

    ModeData

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;
    
    //MVC中的M 👉 储存数据
    public class ModeData
    {
        //MVC 👉 M一般流程 如👇:
        //1、数据内容 ?? 2、数据相关操作&&初始化 ……?? 3、更新数据 ?? 4、储存数据 ……
    
        //1、数据内容
        private int playerLve;
    
        private int lev;
        private int attackValue;
        private int hp;
        private int defense;
    
        public int PlayerLve { get => playerLve; }
    
        public int Lev { get => lev;}
        public int AttackValue { get => attackValue;}
        public int Hp { get => hp;}
        public int Defense { get => defense;}
    
        //使用单例用于外部调用 (M一般情况:自己是个静态单例 或者 存在一个单例模式对象中)
        private static ModeData instance=null;
    
        public static ModeData Instance {
            get
            {
                if (instance == null)
                {
                    instance = new ModeData();
                    instance.Init();
                }
                 return instance;
            }
        }
    
        //使用MVC思想不能从M去调用 其他的事件…… (使用事件)
        private event UnityAction updateDataEvent;
    
    
        //2、数据相关操作 (初始化……)
        public void Init()
        {
            //初始化数据
            playerLve = PlayerPrefs.GetInt("LevValue", 1);
    
            lev = PlayerPrefs.GetInt("LevValue", 1);
            attackValue = PlayerPrefs.GetInt("AttackValue", 888);
            hp = PlayerPrefs.GetInt("HpValue", 888);
            defense = PlayerPrefs.GetInt("DefenseValue", 888);
        }
    
        //3、更新本地数据
        public void UpLev()
        {
            int add = 50;
    
            playerLve += add;
    
            lev += add;
            attackValue += add;
            hp += add;
            defense += add;
    
            Save();
        }
    
        //4、储存数据
        public void Save()
        {
            PlayerPrefs.SetInt("LevValue", lev);
    
            PlayerPrefs.SetInt("LevValue", lev);
            PlayerPrefs.SetInt("AttackValue", attackValue);
            PlayerPrefs.SetInt("HpValue", hp);
            PlayerPrefs.SetInt("DefenseValue", defense);
    
            UpdateInFo();
        }
    
        //添加事件
        public void AddEvent(UnityAction function)
        {
            updateDataEvent += function;
        }
        //移除事件
        public void RemoveEvent(UnityAction function)
        {
            updateDataEvent -= function;
        }
    
        //使用事件通知外部更新数据
        private void UpdateInFo()
        {
            //第一种写法 👇
            //if (updateDataEvent != null)
            //{
            //    updateDataEvent(this);
            //}
    
            //第二种写法  👇
            updateDataEvent?.Invoke(this);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    3、View

    PlayerGradeView

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    //MVC中的V 👉 1、完成控件的查找  👉 2、提供UI更新的方法给外部
    public class PlayerGradeView : MonoBehaviour
    {
        //1、完成控件的查找
        public Text txtLev;
        public Button playerBut;
    
    
        //2、提供UI更新的方法给外部
        public void UpdateInfo(ModeData modeData)
        {
            txtLev.text = "等级:"+modeData.PlayerLve.ToString();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    PlayerInfoView

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    //MVC中的V 👉 1、完成控件的查找 👉 2、提供UI更新的方法给外部……
    public class PlayerInfoView : MonoBehaviour
    {
        //1、完成控件的查找
        public Text txtLev;
        public Text playerAttack;
        public Text hp;
        public Text defense;
        public Button upgrade;
        public Button hideBag;
    
    
        //2、提供UI更新的方法给外部
        public void UpdateInfo(ModeData modeData)
        {
            txtLev.text = modeData.Lev.ToString();
            playerAttack.text = modeData.AttackValue.ToString();
            hp.text = modeData.Hp.ToString();
            defense.text = modeData.Defense.ToString();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    最后

    在这里插入图片描述

    本文到这里就结束了,大佬们的支持是我们更新的最大动力,希望这篇文章能帮到大家💪

    在这里插入图片描述

    下篇文章再见ヾ( ̄▽ ̄)ByeBye

    在这里插入图片描述

  • 相关阅读:
    小白高效自学-网络安全(黑客技术)
    JS-水果库存记录实现全选全不选功能
    springcloudalibaba架构(6):Sentinel热点规则
    SSM 框架整合
    Nerfies:可变形神经辐射场
    第六章 树与二叉树
    阿里P9大牛徒手编写的这份十亿级并发手册,教你彻底玩懂高并发,赶紧收藏
    随手记录第十一话 -- PHP + yii2 初体验
    【PAT甲级 - C++题解】1112 Stucked Keyboard
    bfs模板总结
  • 原文地址:https://blog.csdn.net/m0_61490399/article/details/126430647