public override void setData(object data)
    {
        ChallengeInfinityRun d = (ChallengeInfinityRun)data;

        units          = d.summonUnits;
        _summonDelay   = d.summonDelay;
        _delay         = 0.0f;
        _checkDistance = d.checkDistance;
    }
    public void setStage(RoundData rd)
    {
        // 실제 게임이 시작하기 바로 전에 호출.
        useZoomCamera = false;

        int index = 0;
        int i     = 0;
        int len   = 0;

        if (isSetStage)
        {
#if UNITY_EDITOR
            Debug.LogError("### Already Setting Stage!!!");
#endif
            return;
        }

        StageManager.mapStartPosX = rd.mapStartEndPosX[0];
        StageManager.mapEndPosX   = rd.mapStartEndPosX[1];

        killedUnitCount = 0;
        bossNum         = 0;
        monUnitNum      = 0;
        GameManager.me.stageManager.protectNPC = null;
        GameManager.me.stageManager.chaser     = null;
        GameManager.me.stageManager.playerDestroyObjectMonster = null;
        GameManager.me.stageManager.heroMonster = null;

        _v   = GameManager.me.player.cTransformPosition;
        _v.x = rd.playerStartPosX;
        _v.z = 0.0f;
        GameManager.me.player.setPositionCtransform(_v);

        GameManager.me.characterManager.playerMonster.Add(GameManager.me.player);

        if (rd.mode == RoundData.MODE.PVP)
        {
            GameManager.me.battleManager.initPlayer(_v);

            _v = GameManager.me.player.cTransformPosition;
            //_v.x = DebugManager.instance.pvpStartPoint;
            _v.x = 2450.0f;
            GameManager.me.pvpPlayer = addPlayerToStage(false, DebugManager.instance.pvpPlayerData, _v, true);

            GameManager.me.battleManager.initPVPPlayer(_v);

            BaseSkillData.enemyHero = GameManager.me.pvpPlayer;
            isSetStage = true;

            MapManager.zoomCameraTargetX = GameManager.me.pvpPlayer.cTransformPosition.x;

            useZoomCamera = true;

            return;
        }
        else
        {
            DebugManager.instance.useTagMatchMode = false;
            GameManager.me.battleManager.initPlayer(_v);
        }


#if UNITY_EDITOR
        if (UnitSkillCamMaker.instance.useEffectSkillCamEditor)
        {
        }
        else
#endif
        {
            if (rd.heroMonsters.Length > 0)
            {
                index = 0;
                foreach (StageMonsterData data in rd.heroMonsters)
                {
                    if (data.attr == null)
                    {
                        ++index;
                    }
                }

                if (index > 0)
                {
                    GameManager.me.stageManager.heroMonster = new Monster[index];
                }
                else
                {
                    GameManager.me.stageManager.heroMonster = null;
                }


                index = 0;
                foreach (StageMonsterData data in rd.heroMonsters)
                {
                    _v.x = data.posX;
                    _v.y = data.posY;
                    _v.z = data.posZ;

                    if (data.attr == null)
                    {
                        GameManager.me.stageManager.heroMonster[index] = addMonsterToStage(null, null, false, data, data.id, _v);
                        ++index;
                    }
                    else
                    {
                        // attr이 "H" 면 히든임...
                        Monster mon = addMonsterToStage(null, null, false, data, data.id, _v, null, false);
                        mon.setVisible(false);
                        if (mon.miniMapPointer != null)
                        {
                            mon.miniMapPointer.isEnabled = false;
                        }
                        GameManager.me.characterManager.decoMonsters.Add(mon);
                    }
                }
            }
        }



        if (rd.unitMonsters != null)
        {
            foreach (StageMonsterData data in rd.unitMonsters)
            {
                _v.x = data.posX;
                _v.y = data.posY;
                _v.z = data.posZ;

                if (data.attr != null)
                {
                    if (data.attr == "V")                    // 적에게 쳐맞거나 상대가 위치에 왔을때 동작.
                    {
                        Monster mon = addMonsterToStage(null, null, false, null, data.id, _v);
                        if (data.checkLine > -1000)
                        {
                            mon.waitEnemy = true;
                            mon.waitLine  = data.checkLine;
                        }
                    }
                    else if (data.attr == "H")                    // 화면에 안보이다가 스폰...
                    {
                    }
                }
                else
                {
                    addMonsterToStage(null, null, false, null, data.id, _v);
                }
            }
        }


        if (rd.decoObject != null)
        {
            foreach (StageMonsterData data in rd.decoObject)
            {
                _v.x = data.posX;
                _v.y = data.posY;
                _v.z = data.posZ;

                Monster mon = addMonsterToStage(null, null, false, data, data.id, _v, null, false);
                GameManager.me.characterManager.decoMonsters.Add(mon);

                if (data.angle > -1000)
                {
                    Quaternion q = mon.tf.localRotation;
                    _v                   = q.eulerAngles;
                    _v.y                 = data.angle;
                    q.eulerAngles        = _v;
                    mon.tf.localRotation = q;
                }

                if (data.attr != null)
                {
                    string[] attr = data.attr.Split('-');
                    if (string.IsNullOrEmpty(attr[0]) == false && mon.ani != null)
                    {
                        mon.playAni(attr[0]);
                    }

                    if (attr.Length > 1)
                    {
                        float.TryParse(attr[2], out _v.x);
                        float.TryParse(attr[3], out _v.y);
                        float.TryParse(attr[4], out _v.z);
                        GameManager.info.effectData[attr[1]].getEffect(-1000, _v);
                    }
                }
            }
        }

        if (rd.blockObject != null)
        {
            foreach (StageMonsterData data in rd.blockObject)
            {
                _v.x = data.posX;
                _v.y = data.posY;
                _v.z = data.posZ;

                Monster dm = null;

                switch (data.attr)
                {
                case "0":
                    dm = addMonsterToStage(null, null, false, data, data.id, _v);
                    dm.isBlockMonster = false;
                    dm.specialType    = Monster.SpecialType.SKIP_DESTORY_CHECK;
                    break;

                case "1":
                    dm = addMonsterToStage(null, null, false, data, data.id, _v);
                    dm.isBlockMonster = true;
                    dm.specialType    = Monster.SpecialType.SKIP_DESTORY_CHECK;
                    break;

                case "2":
                    dm = addMonsterToStage(null, null, true, data, data.id, _v);
                    dm.isBlockMonster = false;
                    dm.specialType    = Monster.SpecialType.SKIP_DESTORY_CHECK;
                    break;

                case "3":
                    dm = addMonsterToStage(null, null, true, data, data.id, _v);
                    dm.isBlockMonster = true;
                    dm.specialType    = Monster.SpecialType.SKIP_DESTORY_CHECK;
                    break;
                }

                if (dm != null && data.angle > -1000)
                {
                    Quaternion q = dm.tf.localRotation;
                    _v                  = q.eulerAngles;
                    _v.y                = data.angle;
                    q.eulerAngles       = _v;
                    dm.tf.localRotation = q;
                }

                dm = null;
            }
        }



        if (rd.mode == RoundData.MODE.KILLCOUNT)
        {
            leftKilledMonsterNum.Clear();

            len = rd.killMonsterCount;
            for (i = 0; i < len; ++i)
            {
#if UNITY_EDITOR
                Debug.Log(rd.killMonsterIds[i] + "   " + rd.killMonsterNum[i]);
#endif

                if (leftKilledMonsterNum.ContainsKey(rd.killMonsterIds[i]))
                {
                    leftKilledMonsterNum[rd.killMonsterIds[i]] = rd.killMonsterNum[i];
                }
                else
                {
                    leftKilledMonsterNum.Add(rd.killMonsterIds[i], rd.killMonsterNum[i]);
                }
            }

            int num = 0;
            foreach (KeyValuePair <string, Xint> kv in GameManager.me.mapManager.leftKilledMonsterNum)
            {
                num += kv.Value;
            }

            GameManager.me.uiManager.uiPlay.lbRoundLeftNum.text = num + "M";
        }
        else if (rd.mode == RoundData.MODE.KILLCOUNT2)
        {
            leftKilledMonster = rd.killMonsterNum[0];
            GameManager.me.uiManager.uiPlay.lbRoundLeftNum.text = GameManager.me.mapManager.leftKilledMonster + "M";
        }
        else if (rd.mode == RoundData.MODE.GETITEM)
        {
            if (rd.settingAttr2 != null)
            {
                createDeadzoneMonster(rd);
            }

            leftGetItemNum.Clear();
            int totalNum = 0;
            foreach (KeyValuePair <string, Xint> kv in rd.getItemData.needCount)
            {
                leftGetItemNum[kv.Key] = kv.Value;
                totalNum += kv.Value;
            }

            GameManager.me.uiManager.uiPlay.lbRoundLeftNum.text = totalNum + "";
        }
        else if (rd.mode == RoundData.MODE.SURVIVAL)
        {
            if (rd.settingAttr2 != null)
            {
                createDeadzoneMonster(rd);
            }
        }
        else if (rd.mode == RoundData.MODE.ARRIVE)
        {
            if (rd.chaser != null)
            {
                _v.x = rd.chaser.posX; _v.y = 0.0f; _v.z = rd.chaser.posZ;
                GameManager.me.stageManager.chaser = addMonsterToStage(null, null, false, rd.chaser, rd.chaser.id, _v, null, false);
                GameManager.me.stageManager.chaser.miniMapPointer = GameManager.me.characterManager.getMinimapPointer(false, GameManager.me.stageManager.chaser.cTransform);
                GameManager.me.stageManager.chaser.initMiniMap();
                GameManager.me.stageManager.chaser.stat.speed = rd.chaser.speed;
                GameManager.me.stageManager.chaser.lookDirection(1000);
            }

            if (rd.protectObject != null)
            {
                _v    = GameManager.me.player.cTransformPosition;
                _v.x -= 150.0f;
                _v.z  = rd.protectObject[0].posZ;

                if (GameManager.info.npcData[rd.protectObject[0].id].type == NPCData.Type.PLAYER)
                {
                    GameManager.me.stageManager.protectNPC = (Monster)GameManager.me.characterManager.getNPCPlayerCharacter(rd.protectObject[0].id, true);                    // addMonsterToStage(true, rd.protectObject[0], rd.protectObject[0].id ,_v);
                    GameManager.me.stageManager.protectNPC.setPositionCtransform(_v);
                }
                else
                {
                    GameManager.me.stageManager.protectNPC = addMonsterToStage(null, null, true, rd.protectObject[0], rd.protectObject[0].id, _v);
                }

                GameManager.me.stageManager.protectNPC.miniMapPointer.init(CharacterMinimapPointer.PROTECT, GameManager.me.stageManager.protectNPC.cTransform, 12);

                GameManager.me.characterManager.setCharacterAction(GameManager.me.stageManager.protectNPC.action, GameManager.me.stageManager.protectNPC.category);
                GameManager.me.stageManager.protectNPC.action   = null;
                GameManager.me.stageManager.protectNPC.category = MonsterCategory.Category.PROTECT;
                GameManager.me.stageManager.protectNPC.action   = GameManager.me.characterManager.getCharacterAction(GameManager.me.stageManager.protectNPC.category);
                GameManager.me.stageManager.protectNPC.action.init(GameManager.me.stageManager.protectNPC);

                GameManager.me.stageManager.protectNPC.action.targetPos.x = rd.protectObject[0].checkLine.Get();
            }


            targetPosMinimapPointer = GameManager.me.characterManager.getMinimapPointer(false, null);
            targetPosMinimapPointer.pointer.spriteName = CharacterMinimapPointer.DISTANCE;
            targetPosMinimapPointer.init(CharacterMinimapPointer.DISTANCE, null, 16, true);
            targetPosMinimapPointer.setPosition(rd.targetPos);
            targetPosMinimapPointer.isEnabled = true;

            _v.x         = rd.targetPos + 50; _v.y = 5; _v.z = 0;
            effectArrive = GameManager.info.effectData["E_EVENT_ARRIVE_EFF"].getParticleEffect(-1000, _v, null, null);
        }
        else if (rd.mode == RoundData.MODE.PROTECT)
        {
            if (rd.settingAttr2 != null)
            {
                createDeadzoneMonster(rd);
            }

            index = 0;
            GameManager.me.stageManager.playerProtectObjectMonster = new Monster[rd.protectObject.Length];
            GameManager.me.stageManager.protectObjMonCount         = rd.protectObject.Length;
            foreach (StageMonsterData data in rd.protectObject)
            {
                _v.x = data.posX;
                _v.y = data.posY;
                _v.z = data.posZ;

                Monster pMon;

                if (GameManager.info.npcData[data.id].type == NPCData.Type.PLAYER)
                {
                    pMon = (Monster)GameManager.me.characterManager.getNPCPlayerCharacter(data.id, true);
                    pMon.setPositionCtransform(_v);
                }
                else
                {
                    pMon = addMonsterToStage(null, null, true, data, data.id, _v);
                }

                GameManager.me.stageManager.playerProtectObjectMonster[index] = pMon;
                pMon.miniMapPointer.init(CharacterMinimapPointer.PROTECT, pMon.cTransform, 12);


                GameManager.me.characterManager.setCharacterAction(pMon.action, pMon.category);
                pMon.action   = null;
                pMon.category = MonsterCategory.Category.NPC;
                pMon.action   = GameManager.me.characterManager.getCharacterAction(pMon.category);
                pMon.action.init(pMon);


                if (data.angle > -1000)
                {
                    Quaternion q = pMon.tf.localRotation;
                    _v                    = q.eulerAngles;
                    _v.y                  = data.angle;
                    q.eulerAngles         = _v;
                    pMon.tf.localRotation = q;
                }


                if (data.attr != null)
                {
                    string[] attr = data.attr.Split('-');
                    if (string.IsNullOrEmpty(attr[0]) == false && pMon.ani != null)
                    {
                        pMon.playAni(attr[0]);
                    }

                    if (attr.Length > 1)
                    {
                        float.TryParse(attr[2], out _v.x);
                        float.TryParse(attr[3], out _v.y);
                        float.TryParse(attr[4], out _v.z);
                        GameManager.info.effectData[attr[1]].getEffect(-1000, _v);
                    }
                }

//				Debug.LogError("pMon type! : " + pMon.stat.monsterType);

                ++index;
            }
        }
        else if (rd.mode == RoundData.MODE.SNIPING)
        {
                        #if UNITY_EDITOR
            if (UnitSkillCamMaker.instance.useEffectSkillCamEditor)
            {
            }
            else
                        #endif
            {
                GameManager.me.stageManager.heroMonster[rd.targetIndex].miniMapPointer.init(CharacterMinimapPointer.BOSS, GameManager.me.stageManager.heroMonster[rd.targetIndex].cTransform, 7);
            }
        }
        else if (rd.mode == RoundData.MODE.DESTROY)
        {
            if (rd.chaser != null)
            {
                _v.x = rd.chaser.posX; _v.y = 0.0f; _v.z = rd.chaser.posZ;
                GameManager.me.stageManager.chaser = addMonsterToStage(null, null, false, rd.chaser, rd.chaser.id, _v, null, false);
                GameManager.me.stageManager.chaser.miniMapPointer = GameManager.me.characterManager.getMinimapPointer(false, GameManager.me.stageManager.chaser.cTransform);
                GameManager.me.stageManager.chaser.initMiniMap();
                GameManager.me.stageManager.chaser.stat.speed = rd.chaser.speed;
                GameManager.me.stageManager.chaser.lookDirection(1000);
            }

            leftDestroyObjectNum.Clear();
            index = 0;
            GameManager.me.stageManager.playerDestroyObjectMonster = new Monster[rd.destroyObject.Length];

            foreach (StageMonsterData data in rd.destroyObject)
            {
                if (leftDestroyObjectNum.ContainsKey(data.id) == false)
                {
                    leftDestroyObjectNum[data.id] = 1;
                }
                else
                {
                    ++leftDestroyObjectNum[data.id];
                }

                _v.x = data.posX;
                _v.y = data.posY;
                _v.z = data.posZ;
                GameManager.me.stageManager.playerDestroyObjectMonster[index]            = addMonsterToStage(null, null, false, data, data.id, _v);
                GameManager.me.stageManager.playerDestroyObjectMonster[index].stat.speed = data.speed;


                if (data.angle > -1000)
                {
                    Quaternion q = GameManager.me.stageManager.playerDestroyObjectMonster[index].tf.localRotation;
                    _v            = q.eulerAngles;
                    _v.y          = data.angle;
                    q.eulerAngles = _v;
                    GameManager.me.stageManager.playerDestroyObjectMonster[index].tf.localRotation = q;
                }

                ++index;
            }

            int num = 0;
            foreach (KeyValuePair <string, Xint> kv in leftDestroyObjectNum)
            {
                num += kv.Value;
            }

            GameManager.me.uiManager.uiPlay.lbRoundLeftNum.text = num + "";
        }
        else if (rd.mode == RoundData.MODE.C_RUN)        // 무한질주
        {
            string[] cData         = rd.settingAttr.Split('/');
            string[] cRun          = cData[0].Split(',');
            int      cBossNum      = 0;
            float    startX        = 0;
            float    xOffset       = 0;
            float    checkDistance = 0;
            float.TryParse(cRun[1], out startX);
            float.TryParse(cRun[2], out xOffset);
            int.TryParse(cRun[3], out cBossNum);
            float.TryParse(cRun[4], out checkDistance);

            float[] constValue = Util.stringToFloatArray(cData[1], ',');

            for (i = 0; i < cBossNum; ++i)
            {
                _v.x = startX + (i * xOffset);
                _v.y = 0.0f;
                _v.z = 0.0f;
                Monster mon = addMonsterToStage(null, null, false, rd.challengeData, cRun[0], _v);
                GameManager.me.characterManager.setCharacterAction(mon.action, mon.category);
                mon.action   = null;
                mon.category = MonsterCategory.Category.CHALLENGE_RUN_BOSS;
                mon.action   = GameManager.me.characterManager.getCharacterAction(mon.category);
                mon.action.init(mon);
                mon.name = "RUN_BOSS";

                ChallengeInfinityRun cr = new ChallengeInfinityRun();
                cr.checkDistance = checkDistance;
                cr.summonDelay   = (float)(cBossNum - i) / (float)cBossNum * constValue[0] + constValue[1];
                cr.summonDelay  *= 0.001f;
                cr.summonUnits   = rd.units;
                cr.rankData      = Util.stringToIntArray(cData[2], ',');
                rankData         = cr.rankData;
                mon.action.setData((object)cr);
                mon.initMiniMap();
            }

            GameManager.me.uiManager.uiPlay.challangeModeInfo.init(rd.mode, rankData[0], rankData[1], rankData[2]);
        }
        else if (rd.mode == RoundData.MODE.C_SURVIVAL)        // 무한 생존
        {
            string[] cData  = rd.settingAttr.Split('/');
            float[]  csData = Util.stringToFloatArray(cData[0], ',');
            _v.x = csData[0];
            _v.y = 0.0f;
            _v.z = 0.0f;
            Monster mon = addMonsterToStage(null, null, false, null, rd.challengeData.id, _v, null, false);
            GameManager.me.characterManager.setCharacterAction(mon.action, mon.category);
            mon.action   = null;
            mon.category = MonsterCategory.Category.CHALLENGE_SURVIVAL_BOSS;
            mon.action   = GameManager.me.characterManager.getCharacterAction(mon.category);
            mon.action.init(mon);
            mon.name = "BOSS";

            ChallengeInfinitySurvival cs = new ChallengeInfinitySurvival();
            cs.constValue  = Util.stringToFloatArray(cData[1], ',');
            cs.rankData    = Util.stringToIntArray(cData[2], ',');
            rankData       = cs.rankData;
            cs.summonUnits = rd.units;
            cs.hitRadius   = csData[1];
            mon.action.setData((object)cs);
            mon.setVisible(false);
            if (mon.miniMapPointer != null)
            {
                mon.miniMapPointer.isEnabled = false;
            }
            GameManager.me.characterManager.decoMonsters.Add(mon);

            GameManager.me.uiManager.uiPlay.challangeModeInfo.init(rd.mode, rankData[0], rankData[1], rankData[2]);


            useZoomCamera     = true;
            zoomCameraTargetX = csData[0];
        }
        else if (rd.mode == RoundData.MODE.C_HUNT)        // 무한 사냥.
        {
            string[] cData = rd.settingAttr.Split('/');

            ChallengeInfinityHunt ch = new ChallengeInfinityHunt();
            ch.summonDelays = Util.stringToFloatArray(cData[2], ',');
            ch.rankData     = Util.stringToIntArray(cData[3], ',');
            rankData        = ch.rankData;
            ch.summonUnits  = rd.units;
            float[] distanceData = Util.stringToFloatArray(cData[1], ',');

            float startPosX = 0.0f;

            float.TryParse(cData[0], out startPosX);

            ch.checkLevelDistance    = new float[5];
            ch.checkLevelDistance[0] = startPosX;

            for (int li = 0; li < 4; ++li)
            {
                ch.checkLevelDistance[li + 1] = distanceData[li] + ch.checkLevelDistance[li];
            }

            _v.x = startPosX;
            foreach (float w in distanceData)
            {
                _v.x += w;
            }

            _v.y = 0.0f;
            _v.z = 0.0f;
            Monster mon = addMonsterToStage(null, null, false, null, rd.challengeData.id, _v, null, false);
            GameManager.me.characterManager.setCharacterAction(mon.action, mon.category);
            mon.action   = null;
            mon.category = MonsterCategory.Category.CHALLENGE_HUNT_BOSS;
            mon.action   = GameManager.me.characterManager.getCharacterAction(mon.category);
            mon.action.init(mon);
            mon.name = "BOSS";

            mon.action.setData((object)ch);
            mon.setVisible(false);
            if (mon.miniMapPointer != null)
            {
                mon.miniMapPointer.isEnabled = false;
            }
            GameManager.me.characterManager.decoMonsters.Add(mon);

            GameManager.me.uiManager.uiPlay.challangeModeInfo.init(rd.mode, rankData[0], rankData[1], rankData[2]);

            useZoomCamera     = true;
            zoomCameraTargetX = _v.x;
        }


        else if (rd.mode == RoundData.MODE.B_TEST)        // 무한질주
        {
            Monster mon = addMonsterToStage(null, null, false, null, rd.challengeData.id, _v, null, false);
            GameManager.me.characterManager.setCharacterAction(mon.action, mon.category);
            mon.action   = null;
            mon.category = MonsterCategory.Category.B_TEST_BOSS;
            mon.action   = GameManager.me.characterManager.getCharacterAction(mon.category);
            mon.action.init(mon);
#if UNITY_EDITOR
            mon.name = "BOSS";
#endif

            mon.action.setData((object)rd.settingAttr);

            mon.setVisible(false);
            if (mon.miniMapPointer != null)
            {
                mon.miniMapPointer.isEnabled = false;
            }
            GameManager.me.characterManager.decoMonsters.Add(mon);

            GameManager.me.uiManager.uiPlay.challangeModeInfo.init(rd.mode, 9999, 9999, 9999);
        }

        isSetStage = true;
    }