Forum begins after the advertisement:


[Part 9] Feedback: unpause, audio, random bug

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 9] Feedback: unpause, audio, random bug

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #13463
    Allan Valin
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    Hey,

    The unpause method wasn’t working, but the solution was in a previous forum post.

    Some AudioSource details aren’t mentioned or repeated every time in the video:

    • main menu: not mentioned to add the audio mixer to the audio source (it works without, but I assume if you change the volume it won’t be affected)
    • pause menu: adding audio source isn’t at all mentioned (or at least shown)
    • player audio: finally mentioned to add the audio mixer, which prompted me to go to the two previous sections to solve the problems.

    I wasn’t sure if I had to add the DestroyInMainMenu script to ALL prefabs, but I did it anyway. It says to add to the Singleton prefabs. Are there ones that aren’t singletons? idk

    Sometimes when I used Desolate Dive the ground collision isn’t detected, I tried recording it, but after 2 minutes trying the bug decided to disappear lol kinda randomly appears.

    Back to my previous being damaged when attacking problem: At 22:40 (part 9) code I saw that the code shown is different from what is shown on the video where the code is shown. Basically if (hasTakenDamage) return; isn’t there and the method name is different as well.

    <code>
        public virtual void EnemyHit(float _damageDone, Vector2 _hitDirection, float _hitForce)
        {
            if (hasTakenDamage) return;
    
            health -= _damageDone;
            if (!isRecoiling)
            {
                GameObject _orangeBlood = Instantiate(orangeBlood, transform.position, Quaternion.identity);
                Destroy(_orangeBlood, 5.5f);
                rb.velocity = _hitForce * recoilFactor * _hitDirection;
            }
            hasTakenDamage = true;
    
        }
    </code>

    Since that a code that is different from what was given and seems to work differently, I wonder if it could be the culprit. Which is supposed to be the “real” version?

    All in all, aside from a couple fast forwards making things difficult to understand what was done, part 9 was one of the easiest videos to follow.

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

    Thanks for posting this Allan. I’ve pinned this topic so that we can review this while working on the revamp. Also gave you another Bug Reporter + Content Contributor badge as thanks for your help in typing this out.

    Regarding the EnemyHit() function, can you show me what the other code is? I’ll have a read and give you my thoughts on it.

    #13492
    Allan Valin
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    Inside Enemy the variable protected bool hasTakenDamage = false; is already initialized, but changing that doesn’t seems to make a difference. In both cases, I tried jumping over an enemy while hitting another on the right, that causes the DownAttackTransform to freeze the player on the air taking damage multiple times in a row.

    While before the code wasn’t showing any errors, after changing hasTakenDamage between not having a starting value and returning it to the having one, now I can see two of them.

    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.Graphs.Edge.WakeUp () (at <84411d99c4a04a5f824cb9590142af8d>:0)
    UnityEditor.Graphs.Graph.DoWakeUpEdges (System.Collections.Generic.List<code>1[T] inEdges, System.Collections.Generic.List</code>1[T] ok, System.Collections.Generic.List`
    1[T] error, System.Boolean inEdgesUsedToBeValid) (at <84411d99c4a04a5f824cb9590142af8d>:0)
    UnityEditor.Graphs.Graph.WakeUpEdges (System.Boolean clearSlotEdges) (at <84411d99c4a04a5f824cb9590142af8d>:0)
    UnityEditor.Graphs.Graph.WakeUp (System.Boolean force) (at <84411d99c4a04a5f824cb9590142af8d>:0)
    UnityEditor.Graphs.Graph.WakeUp () (at <84411d99c4a04a5f824cb9590142af8d>:0)
    UnityEditor.Graphs.Graph.OnEnable () (at <84411d99c4a04a5f824cb9590142af8d>:0)
    ArgumentNullException: Value cannot be null.
    Parameter name: _unity_self
    UnityEditor.SerializedObject.FindProperty (System.String propertyPath) (at <9920ff0c944845d7b9f9a61ef1478edc>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindPropertyRelative (UnityEngine.UIElements.IBindable field, UnityEditor.SerializedProperty parentProperty) (at <8c3449848bd845499081ddbe4a09b367>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <8c3449848bd845499081ddbe4a09b367>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.ContinueBinding (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <8c3449848bd845499081ddbe4a09b367>:0)
    UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation+BindingRequest.Bind (UnityEngine.UIElements.VisualElement element) (at <8c3449848bd845499081ddbe4a09b367>:0)
    UnityEngine.UIElements.VisualTreeBindingsUpdater.Update () (at <7c69dfc1e63a4ea388c73014d3c7ce20>:0)
    UnityEngine.UIElements.VisualTreeUpdater.UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase phase) (at <7c69dfc1e63a4ea388c73014d3c7ce20>:0)
    UnityEngine.UIElements.Panel.UpdateBindings () (at <7c69dfc1e63a4ea388c73014d3c7ce20>:0)
    UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.UpdateSchedulers () (at <7c69dfc1e63a4ea388c73014d3c7ce20>:0)
    UnityEngine.UIElements.UIEventRegistration.UpdateSchedulers () (at <7c69dfc1e63a4ea388c73014d3c7ce20>:0)
    UnityEditor.RetainedMode.UpdateSchedulers () (at <8c3449848bd845499081ddbe4a09b367>:0)

    Here are all the times I found a mention of EnemyHit().

    PlayerController

    void Hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilBool, Vector2 _recoilDir, float _recoilStrength)
    {
        Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
    
        if (objectsToHit.Length > 0)
        {
            _recoilBool = true;
        }
        for (int i = 0; i < objectsToHit.Length; i++)
        {
            if (objectsToHit[i].GetComponent<Enemy>() != null)
            {
                objectsToHit[i].GetComponent<Enemy>().EnemyHit(damage, _recoilDir, _recoilStrength);
    
                if (objectsToHit[i].CompareTag("Enemy"))
                {
                    Mana += manaGain;
                }
            }
        }
    
    private void OnTriggerEnter2D(Collider2D _other) //for up and down cast spell
    {
        if (_other.GetComponent<Enemy>() != null && pState.casting)
        {
            _other.GetComponent<Enemy>().EnemyHit(spellDamage, (_other.transform.position - transform.position).normalized, -recoilYSpeed);
        }
    }

    Enemy

    public virtual void EnemyHit(float _damageDone, Vector2 _hitDirection, float _hitForce)
    {
        if (hasTakenDamage) return;
    
        health -= _damageDone;
        if (!isRecoiling)
        {
            audioSource.PlayOneShot(hurtSound);
            GameObject _orangeBlood = Instantiate(orangeBlood, transform.position, Quaternion.identity);
            Destroy(_orangeBlood, 5.5f);
            rb.velocity = _hitForce * recoilFactor * _hitDirection;
        }
        hasTakenDamage = true;
    
    }

    Bat

    public override void EnemyHit(float _damageDone, Vector2 _hitDirection, float _hitForce)
    {
        base.EnemyHit(_damageDone, _hitDirection, _hitForce);
    
        if (health > 0) ChangeState(EnemyStates.Bat_Stunned);
        else ChangeState(EnemyStates.Bat_Death);
    
    }

    Fireball

    private void OnTriggerEnter2D(Collider2D _other)
    {
        if (_other.tag == "Enemy")
        {
            _other.GetComponent<Enemy>().EnemyHit(damage, (_other.transform.position - transform.position).normalized, -hitForce);
        }
    }

    I also noticed that my enemies didn’t have an Anim animator assigned to them, so I just added the same that was below them in the Inspector. Didn’t seem to change anything.

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

    To answer this question of yours:

    Since that a code that is different from what was given and seems to work differently, I wonder if it could be the culprit. Which is supposed to be the “real” version?

    I suspect the if(hasTakenDamage) return; line is there to prevent an enemy from taking more than 1 instance of damage in a single frame. This can happen if the enemy has multiple colliders, and your attack collider overlaps with at least 1 of them. It is a “cheap” way of doing this — the better (but harder) way will be to build your combat system in such a way that it circumvents this error entirely.

    That being said. Keeping this there would be a better choice than leaving it out.

    #13652
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    It’s a bit late, but to add on, the hasTakenDamage is likely a bugfix as mentioned for an issue presented during the series’ creation.

    [Part 3] Multiple colliders on Enemy causing multiple hits

    Thus, it’s likely the creators had integrated this fix without mentioning it.

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

Go to Login Page →


Advertisement below: