https://github.com/Coding-w-Art/ManGodSkyGroup


QQ截图20160130140148.png

某一年年会前,公司组织了一次游戏马拉松活动,要求是在 48H 内做一个可以游玩的游戏,要有原创性,创新点和核心的玩法,还要包含公司的元素。时间段任务重,很快就决定了需要在现有成熟的玩法进行修改。

给项目起名叫男神天团(Man God Sky Group),那就放出来游戏里的男神角色:三个老板 辟邪 镇楼:

tex_heiyi_1.png

tex_weifeng_1.png

tex_bingge_1.png

游戏的核心玩法就是双人版别踩白块,两个玩家选择角色后,消去一块后,对应的角色向前移动一步,最先移动到重点的玩家获胜。

我的分工是别踩白块的游戏逻辑和界面表现部分。其他还有角色设计、角色移动表现、结算、联机功能、排行榜等由其他人负责。由于是现有项目魔改,所以使用了现有项目的服务器,新添加了消息进行双方进度的同步。

砖块的核心逻辑:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class UIBlock : MonoBehaviour
{
    public UILabel m_kSkillCount;

    public UITexture[] m_kTexLine_0;
    public UITexture[] m_kTexLine_1;
    public UITexture[] m_kTexLine_2;
    public UITexture[] m_kTexLine_3;
    public UITexture[] m_kTexLine_4;
    public UITexture[] m_kTexLine_5;
    public UITexture[] m_kTexLine_6;
    public UITexture[] m_kTexLine_7;
    public UITexture[] m_kTexLine_8;

    public GameObject m_kLine_0;
    public GameObject m_kLine_1;
    public GameObject m_kLine_2;
    public GameObject m_kLine_3;
    public GameObject m_kLine_4;
    public GameObject m_kLine_5;
    public GameObject m_kLine_6;
    public GameObject m_kLine_7;
    public GameObject m_kLine_8;

    public UIMain m_kMainUI;
    public UISprite m_kComboProgress;
    public GameObject m_kTexSkill;
    
    public int[] Key = { (int)KeyCode.Q, (int)KeyCode.W, (int)KeyCode.E };   

    public float fSpeedRate = 1f;
    private const int MAX_LINE_COUNT = 9;
    private const int MAX_ROW_COUNT = 3;
    private const int BLOCK_SIZE = 60;
    private const int BLOCK_TOTAL_SIZE = 480;
    
    float fMoveDelta = 0;
    int iRollCount = 0;
    int iCurrentLine = 0;
    bool[,] bData = new bool[MAX_LINE_COUNT, MAX_ROW_COUNT];
    bool bGameStart = false;
    float fStartTime = 0f;
    float fDropTime = 0.05f;
    public List<GameObject> m_kTexList;
    public List<UITexture[]> m_kTexlinelist;
    float[] fOriginY = new float[MAX_LINE_COUNT];
    
    int iComboCount = 0;

    bool bBlockDroping = false;
    bool bSkillSlow = false;
    bool bSkillSlowCounter = false;

    public int iPanelIndex = 0;
    public int iPlayerIndex = 0;
    public int iOtherPlayerIndex = 0;
    private int MaxStepCount = 155;

    private float fSkillDuration = 2f;
    private float fWrongDuration = 0.3f;

    private float fSkill1Duration = 1.5f;
    private float fSkill2Duration = 1.5f;
    private float fSkill3Duration = 6f;

    private int[] iSkill1Combo = {20, 15, 25, 20 };

    private AUDIO_TYPE audioType;

    public List<GameObject> m_kBtns = new List<GameObject>();

    public class kBlock
    {
        public bool bBanana;
        public UITexture kTex;
    }
    public kBlock[,] m_kTexlinelistNew = new kBlock[MAX_LINE_COUNT, MAX_ROW_COUNT];
    

    // Use this for initialization
    void Start()
    {
        MaxStepCount = m_kMainUI.MaxStepCount;
        m_kTexlinelistNew[0, 0] = new kBlock();
        m_kTexlinelist = new List<UITexture[]>
        {
            m_kTexLine_0, m_kTexLine_1, m_kTexLine_2,
            m_kTexLine_3, m_kTexLine_4, m_kTexLine_5,
            m_kTexLine_6, m_kTexLine_7, m_kTexLine_8,
        };

        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            for (int j = 0; j < MAX_ROW_COUNT; j++)
            {
                m_kTexlinelistNew[i, j] = new kBlock();
                m_kTexlinelistNew[i, j].kTex = m_kTexlinelist[i][j];
                m_kTexlinelistNew[i, j].kTex.mainTexture = Resources.Load("UI/Main/tex_block_0") as Texture2D;
                m_kTexlinelistNew[i, j].bBanana = false;
            }
        }

        m_kTexList = new List<GameObject>
        {
            m_kLine_0, m_kLine_1, m_kLine_2,
            m_kLine_3, m_kLine_4, m_kLine_5,
            m_kLine_6, m_kLine_7, m_kLine_8,
        };
        audioType = (iPanelIndex == 0) ? AUDIO_TYPE.AT_Guild : AUDIO_TYPE.AT_Event;
        InitBlockData();
        UpdateComboProgress();
    }
    
    // Update is called once per frame
    void Update()
    {
        if (!bGameStart)
            return;
        if (bBlockDroping)
            return;

        if (Input.GetKeyDown((KeyCode)Key[0]))
        {
            GetKeyResult(0);
        }
        if (Input.GetKeyDown((KeyCode)Key[1]))
        {
            GetKeyResult(1);
        }
        if (Input.GetKeyDown((KeyCode)Key[2]))
        {
            GetKeyResult(2);
        }
    }

    void onKeyClick(GameObject go)
    {
        if (bBlockDroping)
            return;
        GetKeyResult(m_kBtns.IndexOf(go));
    }

    public void InitNativePlayerKey()
    {
        foreach (GameObject btn in m_kBtns)
        {
            UIEventListener.Get(btn).onClick += onKeyClick;
        }
    }

    IEnumerator BlockDrop()
    {
        fStartTime = Time.time;
        float fPercent = 0f;
        while (fPercent < 1)
        {
            fPercent = (Time.time - fStartTime) / fDropTime;
            fPercent = fPercent > 1 ? 1 : fPercent;
            fMoveDelta = fPercent * BLOCK_SIZE;
            for (int i = 0; i < MAX_LINE_COUNT; i++)
            {
                m_kTexList[i].transform.localPosition = new Vector3(0, fOriginY[i] - fMoveDelta, 0);
            }
            yield return null;
        }
        UpdateOneLineBlock(iCurrentLine);
        m_kTexList[iCurrentLine].transform.localPosition = new Vector3(0, BLOCK_TOTAL_SIZE, 0);
        iRollCount++;
        iCurrentLine++;
        iCurrentLine = iCurrentLine < MAX_LINE_COUNT ? iCurrentLine : 0;
        bBlockDroping = false;
    }

    public void SetGameStart()
    {
        bGameStart = true;
    }

    public void SetGameStop()
    {
        bGameStart = false;
    }

    void InitBlockData()
    {
        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            int j = GetRandom();
            m_kTexlinelistNew[i, j].bBanana = true;
            m_kTexlinelistNew[i, j].kTex.GetComponent<UITexture>().mainTexture = Resources.Load("UI/Main/tex_block_1") as Texture2D;
         }
    }

    void SetUITexture(UITexture kTexture, bool bData)
    {
        string strName = bData ? "UI/Main/tex_block_1" : "UI/Main/tex_block_0";
        var tex = Resources.Load(strName) as Texture2D;
        kTexture.mainTexture = tex;
    }

    void UpdateOneLineBlock(int iNewLine)
    {
        m_kTexlinelistNew[iNewLine, 0].bBanana = false;
        m_kTexlinelistNew[iNewLine, 0].kTex.mainTexture = Resources.Load("UI/Main/tex_block_0") as Texture2D;
        m_kTexlinelistNew[iNewLine, 1].bBanana = false;
        m_kTexlinelistNew[iNewLine, 1].kTex.mainTexture = Resources.Load("UI/Main/tex_block_0") as Texture2D;
        m_kTexlinelistNew[iNewLine, 2].bBanana = false;
        m_kTexlinelistNew[iNewLine, 2].kTex.mainTexture = Resources.Load("UI/Main/tex_block_0") as Texture2D;
        int i = GetRandom();
        m_kTexlinelistNew[iNewLine, i].bBanana = true;
        m_kTexlinelistNew[iNewLine, i].kTex.mainTexture = Resources.Load("UI/Main/tex_block_1") as Texture2D;
    }
    
    void GetKeyResult(int iInput)
    {
        if (!bGameStart)
            return;

        if(m_kTexlinelistNew[iCurrentLine, iInput].bBanana)
        {
            for (int i = 0; i < MAX_LINE_COUNT; i++)
            {
                fOriginY[i] = m_kTexList[i].transform.localPosition.y;
            }
            bBlockDroping = true;
            m_kTexlinelistNew[iCurrentLine, iInput].kTex.mainTexture = Resources.Load("UI/Main/tex_block_3") as Texture2D;
            iComboCount++;
            AudioPlayer.Instance().Play(audioType, @"Audio/Correct", false);
            StartCoroutine(BlockDrop());
            if (bSkillSlow)
            {
                if(bSkillSlowCounter)
                {
                    SYSLogic.Instance().IncreasePlayerStep(iPanelIndex);
                }
                bSkillSlowCounter = !bSkillSlowCounter;
            }
            else
            {
                SYSLogic.Instance().IncreasePlayerStep(iPanelIndex);
            }
            if (SYSLogic.Instance().GetPlayerStep(iPanelIndex) >= MaxStepCount)
            {
                //===================================
                //TODO:游戏结束
                m_kMainUI.SetGameStop();
                bGameStart = false;
                //===================================
            }
        }
        else
        {
            bBlockDroping = true;
            iComboCount = 0;
            m_kTexlinelistNew[iCurrentLine, iInput].kTex.mainTexture = Resources.Load("UI/Main/tex_block_2") as Texture2D;
            AudioPlayer.Instance().Play(audioType, @"Audio/Error", false);
            StartCoroutine(WrongInput());
        }

        UpdateComboProgress();
        if (iComboCount >= iSkill1Combo[iPlayerIndex])
        {
            iComboCount = 0;
            m_kMainUI.CastSkill(iPanelIndex, iPlayerIndex);
        }
        
    }

    void UpdateComboProgress()
    {
        m_kComboProgress.fillAmount = (float)iComboCount / (float)iSkill1Combo[iPlayerIndex];
    }
    
    int GetRandom()
    {
        int i = Random.Range(0, 3);
        return i % MAX_ROW_COUNT;
    }

    public void CastSkill(int iPlayer)
    {
        switch (iPlayer)
        {
            case 1:
                StartCoroutine(CastSkill1());
                break;
            case 2:
                StartCoroutine(CastSkill2());
                break;
            case 3:
                StartCoroutine(CastSkill3());
                break;
            default:
                break;
        }
    }

    IEnumerator WrongInput()
    {
        float fTime = Time.time;
        bGameStart = false;
        while (Time.time < fTime + fWrongDuration)
        {
            yield return null;
        }
        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            fOriginY[i] = m_kTexList[i].transform.localPosition.y;
        }
        StartCoroutine(BlockDrop());
        bGameStart = true;
    }
    //遮挡
    IEnumerator CastSkill1()
    {
        float fTime = Time.time;
        m_kTexSkill.SetActive(true);
        while (Time.time < fTime + fSkill1Duration)
        {
            yield return null;
        }
        m_kTexSkill.SetActive(false);
    }
    //停止
    IEnumerator CastSkill2()
    {
        float fTime = Time.time;
        bGameStart = false;
        SetBananaGrey();
        while (Time.time < fTime + fSkill2Duration)
        {
            yield return null;
        }
        SetBananaNormal();
        bGameStart = true;
    }
    //减速
    IEnumerator CastSkill3()
    {
        float fTime = Time.time;
        SetBananaBad();
        bSkillSlow = true;
        while (Time.time < fTime + fSkill3Duration)
        {
            yield return null;
        }
        SetBananaNormal();
        bSkillSlow = false;
    }

    void SetBananaGrey()
    {
        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            for (int j = 0; j < MAX_ROW_COUNT; j++)
            {
                if (m_kTexlinelistNew[i, j].bBanana)
                    m_kTexlinelistNew[i, j].kTex.mainTexture = Resources.Load("UI/Main/tex_xiangjiao_1") as Texture2D;
            }
        }
    }

    void SetBananaNormal()
    {
        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            for (int j = 0; j < MAX_ROW_COUNT; j++)
            {
                if (m_kTexlinelistNew[i, j].bBanana)
                    m_kTexlinelistNew[i, j].kTex.mainTexture = Resources.Load("UI/Main/tex_block_1") as Texture2D;
            }
        }
    }

    void SetBananaBad()
    {
        for (int i = 0; i < MAX_LINE_COUNT; i++)
        {
            for (int j = 0; j < MAX_ROW_COUNT; j++)
            {
                if (m_kTexlinelistNew[i, j].bBanana)
                    m_kTexlinelistNew[i, j].kTex.mainTexture = Resources.Load("UI/Main/tex_xiangjiao_2") as Texture2D;
            }
        }
    }
}

游戏主流程的核心逻辑:

using UnityEngine;
using System.Collections;
using System;

public class UIMain : MonoBehaviour {

    public Transform m_kLeftAnchor;
    public Transform m_kRightAnchor;

    public int MaxStepCount = 120;

    public UITexture m_kTexAvatar1;
    public UITexture m_kTexAvatar2;

    public UILabel m_kLabPlayerName1;
    public UILabel m_kLabPlayerName2;

    public UILabel m_kLabSkillNum;

    public UIBlock m_kLeftBlockPanel;
    public UIBlock m_kRightBlockPanel;
    
    public GameObject m_kPlayer1;
    public GameObject m_kPlayer2;

    public GameObject m_kSmallAvatar_1;
    public GameObject m_kSmallAvatar_2;
    public UISprite m_kProgress;

    public GameObject m_kTimePanel;
    public UILabel m_kLabTime;

    public GameObject m_kStartPanel;
    public UIFinish m_kFinishPanel;

    public GameObject m_kSkillPanel;
    public UITexture m_kTexSkill;

    public GameObject[] m_kStartCounter;

    private CharacterControl m_kPlayer1Control;
    private CharacterControl m_kPlayer2Control;

    public int iPlayer1 = 0;
    public int iPlayer2 = 1;

    public Vector3 m_kPlayer1StartPos = new Vector3(0f,0f,0f);
    public Vector3 m_kPlayer2StartPos = new Vector3(0f, 0f, 0f);
    public Transform m_kMainCamera;
    public Transform m_kLight;
    bool bIsGameStart;

    public Transform m_kForaneTex;
    public float m_kForaneFollowCameraRate = 0.5f;

    private Vector3 mLastFrameCameraPos;

    private float fStartTime;
    private float fAvatarPosOrigin = -200f;
    private float fAvatarPosMove = 400f;

    private string[] strTexSkillPath = { "", "tex_weifeng_1", "tex_heiyi_1", "tex_bingge_1" };

    void Awake()
    {
        adaptScreen();
    }

    private void adaptScreen()
    {
        Vector3 rightAnchorPos = m_kRightAnchor.transform.localPosition;
        rightAnchorPos.x += UIUtility.GetDockOffsetX();
        m_kRightAnchor.transform.localPosition = rightAnchorPos;

        Vector3 leftAnchorPos = m_kLeftAnchor.transform.localPosition;
        leftAnchorPos.x -= UIUtility.GetDockOffsetX();
        m_kLeftAnchor.transform.localPosition = leftAnchorPos;
    }

    // Use this for initialization
    void Start () {

        m_kLeftBlockPanel.m_kMainUI = this;
        m_kRightBlockPanel.m_kMainUI = this;

        iPlayer1 = SYSLogic.Instance().GetPlayerInfo(0);
        iPlayer2 = SYSLogic.Instance().GetPlayerInfo(1);

        SYSLogic.Instance().ClearPlayerStep();

        SetKey();
        SetAvatar();

        m_kPlayer1 = ResourceMgr.LoadResources(@"Character/Character0" + iPlayer1 + "_Prefab");
        m_kPlayer1.animation.Play("Player1DropDown");
        m_kPlayer2 = ResourceMgr.LoadResources(@"Character/Character0" + iPlayer2 + "_Prefab");
        m_kPlayer2.animation.Play("Player2DropDown");
        m_kPlayer1Control = m_kPlayer1.GetComponent<CharacterControl>();
        m_kPlayer2Control = m_kPlayer2.GetComponent<CharacterControl>();

        m_kPlayer1Control.Init(0);
        m_kPlayer2Control.Init(1);

        m_kPlayer1.transform.position = m_kPlayer1StartPos;
        m_kPlayer2.transform.position = m_kPlayer2StartPos;
        
        Vector3 cameraPos = m_kMainCamera.position;
        //cameraPos.x = ((m_kPlayer1StartPos + m_kPlayer2StartPos) / 2).x;
        if (m_kPlayer1.transform.position.x < m_kPlayer2.transform.position.x)
        {
            cameraPos.x = m_kPlayer1.transform.position.x;
        }
        else
        {
            cameraPos.x = m_kPlayer2.transform.position.x;
        }
        m_kMainCamera.position = cameraPos;
        mLastFrameCameraPos = cameraPos;

        m_kProgress.fillAmount = 0f;

        StartCoroutine(StartCounter());
		//SetGameStart();
    }

    IEnumerator StartCounter()
    {
        fStartTime = Time.time;
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }

        fStartTime = Time.time;
        m_kStartPanel.SetActive(true);
        m_kStartCounter[4].SetActive(true);
        AudioPlayer.Instance().Play(AUDIO_TYPE.AT_UI_BGM, @"Audio/Counter", false);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }

        fStartTime = Time.time;
        m_kStartCounter[4].SetActive(false);
        m_kStartCounter[3].SetActive(true);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }

        fStartTime = Time.time;
        m_kStartCounter[3].SetActive(false);
        m_kStartCounter[2].SetActive(true);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }

        fStartTime = Time.time;
        m_kStartCounter[2].SetActive(false);
        m_kStartCounter[1].SetActive(true);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }
        
        fStartTime = Time.time;
        m_kStartCounter[1].SetActive(false);
        m_kStartCounter[0].SetActive(true);
        AudioPlayer.Instance().Play(AUDIO_TYPE.AT_SCENE_BGM, @"Audio/RunningBGM", true);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }

        m_kStartCounter[0].SetActive(false);
        m_kStartPanel.SetActive(false);
        SetGameStart();
    }
    

    void SetKey()
    {
        m_kLeftBlockPanel.Key = new int[] { (int)KeyCode.A, (int)KeyCode.S, (int)KeyCode.D };
        m_kRightBlockPanel.Key = new int[] { (int)KeyCode.LeftArrow, (int)KeyCode.DownArrow, (int)KeyCode.RightArrow };
    }

    void SetAvatar()
    {
        m_kLeftBlockPanel.iPanelIndex = 0;
        m_kRightBlockPanel.iPanelIndex = 1;
        m_kLeftBlockPanel.iPlayerIndex = iPlayer1;
        m_kLeftBlockPanel.iOtherPlayerIndex = iPlayer2;
        m_kRightBlockPanel.iPlayerIndex = iPlayer2;
        m_kRightBlockPanel.iOtherPlayerIndex = iPlayer1;
        m_kTexAvatar1.mainTexture = Resources.Load("UI/Main/tex_avatar_" + iPlayer1) as Texture2D;
        m_kTexAvatar2.mainTexture = Resources.Load("UI/Main/tex_avatar_" + iPlayer2) as Texture2D;
        m_kSmallAvatar_1.GetComponent<UITexture>().mainTexture = Resources.Load("UI/Main/tex_avatar_" + iPlayer1) as Texture2D;
        m_kSmallAvatar_2.GetComponent<UITexture>().mainTexture = Resources.Load("UI/Main/tex_avatar_" + iPlayer2) as Texture2D;
        m_kLeftBlockPanel.InitNativePlayerKey();
        m_kRightBlockPanel.InitNativePlayerKey();
    }

    // Update is called once per frame
    void Update () {

        m_kLight.LookAt(m_kMainCamera);

        Vector3 cameraPos = m_kMainCamera.position;
        float displacement = cameraPos.x - mLastFrameCameraPos.x;
        mLastFrameCameraPos = cameraPos;

        mLastFrameCameraPos = m_kMainCamera.position;
        if (m_kPlayer1.transform.position.x < m_kPlayer2.transform.position.x)
        {
            cameraPos.x = m_kPlayer1.transform.position.x;
        }
        else
        {
            cameraPos.x = m_kPlayer2.transform.position.x;
        }
        //cameraPos.x = ((m_kPlayer1.transform.position + m_kPlayer2.transform.position) / 2).x;
        m_kMainCamera.position = cameraPos;
        Vector3 foraneTexPos = m_kForaneTex.position;
        foraneTexPos.x += displacement * m_kForaneFollowCameraRate;
        m_kForaneTex.position = foraneTexPos;

        if(bIsGameStart)
        {
            UpdateTime();
            float fProgress = (float)GetMaxStep() / (float)MaxStepCount;
            m_kProgress.fillAmount = fProgress > 1 ? 1 : fProgress;
        }
    }

    void UpdateTime()
    {
        float fDeltaTime = Time.time - fStartTime;
        TimeSpan ts = new TimeSpan(0, 0, 0, (int)fDeltaTime);
        string strMilliSecond = ((fDeltaTime - (int)fDeltaTime).ToString() + "00").Substring(2, 2);
        m_kLabTime.text = ts.Minutes.ToString() + ":" + ts.Seconds.ToString() + "." + strMilliSecond;
    }

    int GetMaxStep()
    {
        int iPlayer1 = SYSLogic.Instance().GetPlayerStep(0);
        int iPlayer2 = SYSLogic.Instance().GetPlayerStep(1);

        m_kSmallAvatar_1.transform.localPosition = new Vector3(fAvatarPosOrigin + ((float)iPlayer1 / (float)MaxStepCount) * fAvatarPosMove, -16, 0);
        m_kSmallAvatar_2.transform.localPosition = new Vector3(fAvatarPosOrigin + ((float)iPlayer2 / (float)MaxStepCount) * fAvatarPosMove, -56, 0);

        return iPlayer1 > iPlayer2 ? iPlayer1 : iPlayer2;
    }

    public void SetGameStart()
    {
        bIsGameStart = true;
        m_kLeftBlockPanel.SetGameStart();
        if (!SYSLogic.Instance().m_bPVP) m_kRightBlockPanel.SetGameStart();
        m_kTimePanel.SetActive(true);
        fStartTime = Time.time;
    }

    public void SetGameStop()
    {
        bIsGameStart = false;
        m_kLeftBlockPanel.SetGameStop();
        m_kRightBlockPanel.SetGameStop();

        bool bPlayer1 = (SYSLogic.Instance().GetPlayerStep(0) > SYSLogic.Instance().GetPlayerStep(1));
        SYSLogic.Instance().FinishBattle((int)(Time.time - fStartTime));
        m_kFinishPanel.SetData(bPlayer1, iPlayer1, iPlayer2);
        m_kFinishPanel.gameObject.SetActive(true);
        AudioPlayer.Instance().Pause(AUDIO_TYPE.AT_SCENE_BGM);
        AudioPlayer.Instance().Play(AUDIO_TYPE.AT_Use_Once, @"Audio/Victory", false);
    }

    public void CastSkill(int iPanelIndex, int iPlayerIndex)
    {
        AudioPlayer.Instance().Play(AUDIO_TYPE.AT_Use_Once, @"Audio/Skill", false);
        StartCoroutine(ShowSkillPanel(iPlayerIndex));
        switch (iPanelIndex)
        {
            case 0:
                m_kRightBlockPanel.CastSkill(iPlayerIndex);
                break;
            case 1:
                m_kLeftBlockPanel.CastSkill(iPlayerIndex);
                break;
            default:
                break;
        }
    }

    IEnumerator ShowSkillPanel(int iPlayer)
    {
        float fStartTime = Time.time;
        m_kTexSkill.mainTexture = Resources.Load("UI/Main/" + strTexSkillPath[iPlayer]) as Texture2D;
        m_kSkillPanel.SetActive(true);
        while (Time.time < fStartTime + 1f)
        {
            yield return null;
        }
        m_kSkillPanel.SetActive(false);
    }

    public void playStartCountdownVoice()
    {
        AudioSource _audioSource = new AudioSource();
    }
}