示例#1
0
        void SwapResource(int ID)
        {
            List <Rsc> rscList = EditorDBManager.GetRscList();

            Rsc rsc = rscList[currentSwapID];

            rscList[currentSwapID] = rscList[ID];
            rscList[ID]            = rsc;

            currentSwapID = -1;

            EditorDBManager.SetDirtyRsc();
        }
示例#2
0
        public static Vector3 DrawStat(UnitStat stat, float startX, float startY, float statContentHeight, UnitTower tower, UnitCreep creep)
        {
            List <Rsc> rscList = EditorDBManager.GetRscList();

            float width  = 150;
            float fWidth = 35;
            float spaceX = 130;
            float height = 18;
            float spaceY = height + 2;

            //startY-=spaceY;

            GUI.Box(new Rect(startX, startY, 220, statContentHeight - startY), "");

            startX += 10;     startY += 10;

            if (tower != null)
            {
                cont = new GUIContent("Construct Duration:", "The time in second it takes to construct (if this is the first level)/upgrade (if this is not the first level)");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.buildDuration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buildDuration);

                cont = new GUIContent("Deconstruct Duration:", "The time in second it takes to deconstruct if the unit is in this level");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.unBuildDuration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.unBuildDuration);


                if (stat.cost.Count != rscList.Count)
                {
                    while (stat.cost.Count > rscList.Count)
                    {
                        stat.cost.RemoveAt(stat.cost.Count - 1);
                    }
                    while (stat.cost.Count < rscList.Count)
                    {
                        stat.cost.Add(0);
                    }
                }
                cont = new GUIContent("Build/Upgrade Cost:", "The resource required to build/upgrade to this level");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                int count = 0;    startY += spaceY;         float cachedX = startX;
                for (int i = 0; i < rscList.Count; i++)
                {
                    EditorUtilities.DrawSprite(new Rect(startX + 10, startY - 1, 20, 20), rscList[i].icon);
                    stat.cost[i] = EditorGUI.IntField(new Rect(startX + 30, startY, fWidth, height), stat.cost[i]);
                    count       += 1;       startX += 65;
                    if (count == 3)
                    {
                        startY += spaceY; startX = cachedX;
                    }
                }
                startX = cachedX; startY += 5;

                startY += spaceY + 5;
            }



            if ((tower && TowerUseShootObject(tower)))
            {
                cont = new GUIContent("ShootObject:", "The shootObject used by the unit.\nUnit that intended to shoot at the target will not function correctly if this is left unassigned.");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.shootObject = (ShootObject)EditorGUI.ObjectField(new Rect(startX + spaceX - 50, startY, 4 * fWidth - 20, height), stat.shootObject, typeof(ShootObject), false);
                startY          += 5;
            }

            if (tower && TowerUseShootObjectT(tower))
            {
                cont = new GUIContent("ShootObject:", "The shootObject used by the unit.\nUnit that intended to shoot at the target will not function correctly if this is left unassigned.");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.shootObjectT = (Transform)EditorGUI.ObjectField(new Rect(startX + spaceX - 50, startY, 4 * fWidth - 20, height), stat.shootObjectT, typeof(Transform), false);
                startY           += 5;
            }

            if ((tower && TowerDealDamage(tower)))
            {
                cont = new GUIContent("Damage(Min/Max):", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.damageMin = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.damageMin);
                stat.damageMax = EditorGUI.FloatField(new Rect(startX + spaceX + fWidth, startY, fWidth, height), stat.damageMax);

                cont = new GUIContent("Cooldown:", "Duration between each attack");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.cooldown = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.cooldown);

                /*
                 * cont=new GUIContent("Clip Size:", "The amount of attack the unit can do before the unit needs to reload\nWhen set to <0 the unit will never need any reload");
                 * EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
                 * stat.clipSize=EditorGUI.FloatField(new Rect(startX+spaceX, startY, fWidth, height), stat.clipSize);
                 * stat.clipSize=Mathf.Round(stat.clipSize);
                 *
                 *
                 * cont=new GUIContent("Reload Duration:", "");
                 * EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
                 * stat.reloadDuration=EditorGUI.FloatField(new Rect(startX+spaceX, startY, fWidth, height), stat.reloadDuration);
                 */


                cont = new GUIContent("Range:", "Effect range of the unit");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.range = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.range);

                cont = new GUIContent("AOE Radius:", "Area-of-Effective radius. When the shootObject hits it's target, any other hostile unit within the area from the impact position will suffer the same target as the target.\nSet value to >0 to enable. ");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.aoeRadius = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.aoeRadius);



                cont = new GUIContent("Stun", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Chance:", "Chance to stun the target in each successful attack. Takes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.stun.chance = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.stun.chance);

                cont = new GUIContent("        - Duration:", "The stun duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.stun.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.stun.duration);



                cont = new GUIContent("Critical", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("            - Chance:", "Chance to score critical hit in attack. Takes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.crit.chance = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.crit.chance);

                cont = new GUIContent("            - Multiplier:", "Damage multiplier for successful critical hit. Takes value from 0 and above with with 0.5 being 50% of normal damage as bonus");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.crit.dmgMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.crit.dmgMultiplier);



                cont = new GUIContent("Slow", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("         - Duration:", "The effect duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.slow.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.slow.duration);

                cont = new GUIContent("         - Multiplier:", "Move speed multiplier. Takes value from 0-1 with with 0.7 being decrese default speed by 30%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.slow.slowMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.slow.slowMultiplier);



                cont = new GUIContent("Dot", "Damage over time");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Duration:", "The effect duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.duration);

                cont = new GUIContent("        - Interval:", "Duration between each tick. Damage is applied at each tick.");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.interval = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.interval);

                cont = new GUIContent("        - Damage:", "Damage applied at each tick");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.value = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.value);
            }



            if ((tower && tower.type == _TowerType.Support))
            {
                cont = new GUIContent("Range:", "Effect range of the unit");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.range = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.range);
                startY    += 5;

                cont = new GUIContent("Buff:", "Note: Buffs from multple tower doesnt stack, however when there's difference in the buff strength, the stronger buff applies. A tower can gain maximum dmage buff from one source and maximum range buff from another");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Damage:", "Damage buff multiplier. Takes value from 0 and above with 0.5 being 50% increase in damage");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.damageBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.damageBuff);

                cont = new GUIContent("        - Cooldown:", "Dooldown buff multiplier. Takes value from 0-1 with 0.2 being reduce cooldown by 20%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.cooldownBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.cooldownBuff);

                cont = new GUIContent("        - Range:", "Range buff multiplier. Takes value from 0 and above with 0.5 being 50% increase in range");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.rangeBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.rangeBuff);

                cont = new GUIContent("        - Critical:", "Critical hit chance buff modifier. Takes value from 0 and above with 0.25 being 25% increase in critical hit chance");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.criticalBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.criticalBuff);

                cont = new GUIContent("        - HP Regen:", "HP Regeneration Buff. Takes value from 0 and above with 2 being gain 2HP second ");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.regenHP = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.regenHP);
            }



            if (tower)
            {
                startY += 10;
                cont    = new GUIContent("Custom Description:", "Check to use use custom description. If not, the default one (generated based on the effect) will be used");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.useCustomDesp = EditorGUI.Toggle(new Rect(startX + spaceX, startY, 40, height), stat.useCustomDesp);
                if (stat.useCustomDesp)
                {
                    GUIStyle style = new GUIStyle("TextArea");
                    style.wordWrap = true;
                    //~ cont=new GUIContent("Description(to be used in runtime): ", "");
                    //~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, 200, 20), cont);
                    stat.desp = EditorGUI.TextArea(new Rect(startX, startY + spaceY - 3, 200, 90), stat.desp, style);
                    startY   += 90;
                }
            }



            statContentHeight = startY + spaceY + 5;

            return(new Vector3(startX + 220, startY, statContentHeight));
        }
示例#3
0
        Vector3 DrawUnitConfigurator(float startX, float startY, List <UnitCreep> creepList, bool offense = false)
        {
            UnitCreep creep = creepList[selectID];

            float maxWidth = 0;
            //float cachedY=startY;
            float cachedX = startX;

            startX += 65;               //startY+=20;

            int type = (int)creep.type;

            cont = new GUIContent("Creep Type:", "Type of the creep. Different type of creep has different capabilities");
            EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
            contL = new GUIContent[creepTypeLabel.Length];
            for (int i = 0; i < contL.Length; i++)
            {
                contL[i] = new GUIContent(creepTypeLabel[i], creepTypeTooltip[i]);
            }
            type       = EditorGUI.Popup(new Rect(startX + 80, startY, width - 40, 15), new GUIContent(""), type, contL);
            creep.type = (_CreepType)type;
            startX     = cachedX;

            v3 = DrawIconAndName(creep, startX, startY);      startY = v3.y;    maxWidth = v3.z;


            cont = new GUIContent("Dodge Chance:", "Take value from 0-1. 0 being 0% and 1 being 100%. Final value are subject to target's hitChance. Assume two attackers with 1 hitChance and .8 hitChance and the dodgeChance set to .2, the chances to dodge attack from each attacker are 20% and 40% respectively.");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.stats[0].dodge = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 50, height), creep.stats[0].dodge);

            v3 = DrawUnitDefensiveSetting(creep, startX, startY, objHList, objHLabelList);    startY = v3.y;    if (maxWidth < v3.z)
            {
                maxWidth = v3.z;
            }

            startY += 20;


            cont = new GUIContent("Flying:", "Check to mark the creep as flying unit.");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.flying = EditorGUI.Toggle(new Rect(startX + spaceX, startY, 40, height), creep.flying);

            cont = new GUIContent("Move Speed:", "Moving speed of the creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.moveSpeed = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 40, height), creep.moveSpeed);

            cont = new GUIContent("Life Cost:", "The amont of life taken from player when this creep reach it's destination");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.lifeCost = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.lifeCost);

            //cont=new GUIContent("Score Value:", "Score gained when destroy this creep");
            //EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
            //creep.scoreValue=EditorGUI.IntField(new Rect(startX+spaceX, startY, 40, height), creep.scoreValue);

            cont = new GUIContent("Life Gain:", "Life awarded to the player when player successfully destroy this creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.lifeValue = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.lifeValue);

            cont = new GUIContent("Energy Gain:", "Energy awarded to the player when player successfully destroy this creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.valueEnergyGain = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.valueEnergyGain);


            cont = new GUIContent("Resource Gain Upon Destroyed:", "The amont of life taken from player when this creep reach it's destination");
            //EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
            rscGainFoldout = EditorGUI.Foldout(new Rect(startX, startY += spaceY, width, height), rscGainFoldout, cont);
            if (rscGainFoldout)
            {
                List <Rsc> rscList = EditorDBManager.GetRscList();
                for (int i = 0; i < rscList.Count; i++)
                {
                    EditorUtilities.DrawSprite(new Rect(startX + 25, startY += spaceY - 2, 20, 20), rscList[i].icon);     startY += 2;
                    EditorGUI.LabelField(new Rect(startX, startY, width, height), "    -       min/max");                    //+rscList[i].name);
                    creep.valueRscMin[i] = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.valueRscMin[i]);
                    creep.valueRscMax[i] = EditorGUI.IntField(new Rect(startX + spaceX + 40, startY, 40, height), creep.valueRscMax[i]);
                }
                startY += 5;
            }


            string[] creepNameList = EditorDBManager.GetCreepNameList();
            cont = new GUIContent("SpawnUponDestroyed:", "Creep prefab to be spawn when an instance of this unit is destroyed. Note that the HP of the spawned unit is inherit from the destroyed unit. Use HP-multiplier to specifiy how much of the HP should be carried forward");
            GUI.Label(new Rect(startX, startY += spaceY, width, height), cont);
            int ID = -1;

            for (int i = 0; i < creepList.Count; i++)
            {
                if (creepList[i].gameObject == creep.spawnUponDestroyed)
                {
                    ID = i + 1;
                }
            }
            ID = EditorGUI.Popup(new Rect(startX + spaceX + 30, startY, 120, height), ID, creepNameList);
            if (ID > 0 && creepList[ID - 1] != creep)
            {
                creep.spawnUponDestroyed = creepList[ID - 1].gameObject;
            }
            else if (ID == 0)
            {
                creep.spawnUponDestroyed = null;
            }

            if (creep.spawnUponDestroyed != null)
            {
                cont = new GUIContent(" - Num to Spawn:", "The amount of creep to spawn when this unit is destroyed");
                EditorGUI.LabelField(new Rect(startX + 20, startY += spaceY, width, height), cont);
                creep.spawnUponDestroyedCount = EditorGUI.IntField(new Rect(startX + spaceX + 30, startY, 40, height), creep.spawnUponDestroyedCount);

                cont = new GUIContent(" - HP Multiplier:", "The percentage of HP to pass to the next unit. 0.5 being 50% of parent unit's fullHP, 1 being 100% of parent unit's fullHP");
                EditorGUI.LabelField(new Rect(startX + 20, startY += spaceY, width, height), cont);
                creep.spawnUnitHPMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX + 30, startY, 40, height), creep.spawnUnitHPMultiplier);
            }

            startY += 20;


            if (creep.type == _CreepType.Offense)
            {
                cont = new GUIContent("Stop To Attack:", "Check to have the creep stop moving when there's target to attack");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                creep.stopToAttack = EditorGUI.Toggle(new Rect(startX + spaceX, startY, 40, height), creep.stopToAttack);
                startY            += spaceY;
            }
            v3 = DrawUnitOffensiveSetting(creep, startX, startY, objHList, objHLabelList);            startY = v3.y + 20; if (maxWidth < v3.z)
            {
                maxWidth = v3.z;
            }


            if (creep.type == _CreepType.Offense)
            {
                startY += 30;
            }

            UnitCreepAnimation ani = creep.gameObject.GetComponent <UnitCreepAnimation>();

            if (ani == null)
            {
                if (GUI.Button(new Rect(startX, startY, width + 50, height + 2), "Add animation component"))
                {
                    ani = creep.gameObject.AddComponent <UnitCreepAnimation>();
                }
            }

            if (ani != null)
            {
                if (GUI.Button(new Rect(startX, startY, width + 50, height + 2), "Remove animation component"))
                {
                    DestroyImmediate(ani, true);
                    //creep.gameObject.GetComponent<UnitCreepAnimation>();
                    return(new Vector3(startX, startY, maxWidth));
                }

                startY += 5;

                type  = (int)ani.type;
                cont  = new GUIContent("Type:", "Type of the animation to use");
                contL = new GUIContent[animationTypeLabel.Length];
                for (int i = 0; i < contL.Length; i++)
                {
                    contL[i] = new GUIContent(animationTypeLabel[i], animationTypeTooltip[i]);
                }
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                type     = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), type, contL);
                ani.type = (UnitCreepAnimation._AniType)type;

                if (ani.type == UnitCreepAnimation._AniType.Legacy)
                {
                    int objID = GetObjectIDFromHList(ani.aniRootObj != null ? ani.aniRootObj.transform : null, objHList);
                    cont = new GUIContent("AnimationRootObj:", "The gameObject that contains the Animation component that runs the animation on the unit");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    objID          = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), objID, objHLabelList);
                    ani.aniRootObj = (objHList[objID] == null) ? null : objHList[objID];


                    cont = new GUIContent("Move Speed Multiplier:", "The multiplier used to match the move animation speed to the unit's move speed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.moveSpeedMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX + 30, startY, 40, height), ani.moveSpeedMultiplier);
                }
                else if (ani.type == UnitCreepAnimation._AniType.Mecanim)
                {
                    int objID = GetObjectIDFromHList(ani.aniRootObj != null ? ani.aniRootObj.transform : null, objHList);
                    cont = new GUIContent("Animator RootObj:", "The gameObject that contains the Animator component that control the animation on the unit");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    objID          = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), objID, objHLabelList);
                    ani.aniRootObj = (objHList[objID] == null) ? null : objHList[objID];
                }

                if (ani.type != UnitCreepAnimation._AniType.None)
                {
                    cont = new GUIContent("Spawn Clip:", "The animation clip to be played when the creep is destroyed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipSpawn = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipSpawn, typeof(AnimationClip), false);

                    cont = new GUIContent("Move Clip:", "The animation clip to be played when the creep is moving");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipMove = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipMove, typeof(AnimationClip), false);

                    cont = new GUIContent("Dead Clip:", "The animation clip to be played when the creep is destroyed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipDead = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipDead, typeof(AnimationClip), false);

                    cont = new GUIContent("Destination Clip:", "The animation clip to be played when the creep reach its destination");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipDestination = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipDestination, typeof(AnimationClip), false);
                }
            }



            return(new Vector3(startX, startY, maxWidth));
        }
示例#4
0
        void OnGUI()
        {
            if (window == null)
            {
                Init();
            }

            if (GUI.Button(new Rect(window.position.width - 110, 10, 100, 30), "Save"))
            {
                EditorDBManager.SetDirtyRsc();
            }

            if (GUI.Button(new Rect(10, 10, 100, 30), "New Resource"))
            {
                EditorDBManager.AddNewRsc();
            }

            List <Rsc> rscList = EditorDBManager.GetRscList();

            if (rscList.Count > 0)
            {
                GUI.Box(new Rect(5, 50, 50, 20), "ID");
                GUI.Box(new Rect(5 + 50 - 1, 50, 70 + 1, 20), "Texture");
                GUI.Box(new Rect(5 + 120 - 1, 50, 150 + 2, 20), "Name");
                GUI.Box(new Rect(5 + 270, 50, window.position.width - 280, 20), "");
            }

            int row = 0;

            for (int i = 0; i < rscList.Count; i++)
            {
                if (i % 2 == 0)
                {
                    GUI.color = new Color(.8f, .8f, .8f, 1);
                }
                else
                {
                    GUI.color = Color.white;
                }
                GUI.Box(new Rect(5, 75 + i * 49, window.position.width - 10, 50), "");
                GUI.color = Color.white;

                GUI.Label(new Rect(22, 15 + 75 + i * 49, 50, 20), rscList[i].ID.ToString());


                EditorUtilities.DrawSprite(new Rect(12 + 50, 3 + 75 + i * 49, 44, 44), rscList[i].icon, true);


                //rscList[i].name=EditorGUI.TextField(new Rect(5+120, 15+75+i*49, 150, 20), rscList[i].name);
                rscList[i].name = EditorGUI.TextField(new Rect(5 + 120, 5 + 75 + i * 49, 150, 18), rscList[i].name);
                GUI.Label(new Rect(5 + 120, 25 + 75 + i * 49, 120, 18), "Icon: ");
                rscList[i].icon = (Sprite)EditorGUI.ObjectField(new Rect(45 + 120, 25 + 75 + i * 49, 110, 18), rscList[i].icon, typeof(Sprite), false);

                if (delete != i)
                {
                    if (GUI.Button(new Rect(window.position.width - 35, 12 + 75 + i * 49, 25, 25), "X"))
                    {
                        delete = i;
                    }
                }
                else
                {
                    GUI.color = Color.red;
                    if (GUI.Button(new Rect(window.position.width - 65, 12 + 75 + i * 49, 25, 25), "X"))
                    {
                        EditorDBManager.RemoveRsc(i);
                        delete = -1;
                    }
                    GUI.color = Color.green;
                    if (GUI.Button(new Rect(window.position.width - 35, 12 + 75 + i * 49, 25, 25), "-"))
                    {
                        delete = -1;
                    }
                    GUI.color = Color.white;
                }

                row += 1;
            }


            if (GUI.changed)
            {
                EditorDBManager.SetDirtyRsc();
            }
        }
示例#5
0
        Vector3 DrawUnitConfigurator(float startX, float startY, List <UnitCreep> creepList)
        {
            UnitCreep creep = creepList[selectID];

            float maxWidth = 0;
            float cachedY  = startY;
            float cachedX  = startX;

            startX += 65;               //startY+=20;

            startX = cachedX;

            v3 = DrawIconAndName(creep, startX, startY);      startY = v3.y;    maxWidth = v3.z;

            cachedY = startY;

            v3 = DrawUnitDefensiveSetting(creep, startX, startY, objHList, objHLabelList);    startY = v3.y;    if (maxWidth < v3.z)
            {
                maxWidth = v3.z;
            }

            startY += 20;


            cont = new GUIContent("Flying:", "Check to mark the creep as flying unit.");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.flying = EditorGUI.Toggle(new Rect(startX + spaceX, startY, 40, height), creep.flying);

            cont = new GUIContent("Move Speed:", "Moving speed of the creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.moveSpeed = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 40, height), creep.moveSpeed);

            cont = new GUIContent("Life Cost:", "The amont of life taken from player when this creep reach it's destination");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.lifeCost = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.lifeCost);

            cont = new GUIContent("Life Gain:", "Life awarded to the player when player successfully destroy this creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.lifeValue = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.lifeValue);

            cont = new GUIContent("Energy Gain:", "Energy awarded to the player when player successfully destroy this creep");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
            creep.valueEnergyGain = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.valueEnergyGain);


            cont = new GUIContent("Resource Gain Upon Destroyed:", "The amont of life taken from player when this creep reach it's destination");
            EditorGUI.LabelField(new Rect(startX, startY += spaceY + 5, width + 150, height), cont);
            List <Rsc> rscList = EditorDBManager.GetRscList();

            for (int i = 0; i < rscList.Count; i++)
            {
                EditorUtilities.DrawSprite(new Rect(startX + 25, startY += spaceY - 2, 20, 20), rscList[i].icon);     startY += 2;
                EditorGUI.LabelField(new Rect(startX, startY, width, height), "    -       min/max");                //+rscList[i].name);
                creep.valueRscMin[i] = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), creep.valueRscMin[i]);
                creep.valueRscMax[i] = EditorGUI.IntField(new Rect(startX + spaceX + 40, startY, 40, height), creep.valueRscMax[i]);
            }
            startY += 5;


            startY = cachedY + spaceY;  startX += 300;


            //~ if(creep.type==_CreepType.Offense){
            //~ cont=new GUIContent("Stop To Attack:", "Check to have the creep stop moving when there's target to attack");
            //~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
            //~ creep.stopToAttack=EditorGUI.Toggle(new Rect(startX+spaceX, startY, 40, height), creep.stopToAttack);
            //~ startY+=spaceY;
            //~ }
            //~ v3=DrawUnitOffensiveSetting(creep, startX, startY, objHList, objHLabelList);		startY=v3.y+20;	if(maxWidth<v3.z) maxWidth=v3.z;


            //~ if(creep.type==_CreepType.Offense) startY+=30;

            UnitCreepAnimation ani = creep.gameObject.GetComponent <UnitCreepAnimation>();

            if (ani == null)
            {
                if (GUI.Button(new Rect(startX, startY, width + 50, height + 2), "Add animation component"))
                {
                    ani = creep.gameObject.AddComponent <UnitCreepAnimation>();
                }
            }

            if (ani != null)
            {
                if (GUI.Button(new Rect(startX, startY, width + 50, height + 2), "Remove animation component"))
                {
                    DestroyImmediate(ani, true);
                    //creep.gameObject.GetComponent<UnitCreepAnimation>();
                    return(new Vector3(startX, startY, maxWidth));
                }

                startY += 5;

                int type = (int)ani.type;
                cont  = new GUIContent("Type:", "Type of the animation to use");
                contL = new GUIContent[animationTypeLabel.Length];
                for (int i = 0; i < contL.Length; i++)
                {
                    contL[i] = new GUIContent(animationTypeLabel[i], animationTypeTooltip[i]);
                }
                //cont=new GUIContent("AnimationRootObj:", "The gameObject that contains the Animation component that runs the animation on the unit");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                type     = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), type, contL);
                ani.type = (UnitCreepAnimation._AniType)type;

                if (ani.type == UnitCreepAnimation._AniType.Legacy)
                {
                    int objID = GetObjectIDFromHList(ani.aniRootObj != null ? ani.aniRootObj.transform : null, objHList);
                    cont = new GUIContent("AnimationRootObj:", "The gameObject that contains the Animation component that runs the animation on the unit");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    objID          = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), objID, objHLabelList);
                    ani.aniRootObj = (objHList[objID] == null) ? null : objHList[objID];


                    cont = new GUIContent("Move Speed Multiplier:", "The multiplier used to match the move animation speed to the unit's move speed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.moveSpeedMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX + 30, startY, 40, height), ani.moveSpeedMultiplier);
                }
                else if (ani.type == UnitCreepAnimation._AniType.Mecanim)
                {
                    int objID = GetObjectIDFromHList(ani.aniRootObj != null ? ani.aniRootObj.transform : null, objHList);
                    cont = new GUIContent("Animator RootObj:", "The gameObject that contains the Animator component that control the animation on the unit");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    objID          = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, height), objID, objHLabelList);
                    ani.aniRootObj = (objHList[objID] == null) ? null : objHList[objID];

                    //~ cont=new GUIContent("Dead Clip:", "The animation clip played by the animator when the creep is destroyed. This is required to know the duration of the animation");
                    //~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
                    //~ ani.clipDead=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+spaceX, startY, width, height), ani.clipDead, typeof(AnimationClip), false);

                    //~ cont=new GUIContent("Destination Clip:", "The animation clip played by the animator when the creep reach its destination. This is required to know the duration of the animation");
                    //~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
                    //~ ani.clipDestination=(AnimationClip)EditorGUI.ObjectField(new Rect(startX+spaceX, startY, width, height), ani.clipDestination, typeof(AnimationClip), false);
                }

                if (ani.type != UnitCreepAnimation._AniType.None)
                {
                    cont = new GUIContent("Spawn Clip:", "The animation clip to be played when the creep is destroyed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipSpawn = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipSpawn, typeof(AnimationClip), false);

                    cont = new GUIContent("Move Clip:", "The animation clip to be played when the creep is moving");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipMove = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipMove, typeof(AnimationClip), false);

                    cont = new GUIContent("Dead Clip:", "The animation clip to be played when the creep is destroyed");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipDead = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipDead, typeof(AnimationClip), false);

                    cont = new GUIContent("Destination Clip:", "The animation clip to be played when the creep reach its destination");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    ani.clipDestination = (AnimationClip)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), ani.clipDestination, typeof(AnimationClip), false);
                }
            }



            //GUI.Box(new Rect(cachedX, cachedY, maxWidth, 10), "");

            return(new Vector3(startX, startY, maxWidth));
        }
        public static Vector3 DrawStat(UnitStat stat, float startX, float startY, float statContentHeight, UnitTower tower, UnitCreep creep)
        {
            List <Rsc> rscList = EditorDBManager.GetRscList();

            float width  = 150;
            float fWidth = 35;
            float spaceX = 130;
            float height = 18;
            float spaceY = height + 2;

            //startY-=spaceY;

            GUI.Box(new Rect(startX, startY, 220, statContentHeight - startY), "");

            startX += 10;     startY += 10;

            if (tower != null)
            {
                cont = new GUIContent("Construct Duration:", "The time in second it takes to construct (if this is the first level)/upgrade (if this is not the first level)");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.buildDuration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buildDuration);

                cont = new GUIContent("Deconstruct Duration:", "The time in second it takes to deconstruct if the unit is in this level");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.unBuildDuration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.unBuildDuration);


                if (stat.cost.Count != rscList.Count)
                {
                    while (stat.cost.Count > rscList.Count)
                    {
                        stat.cost.RemoveAt(stat.cost.Count - 1);
                    }
                    while (stat.cost.Count < rscList.Count)
                    {
                        stat.cost.Add(0);
                    }
                }
                cont = new GUIContent("Build/Upgrade Cost:", "The resource required to build/upgrade to this level");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                int count = 0;    startY += spaceY;         float cachedX = startX;
                for (int i = 0; i < rscList.Count; i++)
                {
                    EditorUtilities.DrawSprite(new Rect(startX + 10, startY - 1, 20, 20), rscList[i].icon);
                    stat.cost[i] = EditorGUI.IntField(new Rect(startX + 30, startY, fWidth, height), stat.cost[i]);
                    count       += 1;       startX += 65;
                    if (count == 3)
                    {
                        startY += spaceY; startX = cachedX;
                    }
                }
                startX = cachedX; startY += 5;

                startY += spaceY + 5;
            }



            if ((tower && TowerUseShootObject(tower)) || (creep && creep.type == _CreepType.Offense))
            {
                cont = new GUIContent("ShootObject:", "The shootObject used by the unit.\nUnit that intended to shoot at the target will not function correctly if this is left unassigned.");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.shootObject = (ShootObject)EditorGUI.ObjectField(new Rect(startX + spaceX - 50, startY, 4 * fWidth - 20, height), stat.shootObject, typeof(ShootObject), false);
                startY          += 5;
            }

            if (tower && TowerUseShootObjectT(tower))
            {
                cont = new GUIContent("ShootObject:", "The shootObject used by the unit.\nUnit that intended to shoot at the target will not function correctly if this is left unassigned.");
                EditorGUI.LabelField(new Rect(startX, startY, width, height), cont);
                stat.shootObjectT = (Transform)EditorGUI.ObjectField(new Rect(startX + spaceX - 50, startY, 4 * fWidth - 20, height), stat.shootObjectT, typeof(Transform), false);
                startY           += 5;
            }

            if ((tower && TowerDealDamage(tower)) || (creep && creep.type == _CreepType.Offense))
            {
                cont = new GUIContent("Damage(Min/Max):", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.damageMin = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.damageMin);
                stat.damageMax = EditorGUI.FloatField(new Rect(startX + spaceX + fWidth, startY, fWidth, height), stat.damageMax);

                cont = new GUIContent("Cooldown:", "Duration between each attack");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.cooldown = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.cooldown);


                cont = new GUIContent("Range:", "Effect range of the unit");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.range = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.range);

                //~ cont=new GUIContent("Range(Min/Max):", "");
                //~ EditorGUI.LabelField(new Rect(startX, startY+=spaceY, width, height), cont);
                //~ stat.minRange=EditorGUI.FloatField(new Rect(startX+spaceX, startY, fWidth, height), stat.minRange);
                //~ stat.range=EditorGUI.FloatField(new Rect(startX+spaceX+fWidth, startY, fWidth, height), stat.range);

                cont = new GUIContent("AOE Radius:", "Area-of-Effective radius. When the shootObject hits it's target, any other hostile unit within the area from the impact position will suffer the same target as the target.\nSet value to >0 to enable. ");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.aoeRadius = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.aoeRadius);



                cont = new GUIContent("Hit Chance:", "Take value from 0-1. 0 being 0% and 1 being 100%. Final value are subject to target's dodgeChance. Assume two targets with 0 dodgeChance and .2 dodgeChance and the hitChance set to 1, the unit will always hits the target and have 20% chance to miss the second target.");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.hit = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.hit);

                if (!creep)
                {
                    cont = new GUIContent("Dodge Chance:", "Take value from 0-1. 0 being 0% and 1 being 100%. Final value are subject to target's hitChance. Assume two attackers with 1 hitChance and .8 hitChance and the dodgeChance set to .2, the chances to dodge attack from each attacker are 20% and 40% respectively.");
                    EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                    stat.dodge = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dodge);
                }


                cont = new GUIContent("Stun", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Chance:", "Chance to stun the target in each successful attack. Takes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.stun.chance = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.stun.chance);

                cont = new GUIContent("        - Duration:", "The stun duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.stun.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.stun.duration);



                cont = new GUIContent("Critical", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("            - Chance:", "Chance to score critical hit in attack. Takes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.crit.chance = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.crit.chance);

                cont = new GUIContent("            - Multiplier:", "Damage multiplier for successful critical hit. Takes value from 0 and above with with 0.5 being 50% of normal damage as bonus");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.crit.dmgMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.crit.dmgMultiplier);



                cont = new GUIContent("Slow", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("         - Duration:", "The effect duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.slow.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.slow.duration);

                cont = new GUIContent("         - Multiplier:", "Move speed multiplier. Takes value from 0-1 with with 0.7 being decrese default speed by 30%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.slow.slowMultiplier = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.slow.slowMultiplier);



                cont = new GUIContent("Dot", "Damage over time");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Duration:", "The effect duration in second");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.duration = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.duration);

                cont = new GUIContent("        - Interval:", "Duration between each tick. Damage is applied at each tick.");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.interval = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.interval);

                cont = new GUIContent("        - Damage:", "Damage applied at each tick");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.dot.value = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.dot.value);



                cont = new GUIContent("InstantKill", "");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("                - Chance:", "The chance to instant kill the target. Takes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.instantKill.chance = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.instantKill.chance);

                cont = new GUIContent("        - HP Threshold:", "The HP threshold of the target in order for the instantKill to become valid. Take value from 0-1 with 0.3 being 30% of the fullHP.");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.instantKill.HPThreshold = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.instantKill.HPThreshold);


                cont = new GUIContent("Damage Shield Only:", "When checked, unit will only inflict shield damage");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.damageShieldOnly = EditorGUI.Toggle(new Rect(startX + spaceX, startY, fWidth, height), stat.damageShieldOnly);

                cont = new GUIContent("Shield Break:", "The chance of the unit's attack to damage target's shield and disable shield regen permenantly\nTakes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.shieldBreak = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.shieldBreak);

                cont = new GUIContent("Shield Pierce:", "The chance of the unit's attack to bypass target's shield and damage HP directly\nTakes value from 0-1 with 0 being 0% and 1 being 100%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.shieldPierce = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.shieldPierce);
            }



            if ((tower && tower.type == _TowerType.Support) || (creep && creep.type == _CreepType.Support))
            {
                cont = new GUIContent("Range:", "Effect range of the unit");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.range = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.range);
                startY    += 5;

                cont = new GUIContent("Buff:", "Note: Buffs from multple tower doesnt stack, however when there's difference in the buff strength, the stronger buff applies. A tower can gain maximum dmage buff from one source and maximum range buff from another");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);    startY -= spaceY;

                cont = new GUIContent("        - Damage:", "Damage buff multiplier. Takes value from 0 and above with 0.5 being 50% increase in damage");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.damageBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.damageBuff);

                cont = new GUIContent("        - Cooldown:", "Dooldown buff multiplier. Takes value from 0-1 with 0.2 being reduce cooldown by 20%");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.cooldownBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.cooldownBuff);

                cont = new GUIContent("        - Range:", "Range buff multiplier. Takes value from 0 and above with 0.5 being 50% increase in range");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.rangeBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.rangeBuff);

                cont = new GUIContent("        - Critical:", "Critical hit chance buff modifier. Takes value from 0 and above with 0.25 being 25% increase in critical hit chance");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.criticalBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.criticalBuff);

                cont = new GUIContent("        - Hit:", "Hit chance buff modifier. Takes value from 0 and above with .2 being 20% increase in hit chance");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.hitBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.hitBuff);

                cont = new GUIContent("        - Dodge:", "Dodge chance buff modifier. Takes value from 0 and above with 0.15 being 15% increase in dodge chance");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.dodgeBuff = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.dodgeBuff);

                cont = new GUIContent("        - HP Regen:", "HP Regeneration Buff. Takes value from 0 and above with 2 being gain 2HP second ");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.buff.regenHP = EditorGUI.FloatField(new Rect(startX + spaceX, startY, fWidth, height), stat.buff.regenHP);
            }


            if (tower && tower.type == _TowerType.Resource)
            {
                if (stat.rscGain.Count != rscList.Count)
                {
                    while (stat.rscGain.Count > rscList.Count)
                    {
                        stat.rscGain.RemoveAt(stat.rscGain.Count - 1);
                    }
                    while (stat.rscGain.Count < rscList.Count)
                    {
                        stat.rscGain.Add(0);
                    }
                }
                cont = new GUIContent("Resource Gain:", "The resource gain by unit at each cooldown interval\nOnly applicable to ResourceTower");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                int count = 0;    startY += spaceY;         float cachedX = startX;
                for (int i = 0; i < rscList.Count; i++)
                {
                    EditorUtilities.DrawSprite(new Rect(startX + 10, startY - 1, 20, 20), rscList[i].icon);
                    stat.rscGain[i] = EditorGUI.IntField(new Rect(startX + 30, startY, fWidth, height), stat.rscGain[i]);
                    count          += 1;       startX += 65;
                    if (count == 3)
                    {
                        startY += spaceY; startX = cachedX;
                    }
                }
                startX = cachedX; startY += 5;
            }


            if (tower)
            {
                startY += 10;
                cont    = new GUIContent("Custom Description:", "Check to use use custom description. If not, the default one (generated based on the effect) will be used");
                EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont);
                stat.useCustomDesp = EditorGUI.Toggle(new Rect(startX + spaceX, startY, 40, height), stat.useCustomDesp);
                if (stat.useCustomDesp)
                {
                    GUIStyle style = new GUIStyle("TextArea");
                    style.wordWrap = true;
                    stat.desp      = EditorGUI.TextArea(new Rect(startX, startY + spaceY - 3, 200, 90), stat.desp, style);
                    startY        += 90;
                }
            }



            statContentHeight = startY + spaceY + 5;

            return(new Vector3(startX + 220, startY, statContentHeight));
        }