virtual protected void DrawProjectileEditor(MultiProjectileData projectile, MultiProjectileAttackData attack) { // Projectile prefab GameObject prefab = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Projectile Prefab", "Prefab to use for the projectile. Created on fire."), projectile.projectilePrefab, typeof(GameObject), false); if (prefab != projectile.projectilePrefab) { projectile.projectilePrefab = prefab; } // Projectile delay float projectileDelay = EditorGUILayout.FloatField(new GUIContent("Projectile Delay", "Delay in seconds (from attack start) before the projectile is instantiated."), projectile.delay); // if (projectileDelay > attack.attackTime) projectileDelay = attack.attackTime; if (projectileDelay != projectile.delay) { projectile.delay = projectileDelay; } // Position Vector2 positionOffset = EditorGUILayout.Vector2Field(new GUIContent("Position Offset", "Additional position offset to apply to this projectile."), projectile.positionOffset); if (positionOffset.x != projectile.positionOffset.x || positionOffset.y != projectile.positionOffset.y) { projectile.positionOffset = positionOffset; } // Angle float angleOffset = EditorGUILayout.FloatField(new GUIContent("Angle Offset", "Additional rotation to apply to this prefab in degrees."), projectile.angleOffset); if (angleOffset != projectile.angleOffset) { projectile.angleOffset = angleOffset; } // Flip X/Y EditorGUILayout.BeginHorizontal(); bool flipX = EditorGUILayout.Toggle(new GUIContent("Flip X", "Flip X offset."), projectile.flipX); if (flipX != projectile.flipX) { projectile.flipX = flipX; } GUILayout.FlexibleSpace(); bool flipY = EditorGUILayout.Toggle(new GUIContent("Flip Y", "Flip Y offset."), projectile.flipY); if (flipY != projectile.flipY) { projectile.flipY = flipY; } EditorGUILayout.EndHorizontal(); // Remove projectile EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Remove Projectile", GUILayout.MinWidth(100))) { attack.projectileData.Remove(projectile); } EditorGUILayout.EndHorizontal(); // Draw a line // GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true)); }
/// <summary> /// Draws the inspector for a basic attack. /// </summary> /// <param name="attack">Attack.</param> virtual protected void DrawMultiProjectileAttackEditor(MultiProjectileAttackData attack) { // Add new button if (GUILayout.Button("Remove Attack")) { ((MultiProjectileAttacks)target).projectileData.Remove(attack); return; } string name = EditorGUILayout.TextField(new GUIContent("Name", "Human readable name (optional)."), attack.name); if (name != attack.name) { attack.name = name; } GUI.enabled = false; EditorGUILayout.EnumPopup(new GUIContent("Attack Type", "Attack which this combo triggers from. Empty or null means trigger from ANY other attack."), AttackType.PROJECTILE); GUI.enabled = true; // Force projectile attack.attackType = AttackType.PROJECTILE; AnimationState state = (AnimationState)EditorGUILayout.EnumPopup(new GUIContent("Animation", "The animation state to set for this attack."), attack.animation); if (state != attack.animation) { attack.animation = state; } AttackLocation location = (AttackLocation)EditorGUILayout.EnumPopup(new GUIContent("Location", "Where does the character need to be to trigger this attack."), attack.attackLocation); if (location != attack.attackLocation) { attack.attackLocation = location; } GUILayout.Label("Controls", EditorStyles.boldLabel); int buttonIndex = EditorGUILayout.IntField(new GUIContent("Action Button", "The index of the action button that needs to be pressed."), attack.actionButtonIndex); if (buttonIndex != attack.actionButtonIndex && buttonIndex >= 0f) { attack.actionButtonIndex = buttonIndex; } bool fireWhenHeld = EditorGUILayout.Toggle(new GUIContent("Allow Button Held", "If true fire when button held not just when its pressed."), attack.fireWhenHeld); if (fireWhenHeld != attack.fireWhenHeld) { attack.fireWhenHeld = fireWhenHeld; } GUILayout.Label("Timing", EditorStyles.boldLabel); float length = EditorGUILayout.FloatField(new GUIContent("Attack Length", "The animation length in seconds."), attack.attackTime); if (length != attack.attackTime && length > 0.0f) { attack.attackTime = length; } GUILayout.Label("Damage", EditorStyles.boldLabel); // Damage Info DamageType damageType = (DamageType)EditorGUILayout.EnumPopup(new GUIContent("Damage Type", "The type of damage this attack deals"), attack.damageType); if (damageType != attack.damageType) { attack.damageType = damageType; } int damageAmount = EditorGUILayout.IntField(new GUIContent("Damage Amount", "Amount of damage caused by this attack."), attack.damageAmount); if (damageAmount > 0 && damageAmount != attack.damageAmount) { attack.damageAmount = damageAmount; } GUILayout.Label("Other", EditorStyles.boldLabel); if (!((MultiProjectileAttacks)target).attackSystemWantsMovementControl) { showBlockingDetails = EditorGUILayout.Foldout(showBlockingDetails, "Movement Blocking"); if (showBlockingDetails) { // Block Jump bool blockJump = EditorGUILayout.Toggle(new GUIContent("Block Jump", "If true the attack system will not allow jumping whilst this attack is playing."), attack.blockJump); if (blockJump != attack.blockJump) { attack.blockJump = blockJump; } // Block Wall bool blockWall = EditorGUILayout.Toggle(new GUIContent("Block Wall Cling", "If true the attack system will not allow wall cling or slide whilst this attack is playing."), attack.blockWall); if (blockWall != attack.blockWall) { attack.blockWall = blockWall; } // Block Climb bool blockClimb = EditorGUILayout.Toggle(new GUIContent("Block Climb", "If true the attack system will not allow ladder or rope climbing whilst this attack is playing."), attack.blockClimb); if (blockClimb != attack.blockClimb) { attack.blockClimb = blockClimb; } // Block Special bool blockSpecial = EditorGUILayout.Toggle(new GUIContent("Block Special", "If true the attack system will not allow special movements whilst this attack is playing."), attack.blockSpecial); if (blockClimb != attack.blockSpecial) { attack.blockSpecial = blockSpecial; } } } else { // Apply gravity bool applyGravity = EditorGUILayout.Toggle(new GUIContent("Apply Gravity", "Should we apply gravity while this attack plays?"), attack.applyGravity); if (applyGravity != attack.applyGravity) { attack.applyGravity = applyGravity; } } GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true)); // Ammo item string ammoType = EditorGUILayout.TextField(new GUIContent("Ammo Type", "Item type to use for ammo. Empty means infinite ammo."), attack.ammoType); if (ammoType != attack.ammoType) { attack.ammoType = ammoType; } // Projectiles if (attack.projectileData == null) { attack.projectileData = new List <MultiProjectileData> (); } List <MultiProjectileData> projectiles = attack.projectileData.ToList(); foreach (MultiProjectileData projectile in projectiles) { DrawProjectileEditor(projectile, attack); } // Add new button if (GUILayout.Button("Add Projectile")) { MultiProjectileData projectile = new MultiProjectileData(); attack.projectileData.Add(projectile); } // Draw a line GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true)); }
/// <summary> /// Fires a single projectile. /// </summary> /// <param name="data">Data about projectile.</param> virtual protected IEnumerator FireSingleProjectile(MultiProjectileAttackData attack, MultiProjectileData data) { yield return(new WaitForSeconds(data.delay)); GameObject go = (GameObject)GameObject.Instantiate(data.projectilePrefab); Projectile projectile = go.GetComponent <Projectile>(); if (projectileAimer != null) { go.transform.position = character.transform.position + (Vector3)projectileAimer.GetAimOffset(character) + new Vector3(data.positionOffset.x * character.LastFacedDirection, data.positionOffset.y, 0); } else { go.transform.position = character.transform.position + new Vector3(data.positionOffset.x * character.LastFacedDirection, data.positionOffset.y, 0); } if (projectile != null) { // Fire projectile if the projectile is of type projectile Vector2 direction = new Vector2(character.LastFacedDirection != 0 ? character.LastFacedDirection : 1, 0); // Use aimer to get direction fo fire if the aimer is configured if (projectileAimer != null) { direction = projectileAimer.GetAimDirection(character); } direction = Quaternion.Euler(0, 0, data.angleOffset * character.LastFacedDirection) * direction; if (data.flipX) { direction.x *= -1; } if (data.flipY) { direction.y *= -1; } projectile.Fire(attack.damageAmount, attack.damageType, direction, character); } // If the projectile is found and the go is still alive call finish if (projectile != null && go != null) { projectile.Finish(); } ConsumeAmmo(attacks [currentAttack]); }