/// <summary> /// Updates unit's layers and tags. /// </summary> private void UpdateLayersAndTags() { if (unitData.gameObject != null) { switch (unitData.gameObject.gameObject.tag) { case "Tower": case "Defender": if (unitData.attack != null) { unitData.attack.gameObject.layer = LayerMask.NameToLayer("AttackAlly"); AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { trigger.tags.Clear(); trigger.tags.Add("Enemy"); trigger.tags.Add("FlyingEnemy"); } } if (unitData.attack != null) { unitData.attack.gameObject.layer = LayerMask.NameToLayer("AttackAlly"); AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { trigger.tags.Clear(); trigger.tags.Add("Enemy"); trigger.tags.Add("FlyingEnemy"); } } break; case "Enemy": case "FlyingEnemy": if (unitData.attack != null) { unitData.attack.gameObject.layer = LayerMask.NameToLayer("AttackEnemy"); AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { trigger.tags.Clear(); trigger.tags.Add("Defender"); } } if (unitData.attack != null) { unitData.attack.gameObject.layer = LayerMask.NameToLayer("AttackEnemy"); AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { trigger.tags.Clear(); trigger.tags.Add("Defender"); } } break; } } }
/// <summary> /// Raises the GU event. /// </summary> void OnGUI() { // Set visual theme GUI.skin = editorGuiSkin; if (EditorApplication.isPlaying == false) { switch (myState) { case MyState.Disabled: EditorGUILayout.HelpBox("Create your own units and towers", MessageType.Info); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); // Add new enemy button if (GUILayout.Button(contents.newEnemyButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Enemy", "Assets/TD2D/Prefabs/Units/Enemies/Units/Enemy"); } // Add new defender button if (GUILayout.Button(contents.newDefenderButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Defender", "Assets/TD2D/Prefabs/Units/Defenders/Defender"); } // Add new ranged tower button if (GUILayout.Button(contents.newTowerButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Tower", "Assets/TD2D/Prefabs/Units/Towers/Towers/MyTowers/Tower"); } // Add new barracks button if (GUILayout.Button(contents.newBarracksButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { CreateNewUnit("Assets/TD2D/Prefabs/Stuff/Templates/Barracks", "Assets/TD2D/Prefabs/Units/Towers/Towers/MyTowers/Barracks"); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); break; case MyState.Enemy: case MyState.Defender: case MyState.Tower: case MyState.Barracks: GUILayout.Space(guiSpace); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(unitData.gameObject.name); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (myState == MyState.Enemy || myState == MyState.Tower || myState == MyState.Barracks) { // Price if (unitData.price != null) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Price"); unitData.price.price = EditorGUILayout.IntField(unitData.price.price); EditorGUILayout.EndHorizontal(); GUILayout.Space(guiSpace); } } if (myState == MyState.Enemy || myState == MyState.Defender) { // Speed EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Speed"); unitData.navAgent.speed = EditorGUILayout.FloatField(unitData.navAgent.speed); EditorGUILayout.EndHorizontal(); // Hitpoints EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Hitpoints"); unitData.damageTaker.hitpoints = EditorGUILayout.IntField(unitData.damageTaker.hitpoints); EditorGUILayout.EndHorizontal(); } if (myState == MyState.Enemy) { // Flying flag bool flyingEnemy = EditorGUILayout.Toggle("Flying", unitData.flying); if (flyingEnemy != unitData.flying && unitData.gameObject != null) { unitData.gameObject.tag = flyingEnemy == true ? "FlyingEnemy" : "Enemy"; unitData.flying = flyingEnemy; } } if (myState == MyState.Enemy || myState == MyState.Defender || myState == MyState.Tower) { GUILayout.Space(guiSpace); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Attack"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } if (myState == MyState.Enemy || myState == MyState.Defender) { // Attack type string[] attackTypes = new string[] { "None", "Melee", "Ranged" }; int attackType = GUILayout.SelectionGrid(unitData.attackType, attackTypes, 1, EditorStyles.radioButton); if (attackType != unitData.attackType) { if (unitData.attack != null) { DestroyImmediate(unitData.attack.gameObject); unitData.attack = null; } switch (attackType) { case 1: Object meleeAttackPrefab = AssetDatabase.LoadAssetAtPath <Object>("Assets/TD2D/Prefabs/Stuff/AttackTypes/MeleeAttack.prefab"); if (meleeAttackPrefab != null) { GameObject meleeAttack = Instantiate(meleeAttackPrefab, unitData.gameObject.transform) as GameObject; meleeAttack.name = meleeAttackPrefab.name; unitData.attack = meleeAttack.GetComponent <Attack>(); } break; case 2: Object rangedAttackPrefab = AssetDatabase.LoadAssetAtPath <Object>("Assets/TD2D/Prefabs/Stuff/AttackTypes/RangedAttack.prefab"); if (rangedAttackPrefab != null) { GameObject rangedAttack = Instantiate(rangedAttackPrefab, unitData.gameObject.transform) as GameObject; rangedAttack.name = rangedAttackPrefab.name; unitData.attack = rangedAttack.GetComponent <Attack>(); } break; } unitData.attackType = attackType; Selection.activeObject = unitData.gameObject.gameObject; UpdateLayersAndTags(); } } if (myState == MyState.Enemy || myState == MyState.Defender || myState == MyState.Tower) { if (unitData.attack != null) { // Damage EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Damage"); unitData.attack.damage = EditorGUILayout.IntField(unitData.attack.damage); EditorGUILayout.EndHorizontal(); // Cooldown EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Cooldown"); unitData.attack.cooldown = EditorGUILayout.FloatField(unitData.attack.cooldown); EditorGUILayout.EndHorizontal(); // Range EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Range"); unitData.attack.transform.localScale = EditorGUILayout.FloatField(unitData.attack.transform.localScale.x) * Vector3.one; EditorGUILayout.EndHorizontal(); } if (unitData.attack is AttackRanged) { // Choose bullet button EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.chooseBulletButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { switch (unitData.gameObject.tag) { case "Defender": case "Tower": ShowPicker <GameObject>(PickerState.BulletAlly, Lables.bulletAlly); break; case "Enemy": case "FlyingEnemy": ShowPicker <GameObject>(PickerState.BulletEnemy, Lables.bulletEnemy); break; } } // Focus on firepoint button if (GUILayout.Button(contents.focusOnFirePointButton, GUILayout.MaxWidth(40f), GUILayout.MaxHeight(40f)) == true) { if ((unitData.attack as AttackRanged).firePoint != null) { Selection.activeGameObject = (unitData.attack as AttackRanged).firePoint.gameObject; } } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } } if (myState == MyState.Enemy) { if (unitData.aiFeature != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Features"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); AiFeature feature = (Selection.activeObject as GameObject).GetComponent <AiFeature>(); // Features buttons EditorGUILayout.BeginHorizontal(); if (GUILayout.Button(contents.add, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { ShowPicker <GameObject>(PickerState.Features, Lables.feature); } GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.prev, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { Selection.activeObject = unitData.aiFeature.GetPreviousFeature(Selection.activeObject as GameObject); } if (GUILayout.Button(contents.next, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { Selection.activeObject = unitData.aiFeature.GetNextFeature(Selection.activeObject as GameObject); } GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.remove, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { if (feature != null) { DestroyImmediate(feature.gameObject); Selection.activeObject = unitData.gameObject; } } EditorGUILayout.EndHorizontal(); if (feature != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(feature.name); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); AiFeaturesGUI(feature); } } } if (myState == MyState.Defender || myState == MyState.Tower) { if (unitData.attack != null) { // Targets EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Targets"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); bool land = EditorGUILayout.Toggle("Land", unitData.targetCommon); bool flying = EditorGUILayout.Toggle("Flying", unitData.targetFlying); if (land != unitData.targetCommon || flying != unitData.targetFlying) { AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { trigger.tags.Clear(); if (land == true) { trigger.tags.Add("Enemy"); } if (flying == true) { trigger.tags.Add("FlyingEnemy"); } } unitData.targetCommon = land; unitData.targetFlying = flying; } } } if (myState == MyState.Barracks) { if (unitData.spawner != null) { // Defenders number EditorGUILayout.LabelField("Defenders number"); unitData.spawner.maxNum = EditorGUILayout.IntSlider(unitData.spawner.maxNum, 1, 3); // Cooldown between defenders spawning EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Cooldown"); unitData.spawner.cooldown = EditorGUILayout.FloatField(unitData.spawner.cooldown); EditorGUILayout.EndHorizontal(); } if (unitData.range != null) { // Range EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Range"); unitData.range.transform.localScale = EditorGUILayout.FloatField(unitData.range.transform.localScale.x) * Vector3.one; EditorGUILayout.EndHorizontal(); } if (unitData.spawner != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Defender"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); // Defender prefab EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.chooseDefenderButton, GUILayout.MaxWidth(60f), GUILayout.MaxHeight(60f)) == true) { ShowPicker <GameObject>(PickerState.Defenders, Lables.defender); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); } } if (myState == MyState.Tower || myState == MyState.Barracks) { if (unitData.range != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Range"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); // Show range unitData.range.SetActive(EditorGUILayout.Toggle("Show range", unitData.range.activeSelf)); } if (unitData.towerActions != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Actions"); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); unitData.towerActions.gameObject.SetActive(EditorGUILayout.Toggle("Show actions", unitData.towerActions.gameObject.activeSelf)); // Actions buttons if (unitData.towerActions.gameObject.activeSelf == true) { TowerAction action = (Selection.activeObject as GameObject).GetComponent <TowerAction>(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button(contents.add, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { ShowPicker <GameObject>(PickerState.TowerActions, Lables.towerAction); } GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.prev, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { Selection.activeObject = unitData.towerActions.GetPrevioustAction(Selection.activeObject as GameObject); } if (GUILayout.Button(contents.next, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { Selection.activeObject = unitData.towerActions.GetNextAction(Selection.activeObject as GameObject); } GUILayout.FlexibleSpace(); if (GUILayout.Button(contents.remove, GUILayout.MaxWidth(30f), GUILayout.MaxHeight(30f)) == true) { if (action != null) { DestroyImmediate(action.gameObject); Selection.activeObject = unitData.gameObject; } } EditorGUILayout.EndHorizontal(); if (action != null) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(action.name); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); TowerActionsGUI(action); } } } } // New object selected in picker window if (Event.current.commandName == "ObjectSelectorUpdated" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) { pickedObject = EditorGUIUtility.GetObjectPickerObject(); if (pickedObject != null) { switch (pickerState) { case PickerState.BulletAlly: case PickerState.BulletEnemy: if (unitData.attack != null && unitData.attack is AttackRanged) { (unitData.attack as AttackRanged).arrowPrefab = pickedObject as GameObject; contents.chooseBulletButton.image = AssetPreview.GetAssetPreview((unitData.attack as AttackRanged).arrowPrefab); } break; case PickerState.Defenders: if (unitData.spawner != null) { unitData.spawner.prefab = pickedObject as GameObject; contents.chooseDefenderButton.image = AssetPreview.GetAssetPreview(unitData.spawner.prefab); } break; case PickerState.Towers: { TowerActionBuild towerActionBuild = (Selection.activeObject as GameObject).GetComponent <TowerActionBuild>(); if (towerActionBuild != null) { towerActionBuild.towerPrefab = pickedObject as GameObject; EditorUtility.SetDirty(towerActionBuild.gameObject); } } break; case PickerState.Icons: { TowerAction towerAction = (Selection.activeObject as GameObject).GetComponent <TowerAction>(); if (towerAction != null) { Image image = towerAction.enabledIcon.GetComponent <Image>(); if (image != null) { image.sprite = pickedObject as Sprite; EditorUtility.SetDirty(towerAction.gameObject); } } } break; } } } // Picker window closed if (Event.current.commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) { if (pickedObject != null) { switch (pickerState) { case PickerState.TowerActions: if (unitData.towerActions != null) { unitData.towerActions.AddAction(pickedObject as GameObject); } break; case PickerState.Features: if (unitData.aiFeature != null) { unitData.aiFeature.AddFeature(pickedObject as GameObject); } break; } } pickedObject = null; pickerState = PickerState.None; } break; } if (myState != MyState.Disabled) { GUILayout.Space(guiSpace); // Apply changes button if (unitData.gameObject != null && PrefabUtility.GetPrefabType(unitData.gameObject) != PrefabType.None) { if (GUILayout.Button(contents.applyChangesButton) == true) { if (unitData.towerActions != null) { unitData.towerActions.gameObject.SetActive(false); } if (unitData.range != null) { unitData.range.SetActive(false); } PrefabUtility.ReplacePrefab(unitData.gameObject.gameObject, PrefabUtility.GetPrefabParent(unitData.gameObject.gameObject), ReplacePrefabOptions.ConnectToPrefab); } // Remove from scene button if (GUILayout.Button(contents.removeFromSceneButton) == true) { DestroyImmediate(unitData.gameObject.gameObject); Selection.activeObject = null; } } } } else { EditorGUILayout.HelpBox("Editor disabled in play mode", MessageType.Info); } }
/// <summary> /// Raises the selection changed event. /// </summary> private void OnSelectionChanged() { myState = MyState.Disabled; unitData.Clear(); // Check for selected gameobject and fill unit descriptor if (Selection.GetFiltered <GameObject>(SelectionMode.ExcludePrefab).Length == 1) { unitData.tower = (Selection.activeObject as GameObject).GetComponentInParent <Tower>(); if (unitData.tower != null) // Tower { unitData.spawner = (Selection.activeObject as GameObject).GetComponentInParent <DefendersSpawner>(); if (unitData.spawner != null) // Barracks { myState = MyState.Barracks; unitData.gameObject = unitData.tower.gameObject; unitData.price = unitData.spawner.GetComponent <Price>(); unitData.tower = unitData.spawner.GetComponent <Tower>(); if (unitData.tower != null) { unitData.range = unitData.tower.range; if (unitData.tower.actions != null) { unitData.towerActions = unitData.tower.actions.GetComponent <TowerActionsInspector>(); } } if (unitData.spawner.prefab != null) { contents.chooseDefenderButton.image = AssetPreview.GetAssetPreview(unitData.spawner.prefab); } else { contents.chooseDefenderButton.image = null; } } else // Ranged tower { myState = MyState.Tower; unitData.gameObject = unitData.tower.gameObject; unitData.price = unitData.gameObject.GetComponent <Price>(); unitData.range = unitData.tower.range; if (unitData.tower.actions != null) { unitData.towerActions = unitData.tower.actions.GetComponent <TowerActionsInspector>(); } unitData.attack = unitData.gameObject.GetComponentInChildren <Attack>(); if (unitData.attack != null) { AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { unitData.targetCommon = trigger.tags.Contains("Enemy") ? true : false; unitData.targetFlying = trigger.tags.Contains("FlyingEnemy") ? true : false; } if ((unitData.attack is AttackRanged) && (unitData.attack as AttackRanged).arrowPrefab != null) { contents.chooseBulletButton.image = AssetPreview.GetAssetPreview((unitData.attack as AttackRanged).arrowPrefab); } else { contents.chooseBulletButton.image = null; } } } } else // Unit { AiBehavior aiBehavior = (Selection.activeObject as GameObject).GetComponentInParent <AiBehavior>(); if (aiBehavior != null) { unitData.gameObject = aiBehavior.gameObject; switch (unitData.gameObject.tag) { case "Enemy": goto case "FlyingEnemy"; case "FlyingEnemy": unitData.price = unitData.gameObject.GetComponent <Price>(); unitData.flying = unitData.gameObject.CompareTag("FlyingEnemy") ? true : false; unitData.aiFeature = unitData.gameObject.GetComponentInChildren <FeaturesInspector>(); goto case "Defender"; case "Defender": myState = unitData.gameObject.CompareTag("Defender") ? MyState.Defender : MyState.Enemy; unitData.navAgent = unitData.gameObject.GetComponent <NavAgent>(); unitData.damageTaker = unitData.gameObject.GetComponent <DamageTaker>(); unitData.attackType = 0; unitData.attack = unitData.gameObject.GetComponentInChildren <Attack>(); if (unitData.attack != null && (unitData.attack is AttackMelee)) { unitData.attackType = 1; AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { unitData.targetCommon = trigger.tags.Contains("Enemy") ? true : false; unitData.targetFlying = trigger.tags.Contains("FlyingEnemy") ? true : false; } } else if (unitData.attack != null && (unitData.attack is AttackRanged)) { unitData.attackType = 2; AiTriggerCollider trigger = unitData.attack.GetComponent <AiTriggerCollider>(); if (trigger != null) { unitData.targetCommon = trigger.tags.Contains("Enemy") ? true : false; unitData.targetFlying = trigger.tags.Contains("FlyingEnemy") ? true : false; } if ((unitData.attack as AttackRanged).arrowPrefab != null) { contents.chooseBulletButton.image = AssetPreview.GetAssetPreview((unitData.attack as AttackRanged).arrowPrefab); } else { contents.chooseBulletButton.image = null; } } break; } } } } }