仿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

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

 

posted @ 2016-05-12 21:09  草帽领  阅读(1570)  评论(3编辑  收藏  举报