zoukankan      html  css  js  c++  java
  • 仿LOL项目开发第六天

    仿LOL项目开发第六天

                                  by草帽

    OK,因为更新模块已经处理好了,接着开始登陆的编写。那么我们就需要状态机的管理。

    所谓状态机就是在哪个状态执行那个状态的代码逻辑:

    那么我们开始编写GameStateManager来管理:

    我们先在DefineCommon里面定义游戏状态类型:

        /// <summary>
        /// 游戏状态
        /// </summary>
        public enum GameStateType
        {
            GS_Continue,//中间状态,也就是说介于两个状态转换的中间状态
            GS_Login,//登陆状态
            GS_User,//创建用户状态
            GS_Lobby,//大厅,类似于LOL主界面状态
            GS_Room,//创建房间状态
            GS_Hero,//选择英雄
            GS_Loading,//加载状态
            GS_Play,//对战状态
            GS_Over,//对战结束
        }

    有分这么多个状态,如果还有其他状态以后再加:

    然后在GameStateManager里面搞个字典缓存这些状态。这个管理方式和WindowManage十分的相似。

    using UnityEngine;
    using System.Collections.Generic;
    using Game;
    using Game.Common;
    /// <summary>
    /// 游戏状态管理器
    /// </summary>
    public class GameStateManager : Singleton<GameStateManager>
    {
        public Dictionary<GameStateType, IGameState> m_dicGameStates;
        IGameState m_oCurrentState;
    
        public IGameState CurrentState 
        {
            get { return this.m_oCurrentState; }
        }
        public GameStateManager()
        {
            m_dicGameStates = new Dictionary<GameStateType, IGameState>();
            m_dicGameStates.Add(GameStateType.GS_Login, new LoginState());
        }
        /// <summary>
        /// 改变游戏状态
        /// </summary>
        /// <param name="stateType"></param>
        public void ChangeGameStateTo(GameStateType stateType)
        {
            if (m_oCurrentState != null && m_oCurrentState.GetStateType() != GameStateType.GS_Loading && m_oCurrentState.GetStateType() == stateType)
                return;
    
            if (m_dicGameStates.ContainsKey(stateType))
            {
                if (m_oCurrentState != null)
                {
                    m_oCurrentState.Exit();//先退出上个状态
                }
    
                m_oCurrentState = m_dicGameStates[stateType];
                m_oCurrentState.Enter();//进入这个状态
            }
        }
        /// <summary>
        /// 进入默认状态,默认为登陆状态
        /// </summary>
        public void EnterDefaultState()
        {
            ChangeGameStateTo(GameStateType.GS_Login);
        }
        public void FixedUpdate(float fixedDeltaTime)
        {
            if (m_oCurrentState != null)
            {
                m_oCurrentState.FixedUpdate(fixedDeltaTime);
            }
        }
        public void Update(float fDeltaTime)
        {
            GameStateType nextStateType = GameStateType.GS_Continue;
            if (m_oCurrentState != null)
            {
                nextStateType = m_oCurrentState.Update(fDeltaTime);
            }
    
            if (nextStateType > GameStateType.GS_Continue)
            {
                ChangeGameStateTo(nextStateType);
            }
        }
        public IGameState getState(GameStateType type)
        {
            if (!m_dicGameStates.ContainsKey(type))
            {
                return null;
            }
            return m_dicGameStates[type];
        }
    }

    我们抽象出所有的状态公有的方法属性:IGameState接口:

    也符合面向接口编程原则。好处我之前讲过了。

    IGameState:

    using UnityEngine;
    using System.Collections;
    using Game.Common;
    /// <summary>
    /// 游戏状态接口
    /// </summary>
    public interface IGameState
    {
        GameStateType GetStateType();//获取实现类的状态类型
        void SetStateTo(GameStateType gsType);//设置实现类的状态类型(改变状态)
        void Enter();//进入实现类的状态,做主要状态的逻辑处理
        GameStateType Update(float fDeltaTime);//状态改变,返回改变后的状态
        void FixedUpdate(float fixedDeltaTime);//固定更新状态
        void Exit();//退出该状态
    }

    然后编写实现接口的子实现类,这里我们先写LoginState:

    using UnityEngine;
    using System.Collections;
    using Game.Common;
    /// <summary>
    /// 登陆游戏状态
    /// </summary>
    public class LoginState : IGameState
    {
        GameStateType m_eStateTo;
        public LoginState()
        {
     
        }
        public GameStateType GetStateType() 
        {
            return GameStateType.GS_Login;
        }
        public void SetStateTo(GameStateType stateType)
        {
            this.m_eStateTo = stateType;
        }
        public void Enter()
        {
            SetStateTo(GameStateType.GS_Continue);
            LoginCtrl.singleton.Enter();
        }
        public void Exit()
        {
            LoginCtrl.singleton.Exit();
        }
        public void FixedUpdate(float fixedDeltaTime)
        {
     
        }
        public GameStateType Update(float fDeltaTime)
        {
            return m_eStateTo;
        }
    }

    然后在GameStateManager的构造方法,添加到缓存字典里面。

    OK,这个状态机,假如说我们调用GameStateManager的ChangeStateTo(你想要的状态类型),那么就会执行你想要的状态实现类的Enter方法。

    所以我们在LoginState的Enter编写我们登陆的逻辑,因为LoginState主要是管理状态改变的,所以我们为了类的单一职责,吧所有登陆逻辑放在:LoginCtrl控制类里面。

        public void Enter()
        {
            SetStateTo(GameStateType.GS_Continue);//先转到中间状态
            LoginCtrl.singleton.Enter();
        }

    LoginCtrl:

    OK,写到这里,我们之后当我知道版本更新完成或者根本不需要更新,就直接弹出登陆UI的用户名输入框界面。

    那么,我们就得写个LoginWindow来管理登陆UI,所以先写LoginWindow:

    using UnityEngine;
    using System.Collections;
    using Game.Common;
    using Utility;
    using System;
    /// <summary>
    /// 登陆界面UI
    /// </summary>
    public class LoginWindow : BaseWindow 
    {
        public LoginWindow()
        {
            this.mResName = "Guis/LoginWindow";
            this.mResident = false;
        }
        public override void Init()
        {
            EventCenter.AddListener(EGameEvent.eGameEvent_LoginEnter, Show);
            EventCenter.AddListener(EGameEvent.eGameEvent_LoginExit, Hide);
        }
        public override void Realse()
        {
            EventCenter.RemoveListener(EGameEvent.eGameEvent_LoginEnter, Show);
            EventCenter.RemoveListener(EGameEvent.eGameEvent_LoginExit,Hide);
        }
        protected override void InitWidget()
        {
    
        }
        protected override void RealseWidget()
        {
            
        }
        protected override void OnAddListener()
        {
    
        }
        protected override void OnRemoveListener()
        {
            
        }
        public override void OnEnable()
        {
            
        }
        public override void OnDisable()
        {
            
        }
        public override void Update(float deltaTime)
        {
            base.Update(deltaTime);
        }
    }

    OK,我们在LoginWindow里面添加显示登陆界面和隐藏登陆界面事件监听。

    首先,我们知道,玩LOL的时候,当我们登陆成功之后,还要选择游戏大区服务器。所以我们把选择服务器归入到登陆界面来管理。

    所以我们还是需要制作一个SelectServer界面,这里我也随便搞了下界面:

    未完待续。。。。。。没时间以后继续

    OK,终于暑假了,又有时间来写了,隔了好久的时间,我可能落下很多步骤,如果有不明白的童鞋,欢迎在下方留言。

    接着讲,我们选择服务器的界面还没有制作,所以首先我们先来制作这个界面。

    粗略的看下这界面的结构:

    1.背景图片

    2.左边的服务器列表

    3.右边的图标和各个按钮

    4.蓝色的服务器背景

    大致就是这些,OK,我们看下Unity中的Hire窗口物体结构:

    我们着重来看下ServerList的制作,其他的读者可以自行理解,然后搭建起来。

    首先来看下ServerList:

    我将他分为两个部分,第一个部分是上面的推荐服,第二个部分是下面的电信联通具体服。

    制作好之后,吧他拖到Prefabs文件夹下面,然后拖到我们之前做好的登陆界面当做子物体。

    然后把他的Panel设置为不激活状态。因为我们默认进入到登陆界面只显示输入用户名和密码,不显示选择服务器界面。等到我们正确的验证密码之后,然后才进入到选择服务器界面。

    OK,大致的界面讲解完成了,我们开始写代码。在写代码之前,先来分析下看,因为这个服务器动态的,也就是说假如一个服务器进行维护或者繁忙,我们这边应该实时的知道。

    所以,当我们进入到选择服务器界面的时候,应该接收到服务器发送来的服务器实时的数据信息,然后客户端才动态加载这些服务器列表。

    所以我们代码怎么写?怎么样才能做到动态加载不确定数量的服务器列表。这里NGUI的UITable和UIGrid有点坑,我们如果想实例化一个子物体给UITable,他是不会动态刷新的,所以我决定自己再封装一层NGUI的代码,形成自己的一套UI管理。

    我们在Window文件夹下面,新建一个UIObject文件夹,里面存放着所以和UI相关的接口和类,如XUISprite.cs实际上就是封装的NGUi的UISprite脚本。

    可以看到我已经封装了这么多,可能有些童鞋会问了,既然NGui的都可以用,为什么还这么麻烦,自己封装一层。

    这个封装确实很有必要:

    1.方便操作,可以根据我们需要的功能进行扩展。就拿这个UITable来说,如果我们需要实时更新里面的Item,我们每在一处添加,都要得写好多代码,如果我们封装起来,一个方法就搞定。

    2.可扩展性强。可以看到我们每个UI都有自己的一个接口,实现了依赖倒置原则。如果我们想要使用UGUi作为UI框架,我们只需要修改下,底层的代码,高层调用者就不需要改动代码,如果不使用的话,高层要高到死为止。

    好处大致就是这么多。OK,我先来贴贴代码,我把所有的代码贴出来:

    IXUIObject.cs

     

    using UnityEngine;
    using System.Collections;
    /// <summary>
    /// 所有UI物体公共的接口
    /// </summary>
    public interface IXUIObject
    {
        Transform CacheTransform
        {
            get;
        }
        GameObject CacheGameObject
        {
            get;
        }
        IXUIObject Parent
        {
            get;
            set;
        }
        string Tip
        {
            get;
            set;
        }
        object TipParam
        {
            get;
            set;
        }
        bool IsVisible();
        void SetVisible(bool bVisible);
        IXUIObject GetUIObject(string strPath);
        void Highlight(bool bTrue);
    }

    XUIObjectBase.cs:

     

    using UnityEngine;
    using System.Collections;
    /// <summary>
    /// 继承MOnoBehavior的UI物体
    /// </summary>
    public abstract class XUIObjectBase : MonoBehaviour,IXUIObject 
    {
        private bool m_bInit = false;
        public string m_strTipText = "";
        protected float m_fAlpha = 1f;
        private Transform m_cacheTransform;
        private GameObject m_cacheGameObject;
        private IXUIObject m_parent;
        public Transform CacheTransform
        {
            get 
            {
                if (this.m_cacheTransform == null) 
                {
                    this.m_cacheTransform = base.transform;
                }
                return this.m_cacheTransform;
            }
        }
        public GameObject CacheGameObject
        {
            get 
            {
                if (this.m_cacheGameObject == null)
                {
                    this.m_cacheGameObject = base.gameObject;
                }
                return this.m_cacheGameObject;
            }
        }
        public object TipParam
        {
            get;
            set;
        }
        public string Tip 
        {
            get { return this.m_strTipText; }
            set { this.m_strTipText = value; }
        }
        public virtual float Alpha 
        {
            get 
            {
                return this.m_fAlpha;
            }
            set 
            {
                this.m_fAlpha = value;
            }
        }
        public virtual IXUIObject Parent 
        {
            get 
            {
                return this.m_parent;
            }
            set 
            {
                this.m_parent = value;
            }
        }
        public bool IsInited 
        {
            get { return this.m_bInit; }
            set { this.m_bInit = value; }
        }
        public virtual void Init()
        {
            this.m_bInit = true;
        }
        public bool IsVisible()
        {
            return base.gameObject.activeInHierarchy;
        }
        public virtual void SetVisible(bool bVisible)
        {
    
        }
        public virtual void Highlight(bool bTrue)
        {
     
        }
        public virtual IXUIObject GetUIObject(string strPath) 
        {
            return null;
        }
        public virtual void OnAwake()
        {
    
        }
        public virtual void OnStart()
        {
     
        }
        public virtual void OnUpdate()
        {
     
        }
        public virtual void _OnClick()
        {
     
        }
        private void Awake()
        {
            OnAwake();
        }
        private void Start()
        {
            if (!this.m_bInit)
            {
                Init();
            }
            OnStart();
        }
        private void Update()
        {
            OnUpdate();
        }
        private void OnClick()
        {
            this._OnClick();
        }
        private void OnEnable()
        {
     
        }
        private void OnDisable()
        {
     
        }
    }

    这个脚本是每个UI必须的,比如NGUi的脚本都是挂在UI物体上的。所以我们自己封装的脚本也是如此。

    注意到没有中间有用到:

    TipParam:这个是提示参数类

     

    using UnityEngine;
    using System.Collections;
    using Game.Common;
    /// <summary>
    /// 提示参数类
    /// </summary>
    public class TipParam 
    {
        //提示信息
        public string Tip
        {
            get;
            set;
        }
        //提示类型,有普通提示(技能装备等)和标题提示(没有带复杂内容,只有一行字)
        public TipEnumType TipType
        {
            get;
            set;
        }
        public TipParam()
        {
            TipType = TipEnumType.eTipType_Common;
        }
    }

    这个主要是处理界面提示用的。

    XUIObject.cs:

     

    using UnityEngine;
    using System.Collections;
    
    public abstract class XUIObject : XUIObjectBase
    {
        public override void OnAwake()
        {
            base.OnAwake();
        }
        public override void OnStart()
        {
            base.OnStart();
        }
        public override void OnUpdate()
        {
            base.OnUpdate();
        }
        public override void Init()
        {
            base.Init();
        }
        public override void SetVisible(bool bVisible)
        {
            NGUITools.SetActiveSelf(base.gameObject, bVisible);
        }
    }

    OK,我们开始写具体的UI类:先写UIList和UIListItem也就是Table或者Grid他对应着UIList,他下面的子物体对应着UIListItem。

    由于UIListItem可能他的子物体有UISprite和UILabel等等,所以我们在写他之前先写UISprite:

    因为我们写程序最好要依赖接口编程,所以写个IXUISprite接口:

     

    using UnityEngine;
    using System.Collections;
    
    public interface IXUISprite : IXUIObject
    {
        Color Color
        {
            get;
            set;
        }
        string SpriteName
        {
            get;
        }
        IXUIAtlas UIAtlas
        {
            get;
        }
        /// <summary>
        /// 播放UI动画
        /// </summary>
        /// <param name="bLoop"></param>
        /// <returns></returns>
        bool PlayFlash(bool bLoop);
        void SetEnable(bool bEnable);
        /// <summary>
        /// 设置UISprite
        /// </summary>
        /// <param name="strSpriteName"></param>
        /// <returns></returns>
        bool SetSprite(string strSpriteName);
        bool SetSprite(string strSpriteName, string strAtlas);
        /// <summary>
        /// 停止UI动画
        /// </summary>
        /// <returns></returns>
        bool StopFlash();
    }  

     

     注意到没有,我们Sprite可能会用到UIAtlas,所以我们得再写个UIAtlas:

    IXUIAtlas:

     

    using UnityEngine;
    using System.Collections;
    public interface IXUIAtlas
    {   
        UIAtlas Atlas
        {
            get;
            set;
        }
    }

    XUIAtlas:

     

    using UnityEngine;
    using System.Collections;
    
    public class XUIAtlas : MonoBehaviour,IXUIAtlas
    {
        private UIAtlas m_uiAtlas;
        public UIAtlas Atlas 
        {
            get
            {
                return this.m_uiAtlas;
            }
            set
            {
                this.m_uiAtlas = value;
            }
        }
        private void Awake()
        {
            this.m_uiAtlas = base.GetComponent<UIAtlas>();
            if (null == this.m_uiAtlas)
            {
                Debug.LogError("null == m_uiAtlas");
            }
        }
    }

    XUISprite:

     

    using UnityEngine;
    using System.Collections;
    using Game.Common;
    [AddComponentMenu("XUI/XUISprite")]
    public class XUISprite : XUIObject,IXUIObject,IXUISprite
    {
        private string m_spriteNameCached = string.Empty;
        private string m_atlasNameCached = string.Empty;
        private UISprite m_uiSprite;
        private UISpriteAnimation m_uiSpriteAnimation;
        private ResourceUnit m_oAltasUnit;
        private IXLog m_log = XLog.GetLog<XUISprite>();
        public override float Alpha
        {
            get
            {
                if (null != this.m_uiSprite)
                {
                    return this.m_uiSprite.alpha;
                }
                return 0f;
            }
            set
            {
                if (null != this.m_uiSprite)
                {
                    this.m_uiSprite.alpha = value;
                }
            }
        }
        public Color Color 
        {
            get 
            {
                if (this.m_uiSprite != null)
                {
                    return this.m_uiSprite.color;
                }
                return Color.white;
            }
            set 
            {
                if (this.m_uiSprite != null)
                {
                    this.m_uiSprite.color = value;
                }
            }
        }
        public string SpriteName
        {
            get
            {
                if (null != this.m_uiSprite)
                {
                    return this.m_uiSprite.spriteName;
                }
                return null;
            }
        }
        public IXUIAtlas UIAtlas 
        {
            get 
            {
                if (null == this.m_uiSprite)
                {
                    return null;
                }
                if (null == this.m_uiSprite.atlas)
                {
                    return null;
                }
                return this.m_uiSprite.atlas.GetComponent<XUIAtlas>();
            }
        }
    
    
        public override void Init()
        {
            base.Init();
            this.m_uiSprite = base.GetComponent<UISprite>();
            if (null == this.m_uiSprite)
            {
                Debug.LogError("null == m_uiSprite");
            }
            this.m_uiSpriteAnimation = base.GetComponent<UISpriteAnimation>();
        }
        /// <summary>
        /// 播放动画
        /// </summary>
        /// <param name="bLoop"></param>
        /// <returns></returns>
        public bool PlayFlash(bool bLoop)
        {
            if (null == this.m_uiSpriteAnimation)
            {
                return false;
            }
            this.m_uiSpriteAnimation.loop = bLoop;
            this.m_uiSpriteAnimation.ResetToBeginning();
            this.m_uiSpriteAnimation.enabled = true;
            this.m_uiSprite.enabled = true;
            return true;
        }
        /// <summary>
        /// 停止动画
        /// </summary>
        /// <returns></returns>
        public bool StopFlash()
        {
            if (null == this.m_uiSpriteAnimation)
            {
                return false;
            }
            this.m_uiSpriteAnimation.enabled = false;
            return true;
        }
        /// <summary>
        /// 设置UISprite
        /// </summary>
        /// <param name="strSprite"></param>
        /// <param name="strAltas"></param>
        /// <returns></returns>
        public bool SetSprite(string strSprite, string strAltas)
        {
            if (null == this.m_uiSprite)
            {
                return false;
            }
            //如果缓存图集已经存在了,那么就直接设置
            if (this.m_atlasNameCached.Equals(strAltas))
            {
                this.m_spriteNameCached = strSprite;
                this.m_uiSprite.spriteName = strSprite;
                this.m_uiSprite.enabled = true;
                return true;
            }
            this.m_spriteNameCached = strSprite;
            this.m_atlasNameCached = strAltas;
            this.PrepareAtlas(strAltas, strSprite);
            return true;
        }
        /// <summary>
        /// 设置默认图集的UISprite
        /// </summary>
        /// <param name="strSpriteName"></param>
        /// <returns></returns>
        public bool SetSprite(string strSpriteName)
        {
            if (null == this.m_uiSprite)
            {
                return false;
            }
            if (!string.IsNullOrEmpty(this.m_atlasNameCached))
            {
                this.SetSprite(this.m_atlasNameCached, strSpriteName);
            }
            else 
            {
                this.m_uiSprite.spriteName = strSpriteName;
            }
            return true;
        }
        public void SetEnable(bool bEnable)
        {
            Collider compent = base.GetComponent<Collider>();
            if (compent != null)
            {
                compent.enabled = bEnable;
            }
        }
        private void OnDestroy()
        {
            if (this.m_oAltasUnit != null)
            {
                this.m_oAltasUnit.Dispose();
                this.m_oAltasUnit = null;
            }
        }
        private void PrepareAtlas(string strAltas, string strSprite)
        {
            m_oAltasUnit = ResourceManager.Instance.LoadImmediate(strAltas, ResourceType.PREFAB);
            GameObject obj = m_oAltasUnit.Asset as GameObject;
            UIAtlas uiAtals = obj.GetComponent<UIAtlas>();
            if (null == uiAtals)
            {
                this.m_log.Error("加载图集的时候出错!!");
                return;
            }
            this.m_uiSprite.atlas = uiAtals;
            this.m_uiSprite.spriteName = strSprite;
            this.m_uiSprite.enabled = true;
        }
    }

    可以看到XUISprite提供4个主要接口:

    1.SetSprite(string strSpriteName)---->设置Sprite,在默认的Alta中

    2.SetSprite(string strSpriteName,string strAtlas)---->设置Sprite,在指定的Atlas中

    3.PlayFlash(bool bLoop)---->是否播放UI帧动画

    4.StopFlash()----->停止播放UI帧动画

    写完Sprite之后,我们写

    IXUIListItem:

     

    using UnityEngine;
    using System.Collections.Generic;
    public interface IXUIListItem :IXUIObject
    {
        int Id
        {
            get;
            set;
        }
        long GUID
        {
            get;
            set;
        }
        int Index
        {
            get;
            set;
        }
        bool IsSelected
        {
            get;
            set;
        }
        Dictionary<string, XUIObjectBase> AllXUIObject
        {
            get;
        }
        bool SetText(string strId,string strContent);
        void SetSelected(bool bTrue);
        void SetEnableSelect(bool bEnable);
        void SetIconSprite(string strSprite);
        void SetIconSprite(string strSprite, string strAtlas);
        void SetIconTexture(string strTexture);
        void SetColor(Color color);
        void SetEnable(bool bEnable);
        void Clear();
    }

    XUIListItem.cs:

     

    using UnityEngine;
    using System.Collections.Generic;
    using UILib;
    using Game.Common;
    [AddComponentMenu("XUI/XUIListItem")]
    public class XUIListItem : XUIObject,IXUIObject,IXUIListItem
    {
        private UISprite m_uiSpriteIcon;
        private UILabel[] m_uiLabels;
        private UITexture m_uiTextureIcon;
        private UIButton m_uiButton;
        private UIToggle m_uiToggle;
        private UITexture[] m_uiTextures;
        private UISprite[] m_uiSprites;
        private XUISprite m_uiSpriteFlash;
        private Dictionary<string, XUIObjectBase> m_dicId2UIObject = new Dictionary<string, XUIObjectBase>();
        protected Collider m_colldier;
        private Color m_highlightColor = Color.clear;
        public int m_unId;
        private int m_unIndex = -1;
        private long m_GUID;
    
    
        public int Id 
        {
            get { return this.m_unId; }
            set 
            { 
                this.m_unId = value;
            }
        }
        public int Index 
        {
            get { return this.m_unIndex; }
            set { this.m_unIndex = value; }
        }
        public long GUID 
        {
            get { return this.m_GUID; }
            set { this.m_GUID = value; }
        }
        public XUIList ParentXUIList 
        {
            get 
            {
                XUIList xUIlist = this.Parent as XUIList;
                if (null == xUIlist)
                {
                    Debug.LogError("null == uiList");
                }
                return xUIlist;
            }
        }
        public bool IsSelected 
        {
            get 
            {
                return this.m_uiToggle != null && this.m_uiToggle.value;
            }
            set
            {
                if (this.m_uiToggle != null && this.m_uiToggle.value != value)
                {
                    this.m_uiToggle.Set(value);
                    if (value)
                    {
                        this.ParentXUIList.SelectItem(this, false);
                    }else
                    {
                        this.ParentXUIList.UnSelectItem(this, false);
                    }
                }
            }
        }
        public Dictionary<string, XUIObjectBase> AllXUIObject
        {
            get { return this.m_dicId2UIObject; }
        }
    
        public void SetSelected(bool bTrue)
        {
            if (this.m_uiToggle != null && this.m_uiToggle.value != bTrue)
            {
                this.m_uiToggle.Set(bTrue);
            }
        }
        public void SetEnableSelect(bool bEnable)
        {
            if (!bEnable && this.m_uiToggle != null)
            {
                this.m_uiToggle.value = false;
            }
            this.Highlight(bEnable);
            if (this.m_uiToggle != null)
            {
                this.m_uiToggle.enabled = bEnable;
            }
        }
        private void OnSelectStateChange()
        {
            bool bSelected = this.m_uiToggle.value;
            if (bSelected)
            {
                //List选择该item
                this.ParentXUIList.OnSelectItem(this);
            }
            else 
            {
                //List不选择该item
                this.ParentXUIList.OnUnSelectItem(this);
            }
        }
        public void SetIconSprite(string strSprite)
        {
            if (null != this.m_uiSpriteIcon)
            {
                this.m_uiSpriteIcon.spriteName = strSprite.Substring(strSprite.LastIndexOf("\") + 1);
                this.m_uiSpriteIcon.enabled = true;
            }
            XUISprite xUISprite = this.GetUIObject("Sprite_Icon") as XUISprite;
            if (null != xUISprite)
            {
                xUISprite.SetSprite(strSprite);
            }
        }
        public void SetIconSprite(string strSprite, string strAtlas)
        {
            XUISprite xUISprite = this.GetUIObject("Sprite_Icon") as XUISprite;
            if (null != xUISprite)
            {
                xUISprite.SetSprite(strSprite, strAtlas);
            }
        }
        public void SetIconTexture(string strTexture)
        {
            XUITexture xUITexture = this.GetUIObject("Texture_Icon") as XUITexture;
            if (xUITexture != null)
            {
                xUITexture.SetTexture(strTexture);
            }
        }
        public bool SetText(string strId, string strText)
        {
            IXUILabel label = this.GetUIObject(strId) as IXUILabel;
            if (label != null)
            {
                label.SetText(strText);
                return true;
            }
            return false;
        }
        public void SetColor(Color color)
        {
            if (this.m_uiSpriteIcon != null)
            {
                this.m_uiSpriteIcon.color = color;
            }
            if (this.m_uiTextureIcon != null)
            {
                this.m_uiTextureIcon.color = color;
            }
        }
        public void SetEnable(bool bEnable)
        {
            if (this.m_colldier != null)
            {
                this.m_colldier.enabled = bEnable;
            }
            if (this.m_uiButton != null)
            {
                this.m_uiButton.enabled = bEnable;
            }
        }
        public void Clear()
        {
            this.m_unId = 0;
            UILabel[] uiLabels = this.m_uiLabels;
            for (int i = 0; i < uiLabels.Length; i++)
            {
                UILabel uILabel = uiLabels[i];
                uILabel.text = string.Empty;
            }
            if (null != this.m_uiSpriteIcon)
            {
                this.m_uiSpriteIcon.enabled = false;
            }
            if (null != this.m_uiTextureIcon)
            {
                this.m_uiTextureIcon.enabled = false;
            }
            this.Tip = string.Empty;
            this.TipParam = null;
        }
        public override void Init()
        {
            base.Init();
            WidgetFactory.FindAllUIObjects(base.transform, this, ref m_dicId2UIObject);
            foreach (var uiObject in this.m_dicId2UIObject.Values)
            {
                uiObject.Parent = this;
                if (!uiObject.IsInited)
                {
                    uiObject.Init();
                }
            }
            if (null == this.m_uiSpriteIcon)
            {
                Transform tran = base.transform.FindChild("Sprite_Icon");
                if (tran != null)
                {
                    this.m_uiSpriteIcon = tran.GetComponent<UISprite>();
                }
            }
            if (null == this.m_uiTextureIcon)
            {
                Transform tran1 = base.transform.FindChild("Texture_Icon");
                if (tran1 != null)
                {
                    this.m_uiTextureIcon = tran1.GetComponent<UITexture>();
                }
            }
            this.m_colldier = base.GetComponent<Collider>();
            this.m_uiLabels = base.GetComponentsInChildren<UILabel>();
            this.m_uiToggle = base.GetComponent<UIToggle>();
            this.m_uiButton = base.GetComponent<UIButton>();
            this.m_uiSprites = base.GetComponentsInChildren<UISprite>(true);
            this.m_uiTextures = base.GetComponentsInChildren<UITexture>(true);
            this.m_uiSpriteFlash = this.GetUIObject("Sprite_Flash") as XUISprite;
            if (this.m_uiToggle != null)
            {
                EventDelegate.Add(this.m_uiToggle.onChange, this.OnSelectStateChange);
            }
            this.Highlight(false);
        }
        public override IXUIObject GetUIObject(string strPath)
        {
            if (strPath == null)
            {
                return null;
            }
            string key = strPath;
            int num = strPath.LastIndexOf('/');
            if (num >= 0)
            {
                key = strPath.Substring(num + 1);
            }
            XUIObjectBase result = null;
            if (this.m_dicId2UIObject.TryGetValue(key, out result))
            {
                return result;
            }
            return null;
        }
        public override void Highlight(bool bTrue)
        {
            base.Highlight(bTrue);
            if (this.m_uiSpriteFlash != null)
            {
                if (!bTrue)
                {
                    this.m_uiSpriteFlash.StopFlash();
                }
                else 
                {
                    this.m_uiSpriteFlash.PlayFlash(true);
                }
            }
        }
        public override void _OnClick()
        {
            base._OnClick();
            this.ParentXUIList._OnClick(this);
        }
    }

    注意了,细心的童鞋可能看到,这个Item他的子物体假如是Sprite,那么他的命名必须是:

    Sprite_Icon

    如果子物体是Texture,那么命名必须是:

    Texture_Icon

    如果子物体是有带动画的Sprite,必须命名为:

    Sprite_Flash

    还有如果这个Item是可以选择的,必须添加UIToggle脚本,具体读者自己看代码。OK,接着我们写

    IXUIList:

     

    using UnityEngine;
    using System.Collections.Generic;
    using Game.Common;
    public interface IXUIList : IXUIObject
    {
        int Count
        {
            get;
        }
        int GetSelectedIndex();
        void SetSelectedIndex(int nIndex);
        void SetSelectedItemByIndex(List<int> listItemIndex);
        void SetSelectedItemById(int unId);
        void SetSelectedItemById(List<int> listItemId);
        IXUIListItem GetSelectedItem();
        IXUIListItem[] GetSelectedItems();
        IXUIListItem GetItemById(int unId, bool bVisible);
        IXUIListItem GetItemByGUID(long ulId);
        IXUIListItem[] GetAllItems();
        IXUIListItem GetItemByIndex(int nIndex);
        IXUIListItem AddListItem(GameObject obj);
        IXUIListItem AddListItem();
        bool DelItemById(int unId);
        bool DelItemByIndex(int nIndex);
        bool DelItem(IXUIListItem iUIListItem);
        void SetEnable(bool bEnable);
        void SetEnableSelect(bool bEnable);
        void SetEnableSelect(List<int> listIds);
        void Highlight(List<int> listIds);
        void Refresh();
        void OnSelectItem(XUIListItem listItem);
        void SelectItem(XUIListItem listItem, bool bTrigerEvent);
        void OnUnSelectItem(XUIListItem listItem);
        void UnSelectItem(XUIListItem listItem, bool bTrigerEvent);
        void RegisterListOnSelectEventHandler(ListSelectEventHandler handler);
        void RegisterListOnUnSelectEventHandler(ListSelectEventHandler handler);
        void RegisterListOnClickEventHandler(ListOnClickEventHandler handler);
        void Clear();
    }
    

     

    可能会有出错,因为我们ListSelectEventHandler委托类型还没有声明,我们到DefineCommon中定义这两个委托类型:

     

    public delegate bool ListSelectEventHandler(IXUIListItem listItem);
    public delegate bool ListOnClickEventHandler(IXUIListItem listItem);
    

     

    XUIList.cs:

    using UnityEngine;
    using System.Collections.Generic;
    using System;
    using Game.Common;
    [AddComponentMenu("XUI/XUIList")]
    public class XUIList : XUIObject, IXUIObject,IXUIList
    {
        public GameObject m_prefabListItem;
        public bool m_bMultiSelect;
        private bool m_bHasAddItem;
        private List<XUIListItem> m_listXUIListItem = new List<XUIListItem>();
        private List<XUIListItem> m_listXUIListItemSelected = new List<XUIListItem>();
        private ListSelectEventHandler m_eventhandlerOnSelect;
        private ListSelectEventHandler m_eventhandlerOnUnSelect;
        private ListOnClickEventHandler m_eventhandlerOnClick;
        private UIGrid m_uiGrid;
        private UITable m_uiTable;
        public int Count 
        {
            get
            {
                if (null == this.m_listXUIListItem)
                {
                    return 0;
                }
                return this.m_listXUIListItem.Count;
            }
        }
    
        public override void Init()
        {
            base.Init();
            this.m_listXUIListItem.Clear();
            this.m_listXUIListItemSelected.Clear();
            for (int i = 0; i < base.transform.childCount; i++)
            {
                Transform child = base.transform.GetChild(i);
                XUIListItem component = child.GetComponent<XUIListItem>();
                if (component == null)
                {
                    Debug.LogError("null == uiListitem");
                }
                else 
                {
                    component.Parent = this;
                    this.m_listXUIListItem.Add(component);
                }
                this.m_listXUIListItem.Sort(new Comparison<XUIListItem>(XUIList.SortByName));
                int num = 0;
                foreach (XUIListItem current in this.m_listXUIListItem)
                {
                    current.name = string.Format("{0:0000}", num);
                    current.Index = num;
                    current.Id = num;
                    if (!current.IsInited)
                    {
                        current.Init();
                    }
                    UIToggle component2 = current.GetComponent<UIToggle>();
                    if (current.IsSelected)
                    {
                        this.m_listXUIListItemSelected.Add(current);
                    }
                    num++;
                }
                this.m_uiGrid = base.GetComponent<UIGrid>();
                if (null != this.m_uiGrid)
                {
                    this.m_uiGrid.Reposition();
                }
                this.m_uiTable = base.GetComponent<UITable>();
                if (null != this.m_uiTable)
                {
                    this.m_uiTable.Reposition();
                }
            }
        }
        public int GetSelectedIndex()
        {
            if (this.m_listXUIListItemSelected.Count > 0)
            {
                return this.m_listXUIListItemSelected[0].Index;
            }
            return -1;
        }
        public void SetSelectedIndex(int nIndex)
        {
            XUIListItem selectedItem = this.GetItemByIndex(nIndex) as XUIListItem;
            this.SetSelectedItem(selectedItem);
            //this.FocusIndex(nIndex);
        }
        public void SetSelectedItemByIndex(List<int> listItemIndex)
        {
            if (this.m_bMultiSelect)
            {
                this.m_listXUIListItemSelected.Clear();
                foreach (XUIListItem current in this.m_listXUIListItem)
                {
                    if (listItemIndex != null && listItemIndex.Contains(current.Index))
                    {
                        current.SetSelected(true);
                        this.m_listXUIListItemSelected.Add(current);
                    }
                    else
                    {
                        current.SetSelected(false);
                    }
                }
            }
            else
            {
                Debug.LogError("false == m_bMultiSelect");
            }
        }
        public void SetSelectedItemById(int unId)
        {
            XUIListItem selectedItem = this.GetItemById(unId) as XUIListItem;
            this.SetSelectedItem(selectedItem);
        }
        public void SetSelectedItemById(List<int> listItemId)
        {
            if (this.m_bMultiSelect)
            {
                this.m_listXUIListItemSelected.Clear();
                foreach (XUIListItem current in this.m_listXUIListItem)
                {
                    if (listItemId != null && listItemId.Contains(current.Id))
                    {
                        current.SetSelected(true);
                        this.m_listXUIListItemSelected.Add(current);
                    }
                    else
                    {
                        current.SetSelected(false);
                    }
                }
            }
            else
            {
                Debug.LogError("false == m_bMultiSelect");
            }
        }
        public void SetSelectedItem(XUIListItem uiListItem)
        {
            foreach (XUIListItem current in this.m_listXUIListItemSelected)
            {
                current.SetSelected(false);
            }
            this.m_listXUIListItemSelected.Clear();
            if (null != uiListItem)
            {
                uiListItem.SetSelected(true);
                this.m_listXUIListItemSelected.Add(uiListItem);
            }
        }
        public IXUIListItem GetItemByIndex(int nIndex)
        {
            if (this.m_listXUIListItem == null)
            {
                return null;
            }
            if (0 > nIndex || nIndex >= this.m_listXUIListItem.Count)
            {
                return null;
            }
            return this.m_listXUIListItem[nIndex];
        }
        public IXUIListItem GetSelectedItem()
        {
            if (this.m_listXUIListItemSelected.Count > 0)
            {
                return this.m_listXUIListItemSelected[0];
            }
            return null;
        }
        public IXUIListItem[] GetSelectedItems()
        {
            return this.m_listXUIListItemSelected.ToArray();
        }
        public IXUIListItem GetItemById(int unId)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                if (unId == current.Id)
                {
                    return current;
                }
            }
            return null;
        }
        public IXUIListItem GetItemById(int unId, bool bVisible)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                if (unId == current.Id && current.IsVisible() == bVisible)
                {
                    return current;
                }
            }
            return null;
        }
        public IXUIListItem GetItemByGUID(long ulId)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                if (ulId == current.GUID)
                {
                    return current;
                }
            }
            return null;
        }
        public IXUIListItem[] GetAllItems()
        {
            return this.m_listXUIListItem.ToArray();
        }
        public IXUIListItem AddListItem(GameObject obj)
        {
            if (null == obj)
            {
                return null;
            }
            GameObject gameObject = UnityEngine.Object.Instantiate(obj) as GameObject;
            gameObject.name = string.Format("{0:0000}", this.Count);
            gameObject.transform.parent = base.transform;
            gameObject.transform.localPosition = Vector3.zero;
            gameObject.transform.localScale = Vector3.one;
            gameObject.transform.localRotation = Quaternion.identity;
            NGUITools.SetLayer(gameObject, this.CacheGameObject.layer);
            UIToggle component = gameObject.GetComponent<UIToggle>();
            XUIListItem xUIListItem = gameObject.GetComponent<XUIListItem>();
            if (null == xUIListItem)
            {
                //Debug.LogError("null == uiListItem");
                xUIListItem = gameObject.AddComponent<XUIListItem>();
            }
            xUIListItem.Index = this.Count;
            xUIListItem.Id = xUIListItem.Index;
            xUIListItem.Parent = this;
            if (!xUIListItem.IsInited)
            {
                xUIListItem.Init();
            }
            this.m_listXUIListItem.Add(xUIListItem);
            this.m_bHasAddItem = true;
            this.Refresh();
            return xUIListItem;
        }
        public IXUIListItem AddListItem()
        {
            if (null != this.m_prefabListItem)
            {
                return this.AddListItem(this.m_prefabListItem);
            }
            return null;
        }
        public bool DelItemById(int unId)
        {
            IXUIListItem itemById = this.GetItemById(unId);
            return this.DelItem(itemById);
        }
        public bool DelItemByIndex(int nIndex)
        {
            IXUIListItem itemByIndex = this.GetItemByIndex(nIndex);
            return this.DelItem(itemByIndex);
        }
        public bool DelItem(IXUIListItem iUIListItem)
        {
            XUIListItem xUIListItem = iUIListItem as XUIListItem;
            if (null == xUIListItem)
            {
                return false;
            }
            this.m_listXUIListItemSelected.Remove(xUIListItem);
            int index = xUIListItem.Index;
            for (int i = index + 1; i < this.Count; i++)
            {
                this.m_listXUIListItem[i].name = string.Format("{0:0000}", i - 1);
                this.m_listXUIListItem[i].Index = i - 1;
            }
            this.m_listXUIListItem.Remove(xUIListItem);
            xUIListItem.gameObject.transform.parent = null;
            UnityEngine.Object.Destroy(xUIListItem.gameObject);
            this.Refresh();
            return true;
        }
        public void Clear()
        {
            if (this.m_listXUIListItem == null)
            {
                return;
            }
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                current.gameObject.transform.parent = null;
                UnityEngine.Object.Destroy(current.gameObject);
            }
            this.m_listXUIListItemSelected.Clear();
            this.m_listXUIListItem.Clear();
            this.Refresh();
        }
        public void SetEnable(bool bEnable)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                current.SetEnable(bEnable);
            }
        }
        public void SetEnableSelect(bool bEnable)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                current.SetEnableSelect(bEnable);
            }
            if (!bEnable)
            {
                this.m_listXUIListItemSelected.Clear();
            }
        }
        public void SetEnableSelect(List<int> listIds)
        {
            if (listIds == null)
            {
                return;
            }
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                if (listIds.Contains(current.Id))
                {
                    current.SetEnableSelect(true);
                }
                else
                {
                    current.SetEnableSelect(false);
                }
            }
            this.m_listXUIListItemSelected.RemoveAll((XUIListItem x) => !listIds.Contains(x.Id));
        }
        public override void Highlight(bool bTrue)
        {
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                current.Highlight(bTrue);
            }
        }
        public void Highlight(List<int> listIds)
        {
            this.Highlight(false);
            if (listIds == null)
            {
                return;
            }
            foreach (XUIListItem current in this.m_listXUIListItem)
            {
                if (listIds.Contains(current.Id))
                {
                    current.Highlight(true);
                }
            }
        }
        public void Refresh()
        {
            if (null != this.m_uiGrid)
            {
                this.m_uiGrid.repositionNow = true;
            }
            if (null != this.m_uiTable)
            {
                this.m_uiTable.repositionNow = true;
            }
            this.RefreshAllItemStatus();
        }
        public void OnSelectItem(XUIListItem listItem)
        {
            this.SelectItem(listItem, true);
        }
        public void SelectItem(XUIListItem listItem, bool bTrigerEvent)
        {
            if (null == listItem)
            {
                return;
            }
            if (this.m_listXUIListItemSelected.Contains(listItem))
            {
                return;
            }
            if (!this.m_bMultiSelect)
            {
                this.m_listXUIListItemSelected.Clear();
            }
            this.m_listXUIListItemSelected.Add(listItem);
            //触发选择委托
            if (bTrigerEvent && this.m_eventhandlerOnSelect != null)
            {
                this.m_eventhandlerOnSelect(listItem);
            }
        }
        public void OnUnSelectItem(XUIListItem listItem)
        {
            this.UnSelectItem(listItem, true);
        }
        public void UnSelectItem(XUIListItem listItem, bool bTrigerEvent)
        {
            if (null == listItem)
            {
                return;
            }
            if (!this.m_listXUIListItemSelected.Contains(listItem))
            {
                return;
            }
            this.m_listXUIListItemSelected.Remove(listItem);
            //不选择委托
            if (bTrigerEvent && this.m_eventhandlerOnUnSelect != null)
            {
                this.m_eventhandlerOnUnSelect(listItem);
            }
        }
        public void RegisterListOnSelectEventHandler(ListSelectEventHandler handler)
        {
            this.m_eventhandlerOnSelect = handler;
        }
        public void RegisterListOnUnSelectEventHandler(ListSelectEventHandler handler)
        {
            this.m_eventhandlerOnUnSelect = handler;
        }
        public void RegisterListOnClickEventHandler(ListOnClickEventHandler handler)
        {
            this.m_eventhandlerOnClick = handler;
        }
        public void _OnClick(XUIListItem item)
        {
            if (this.GetSelectedIndex() != item.Index)
            {
                this.SelectItem(item, false);
            }
            if (this.m_eventhandlerOnClick != null)
            {
                this.m_eventhandlerOnClick(item);
            }
        }
        public static int SortByName(XUIListItem a, XUIListItem b)
        {
            return string.Compare(a.name, b.name);
        }
        private void RefreshAllItemStatus()
        {
            int num = this.GetSelectedIndex();
            if (num < 0)
            {
                this.SetSelectedIndex(0);
            }
        }
    }
    

      

    可以看都XUIList封装了好多处理Item的方法,具体的读者可以自行阅读代码,这里我们只需要知道怎么用就行了。

    OK,封装好了之后,我们回到UI界面,把我们自己定义的这些组件添加到对应的UI组件中。

    这里我们电信的Grid,我添加自己定义的XUIList组件。

    然后他的子物体Item,我添加了XUIListItem组件和UIToggle组件。

    然后将Item拖到Prefab当成预制物,然后到XUiList中设置Prefab ListItem变量为这个预制物。可以看上图的XUIList我已经添加了。

    这个Prefab ListItem有什么用呢?

    这要是我们动态添加item的时候,他就会实例化这个预制物。也就是我们前提设置好要动态添加的item。

    OK,其他的组件自己自行添加。

    同理,联通的那个UIGrid也是类似的。讲完这个自己封装的UI框架,我们继续回到游戏主题。

    开始写LoginWindow.cs

    这节一多,下节继续。。。。。。

  • 相关阅读:
    位运算操作
    C 动态分配内存
    数据查询语言 DQL
    数据操纵语言 ,DML, 增删改
    Convert Sorted List to Binary Search Tree
    Longest Consecutive Sequence
    Binary Tree Postorder Traversal
    Triangle
    4Sum
    3Sum Closest
  • 原文地址:https://www.cnblogs.com/CaomaoUnity3d/p/5487343.html
Copyright © 2011-2022 走看看