仿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

這節一多,下節繼續。。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM