Forum begins after the advertisement:


[Part 15] Adding level up to treasure chest & NullReferenceException

Home Forums Video Game Tutorial Series Creating a Rogue-like Shoot-em Up in Unity [Part 15] Adding level up to treasure chest & NullReferenceException

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #14443
    Nathan
    Level 10
    Participant
    Helpful?
    Up
    0
    ::

    Hello,
    Near the end of part 15, the treasure chest script was updated and I wanted to add the ability to basically level up the player’s weapon or passives(if no evolution is available) by just calling StartLevelUp from the GameManager. After testing, I started getting a NullReferenceException.

    View post on imgur.com

    I then commented out the code I had added and placed a few Debug.log to check what is read and I noticed I get a NullReferenceException with the original script as well(my fault for forgetting to test). This happens when you attempt to pick up a chest without the ability to evolve, and it does not destroy the game object for some reason. I placed my current TreasureChest script below. Thank you.

    View post on imgur.com

    View post on imgur.com

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

    Update 3 May 2024: Fixed an error in the code.

    That’s partially an issue with the OpenTreasureChest() function. You can add a couple of extra checks to prevent the NullReferenceException. For the level up logic, you should put it after the foreach loop.

        public void OpenTreasureChest(PlayerInventory inventory, bool isHigherTier)
        {
            // Loop through every weapon to check whether it can evolve.
            foreach(PlayerInventory.Slot s in inventory.weaponSlots)
            {
                
                Weapon w = s.item as Weapon;
                if (!w || w.data == null || w.data.evolutionData == null) continue; // Ignore weapon if it cannot evolve.
    
                // Loop through every possible evolution of the weapon.
                foreach (ItemData.Evolution e in w.data.evolutionData)
                {
                    // Only attempt to evolve weapons via treasure chest evolution.
                    if (e.condition == ItemData.Evolution.Condition.treasureChest)
                    {
                        bool attempt = w.AttemptEvolution(e, 0);
                        if (attempt) return; // If evolution suceeds, stop.
                    }
                     
                }
            }
    
            // Logic for your level up stuff goes here.
        }

    Let me know if this works!

    #14481
    Nathan
    Level 10
    Participant
    Helpful?
    Up
    0
    ::

    Question. Would it be better to use || rather than && when checking if null? Because if only one of the conditions are met, rather than all three, it would continue. I was having this issue yesterday where if the chest was picked up without a full inventory, I would get a NullReferenceException.

    public void OpenTreasureChest(PlayerInventoy inventory, bool isHigherTier)
    {
        //loop through every weapon to check if it can evolve
        foreach (PlayerInventoy.Slot s in inventory.weaponSlots)
        {
            Weapon w = s.item as Weapon; //if s.item is a weapon, w will hold the weapon, otherwise it will return null
    
            if (w == null || w.data == null || w.data.evolutionData == null)
            {
                continue; // Ignore weapon if it cannot evolve
            }
    
            //loop through every possible evolution of the weapon
            foreach (ItemData.Evolution e in w.data.evolutionData)
            {
                //only attempt to evolve weapons by treasure chest
                if (e.condition == ItemData.Evolution.Condition.treasureChest)
                {
                    Debug.Log(w.name + " | " + s.item + " | " + e.condition);
                    bool attempt = w.AttemptEvolution(e, 0);
                    
                    //if evolution suceeds
                    if (attempt) 
                    {
                        return;
                    }
                }
            }
        }
        //Open level up screen if weapon cannot evolve
    }
    #14486
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Question. Would it be better to use || rather than && when checking if null? Because if only one of the conditions are met, rather than all three, it would continue. I was having this issue yesterday where if the chest was picked up without a full inventory, I would get a NullReferenceException.

    Yup. It will be better. My bad — my logic was wrong. Using || is the right choice.

    #14487
    Nathan
    Level 10
    Participant
    Helpful?
    Up
    0
    ::

    This works! I am working on the logic for implementing leveling up when picking up a chest if evolution is unavailable. I can post it when I have it working. Thank you.

    #14556
    Nathan
    Level 10
    Participant
    Helpful?
    Up
    0
    ::

    I added the logic for leveling up through chests if interested. It works for me and I haven’t found any issues through testing.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using static PlayerStats;
    
    public class TreasureChest : MonoBehaviour
    {
        void OnTriggerEnter2D(Collider2D c)
        {
            PlayerInventoy p = c.GetComponent<PlayerInventoy>();
            
            //evolve weapon
            if (p)
            {
                bool randomBool = Random.Range(0, 2) == 0;
    
                OpenTreasureChest(p, randomBool);
                Destroy(gameObject);
            }
        }
    
        public void OpenTreasureChest(PlayerInventoy inventory, bool isHigherTier)
        {
            bool evolutionAttempted = false; // Flag to track if any evolution attempt was made
            PlayerStats ps = FindObjectOfType<PlayerStats>();
    
            //loop through every weapon to check if it can evolve
            foreach (PlayerInventoy.Slot s in inventory.weaponSlots)
            {
                Weapon w = s.item as Weapon; //if s.item is a weapon, w will hold the weapon, otherwise it will return null
    
                if (w == null || w.data == null || w.data.evolutionData == null)
                {
                    continue; // Ignore weapon if it cannot evolve
                }
    
                //loop through every possible evolution of the weapon
                foreach (ItemData.Evolution e in w.data.evolutionData)
                {
                    //only attempt to evolve weapons by treasure chest
                    if (e.condition == ItemData.Evolution.Condition.treasureChest)
                    {
                        Debug.Log(w.name + " | " + s.item + " | " + e.condition);
                        bool attempt = w.AttemptEvolution(e, 0);
                        
                        //if evolution suceeds
                        if (attempt) 
                        {
                            evolutionAttempted = true; //set flag to true
                            return;
                        }
                    }
                }
            }
            //Open level up screen if weapon cannot evolve
            if (ps != null && !evolutionAttempted) 
            {
                ps.level++;//level up player
                ps.experience = 0;
                
                //Determine the players experience cap for the next level
                int experienceCapIncrease = 0;
                if (ps.levelRanges != null)
                {
                    foreach (LevelRange range in ps.levelRanges)
                    {
                        if (ps.level >= range.startLevel && ps.level <= range.endLevel)
                        {
                            experienceCapIncrease = range.experienceCapIncrease;
                            break;
                        }
                    }
                }
                   
                ps.experienceCap += experienceCapIncrease; //increase the players experience cap for the next level
    
                ps.expBar.fillAmount = (float)ps.experience / ps.experienceCap;//update exp bar fill amount
                ps.UpdateLevelText();
                GameManager.instance.StartLevelUp();
            }
        }
    }
Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: