Forum begins after the advertisement:


[Part 15] Garlic doesn’t deal damage

Home Forums Video Game Tutorial Series Creating a Rogue-like Shoot-em Up in Unity [Part 15] Garlic doesn’t deal damage

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #13904
    Nydeth
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    Hello!

    I’ve been following the YT guide but, as I said in the comments, I got lost creating Garlic. It doesn’t deal any damage but registers the hits when colliding with enemies.

    I’ll show you what happens

    This is the Aura.cs code:

    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// An aura is a damage over time effect that applies to a specific area in timed intervals.
    /// </summary>
    
    public class Aura : WeaponEffect
    {
        Dictionary<EnemyStats, float> affectedTargets = new Dictionary<EnemyStats, float>();
        List<EnemyStats> targetsToUnaffect = new List<EnemyStats>();
    
        void Update()
        {
            Dictionary<EnemyStats, float> affectedTargsCopy = new Dictionary<EnemyStats, float>(affectedTargets);
    
            // Loop through every target affected by the aura and reduce the cooldown
            // of the aura for it. If the cooldown reaches 0, deal damage to it
            foreach (KeyValuePair<EnemyStats, float> pair in affectedTargsCopy)
            {
                affectedTargets[pair.Key] -= Time.deltaTime;
                if (pair.Value <= 0 )
                {
                    if (targetsToUnaffect.Contains(pair.Key))
                    {
                        // If the target is marked for removal, remove it
                        affectedTargets.Remove(pair.Key);
                        targetsToUnaffect.Remove(pair.Key);
                    }
                } else
                {
                    // Reset the cooldown and deal damage
                    Weapon.Stats stats = weapon.GetStats();
                    affectedTargets[pair.Key] = stats.cooldown;
                    pair.Key.TakeDamage(GetDamage(), transform.position, stats.knockback);
                }
            }
        }
    
        void OnTriggerEnter2D(Collider2D other)
        {
            if (other.TryGetComponent(out EnemyStats es))
            {
                Debug.Log("No Hit");
                // If the target is not yet affected by this aura,
                // add it to our list of affected targets
                if (!affectedTargets.ContainsKey(es))
                {
                    Debug.Log("Hit!");
                    // Always starts with an interval of 0,
                    // so that'll get damaged in the next Update() tick
                    affectedTargets.Add(es, 0);
                } else
                {
    
                    Debug.Log("Refresh hit list");
                    if (targetsToUnaffect.Contains(es)) targetsToUnaffect.Remove(es);
                }
            }
        }
    
        void OnTriggerExit2D(Collider2D other)
        {
            if (other.TryGetComponent(out EnemyStats es))
            {
                // Don't directly remove the target upon leaving
                // because we still have to track their cooldowns
                if (affectedTargets.ContainsKey(es)) targetsToUnaffect.Add(es);
            }
        }
    }

    This is what happens when I chose the garlic character, the console logs and garlic configuration in Unity:

    View post on imgur.com

    As you can see, one of the obvious things is that I never get the Refresh hit list message on the console.
    I’m not dealing damage but the weapon exists, somehow.

    #13914
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    This is a tricky one. I’ve crossed checked your code with the one in our article, and it is the same as what you’ve posted. Let’s try logging the number of items in the array, so that it can help us get a glimpse of what is wrong with the tracking system:

        void OnTriggerEnter2D(Collider2D other)
        {
            if (other.TryGetComponent(out EnemyStats es))
            {
                Debug.Log("No Hit");
                // If the target is not yet affected by this aura,
                // add it to our list of affected targets
                if (!affectedTargets.ContainsKey(es))
                {
                    Debug.Log("Hit! Number of affected targets: " + affectedTargets.Count);
                    // Always starts with an interval of 0,
                    // so that'll get damaged in the next Update() tick
                    affectedTargets.Add(es, 0);
                } else
                {
    
                    Debug.Log("Refresh hit list");
                    if (targetsToUnaffect.Contains(es)) targetsToUnaffect.Remove(es);
                }
            }
        }

    Take note of how many enemies are supposed to be in the garlic’s area of effect — does it tally with what is shown visually?

    #13915
    Nydeth
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    I added that line of code and it starts from 0. So, 1 enemy inside the garlic area triggers the message Number of affected targets: 0.

    #13916
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    That number is correct. Because it prints the number before we add the new enemy to the Dictionary.

    How about when you have more than 1 enemy? Does it also print 0?

    #13918
    Nydeth
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    No, it just shows the amount of enemies -1.
    Enemies on screen: 3
    Log: 2

    Like this:

    View post on imgur.com

    #13931
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Alright, then let’s check for 2 more things here:

    • That you have assigned a damage value to the weapon data.
    • That the enemy loses health after you do TakeDamage() to it.

    For the first one, let’s add another debug here:

        void Update()
        {
            Dictionary<EnemyStats, float> affectedTargsCopy = new Dictionary<EnemyStats, float>(affectedTargets);
    
            // Loop through every target affected by the aura and reduce the cooldown
            // of the aura for it. If the cooldown reaches 0, deal damage to it
            foreach (KeyValuePair<EnemyStats, float> pair in affectedTargsCopy)
            {
                affectedTargets[pair.Key] -= Time.deltaTime;
                if (pair.Value <= 0 )
                {
                    if (targetsToUnaffect.Contains(pair.Key))
                    {
                        // If the target is marked for removal, remove it
                        affectedTargets.Remove(pair.Key);
                        targetsToUnaffect.Remove(pair.Key);
                    }
                } else
                {
                    // Reset the cooldown and deal damage
                    Weapon.Stats stats = weapon.GetStats();
                    affectedTargets[pair.Key] = stats.cooldown;
                    pair.Key.TakeDamage(GetDamage(), transform.position, stats.knockback);
                    Debug.Log("Dealing " + GetDamage() + " to " + pair.Key.gameObject.name);
                }
            }
        }

    For the second one, you’ll have to enter Debug mode on the Inspector and watch the enemy’s health when it gets hit.

    #13943
    Nydeth
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    I’ve done what you said and never reaches this part of the code:

    // Reset the cooldown and deal damage
                    Weapon.Stats stats = weapon.GetStats();
                    affectedTargets[pair.Key] = stats.cooldown;
                    pair.Key.TakeDamage(GetDamage(), transform.position, stats.knockback);
                    Debug.Log("Dealing " + GetDamage() + " to " + pair.Key.gameObject.name);

    I’m not getting that log message and I deleted the [HideInInspector] tag of currentHealth in EnemyStats, played with debug mode and the health wasn’t going down when inside the garlic area.

    As I’m trying to do damage, I modified the OnTriggerEnter2D function:

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.TryGetComponent(out EnemyStats es))
        {
            Debug.Log("No Hit");
            // If the target is not yet affected by this aura,
            // add it to our list of affected targets
            if (!affectedTargets.ContainsKey(es))
            {
                Weapon.Stats stats = weapon.GetStats();
                es.TakeDamage(GetDamage(), transform.position, stats.knockback);
                Debug.Log("Hit! Number of affected targets: " + affectedTargets.Count);
                // Always starts with an interval of 0,
                // so that'll get damaged in the next Update() tick
                affectedTargets.Add(es, 0);
            } else
            {
                Debug.Log("Refresh hit list");
                if (targetsToUnaffect.Contains(es)) targetsToUnaffect.Remove(es);
            }
        }
    }

    Adding the weapon stats and making the enemies (Only enemies, not dealing damage to props) get damage works but it damages them every tick, which is not intended as it should have a cooldown:

    View post on imgur.com

    By the way, I have another doubts about why am I collecting exp without actually getting the blue gem. Should I create a new topic after watching the Part 17 video? Because I don’t see it happens to you.

    #13947
    Nydeth
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    I’ve asked GPT what happens with the code and why I’m not dealing damage and here is what he changed:

    In the Update, he said to switch the logic to this:

    void Update()
    {
        Dictionary<EnemyStats, float> affectedTargsCopy = new Dictionary<EnemyStats, float>(affectedTargets);
    
        // Loop through every target affected by the aura and reduce the cooldown
        // of the aura for it. If the cooldown reaches 0, deal damage to it
        foreach (KeyValuePair<EnemyStats, float> pair in affectedTargsCopy)
        {
            affectedTargets[pair.Key] -= Time.deltaTime;
            if (pair.Value <= 0)
            {
                // Reset the cooldown and deal damage
                Weapon.Stats stats = weapon.GetStats();
                affectedTargets[pair.Key] = stats.cooldown;
                pair.Key.TakeDamage(GetDamage(), transform.position, stats.knockback);
                if (targetsToUnaffect.Contains(pair.Key))
                {
                    // If the target is marked for removal, remove it
                    affectedTargets.Remove(pair.Key);
                    targetsToUnaffect.Remove(pair.Key);
                }
            }
    
        }
    }

    So, you deal damage when the cooldown reaches 0 and then refresh. Now it works properly and I can deal damage to the enemies.

    #13953
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    That’s great. Glad you managed to fix this.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: