Forum begins after the advertisement:


[Part 19] LevelUp screen does not display weapons and passives as tutorial video

Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 19] LevelUp screen does not display weapons and passives as tutorial video

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #20023
    Khôi Đỗ
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    Here is my level up screen, not displaying any weapons/passives’ icon and unclickable buttons

    Hi Terence,

    I’ve done all the steps as your instructions in the tutorial video but my level up screen does not display the new weapons or passives (it does display just 1 and only the name and its description) and the rest is default with same default icon for all even I put if (level <= 1) return baseStats; into both PassiveData.cs and WeaponData.cs. And the button is unclickable as well, I tried to remove the EventSystem and added back again but nothing changed. I attach the code below.

    [UIUpgradeWindow.cs]

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Unity.UI;
    using TMPro;
    using UnityEngine.UI;
    
    
    [RequireComponent(typeof(VerticalLayoutGroup))]
    public class UIUpgradeWindow : MonoBehaviour
    {
        VerticalLayoutGroup verticalLayoutGroup;
    
        public RectTransform upgradeOptionTemplate;
        public TextMeshProUGUI tooltipTemplate;
    
    
    
        [Header("Setting")]
        public int maxOptions = 4;
        public string newText = "New";
    
        public Color newTextColor = Color.yellow, levelTextColor = Color.white;
    
    
        [Header("Paths")]
        public string iconPath = "Icon/Item Icon";
        public string namePath = "Name", descriptionPath = "Description", buttonPath = "Button", levelPath = "Level";
    
    
    
    
        RectTransform rectTransform;
        float optionHeight;
        int activeOptions;
    
        List<RectTransform> upgradeOptions = new List<RectTransform>();
    
    
        Vector2 lastScreen;
    
        public void SetUpgrades(PlayerInventory inventory, List<ItemData> possibleUpgrades, int pick = 3, string tooltip = "")
        {
            pick = Mathf.Min(maxOptions, pick);
    
            // If we don't have enough upgrade option boxes, create them.
            if (maxOptions > upgradeOptions.Count)
            {
                for (int i = upgradeOptions.Count; i < pick; i++)
                {
                    GameObject go = Instantiate(upgradeOptionTemplate.gameObject, transform);
                    upgradeOptions.Add((RectTransform)go.transform);
                }
            }
    
            // Update the tooltip and turn it off if it is empty.
            tooltipTemplate.text = tooltip;
            tooltipTemplate.gameObject.SetActive(tooltip.Trim() != "");
    
            // Activate only the number of upgrade options we need, and arm the buttons and the
            // different attributes like descriptions, etc.
            activeOptions = 0;
            int totalPossibleUpgrades = possibleUpgrades.Count; // How many upgrades do we have to choose from?
            foreach (RectTransform r in upgradeOptions)
            {
                if (activeOptions < pick && activeOptions < totalPossibleUpgrades)
                {
                    r.gameObject.SetActive(true);
    
                    // Select one of the possible upgrades, then remove it from the list.
                    ItemData selected = possibleUpgrades[Random.Range(0, possibleUpgrades.Count)];
                    possibleUpgrades.Remove(selected);
                    Item item = inventory.Get(selected);
    
                    // Insert the name of the item.
                    TextMeshProUGUI name = r.Find(namePath).GetComponent<TextMeshProUGUI>();
                    if (name)
                    {
                        name.text = selected.name;
                        if (item)
                        {
                            name.text += " - Level " + (item.currentLevel + 1);
                        }
                    }
    
                    // Insert the description of the item.
                    TextMeshProUGUI desc = r.Find(descriptionPath).GetComponent<TextMeshProUGUI>();
                    if (desc)
                    {
                        if (item)
                        {
                            desc.text = selected.GetLevelData(item.currentLevel + 1).description;
                        }
                        else
                        {
                            desc.text = selected.GetLevelData(1).description;
                        }
                    }
    
                    // Insert the icon of the item.
                    Image icon = r.Find(iconPath).GetComponent<Image>();
                    if (icon)
                    {
                        icon.sprite = selected.icon;
                    }
    
                    // Insert the button action binding.
                    Button b = r.Find(buttonPath).GetComponent<Button>();
                    if (b)
                    {
                        b.onClick.RemoveAllListeners();
                        if (item)
                            b.onClick.AddListener(() => inventory.LevelUp(item));
                        else
                            b.onClick.AddListener(() => inventory.Add(selected));
                    }
    
                    activeOptions++;
                }
                else r.gameObject.SetActive(false);
            }
        }
    
        void RecalculateLayout()
        {
            optionHeight = (rectTransform.rect.height - verticalLayoutGroup.padding.top - verticalLayoutGroup.padding.bottom - (maxOptions - 1) * verticalLayoutGroup.spacing);
            if (activeOptions == maxOptions && tooltipTemplate.gameObject.activeSelf)
                optionHeight /= maxOptions + 1;
            else
                optionHeight /= maxOptions;
    
            if(tooltipTemplate.gameObject.activeSelf)
            {
                RectTransform tooltipRect = (RectTransform)tooltipTemplate.transform;
                tooltipTemplate.gameObject.SetActive(true);
                tooltipRect.sizeDelta = new Vector2(tooltipRect.sizeDelta.x, optionHeight);
                tooltipTemplate.transform.SetAsLastSibling();
            }
    
            foreach(RectTransform r in upgradeOptions)
            {
                if (!r.gameObject.activeSelf) continue;
                r.sizeDelta = new Vector2(r.sizeDelta.x, optionHeight);
            }
        }
    
    
        void Update()
        {
            if(lastScreen.x != Screen.width || lastScreen.y != Screen.height)
            {
                RecalculateLayout();
                lastScreen = new Vector2(Screen.width, Screen.height);
            }
        }
    
    
        void Awake()
        {
            verticalLayoutGroup = GetComponentInChildren<VerticalLayoutGroup>();
            if (tooltipTemplate) tooltipTemplate.gameObject.SetActive(false);
            if (upgradeOptionTemplate) upgradeOptions.Add(upgradeOptionTemplate);
    
            rectTransform = (RectTransform)transform;
        }
    
        void Reset()
        {
            upgradeOptionTemplate = (RectTransform)transform.Find("Upgrade Option");
            tooltipTemplate = transform.Find("Tooltip").GetComponentInChildren<TextMeshProUGUI>();
        }
    
    }
    

    [PassiveData.cs]

    
    using UnityEngine;
    
    
    [CreateAssetMenu(fileName = "Passive Data", menuName = "2d top down/Passive Data")]
    public class PassiveData : ItemData
    {
        public Passive.Modifier baseStats;
        public Passive.Modifier[] growth;
    
        public override Item.LevelData GetLevelData(int level)
        {
            if (level <= 1) return baseStats;
    
            if (level - 2 < growth.Length)
                return growth[level - 2];
    
            Debug.LogWarning(string.Format("Passive doesnt have its level up stats configure for level {0}", level));
            return new Passive.Modifier();
        }
    }
    
    
    [WeaponData.cs]
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    
    [CreateAssetMenu(fileName = "Weapon Data", menuName = "2d top down/Weapon Data")]
    public class WeaponData : ItemData
    {
    
    
        [HideInInspector] public string behaviour;
        public Weapons.Stats baseStats;
        public Weapons.Stats[] linearGrowth;
        public Weapons.Stats[] randomGrowth;
    
    
        public override Item.LevelData GetLevelData(int level)
        {
            if (level <= 1) return baseStats;
    
            if(level - 2 < linearGrowth.Length)
                return linearGrowth[level - 2];
    
            if(randomGrowth.Length > 0)
                return randomGrowth[Random.Range(0, randomGrowth.Length)];
    
    
            Debug.LogWarning(string.Format("Weapon doesn't have its level up stats configured for Level {0}!", level));
            return new Weapons.Stats();
        }
    
    }
    
    #20024
    Terence
    Level 32
    Keymaster
    Helpful?
    Up
    0
    ::

    Hi! From your code, the first thing I would check is the Icon Path in the UIUpgradeWindow Inspector.

    Your script updates the name and description before reaching this line:

    Image icon = r.Find(iconPath).GetComponent<Image>();

    If r.Find(iconPath) cannot find the object, it throws a NullReferenceException. This stops the function before it assigns the icon, sets up the button listener, or populates the remaining options—which would explain the symptoms you described.

    Please check these settings against Part 19:

    1. Verify the template paths. The default Icon/Item Icon expects an object named Item Icon inside Icon, relative to your Upgrade Option template. That object must have an Image component. Likewise, Button must point to the object with the Button component. Check the actual Inspector values, since changing defaults in the script does not update values already saved in the Inspector.

    2. Uncheck Raycast Target on the Upgrade Options Background’s Image component. Section 3b explains that this background can block clicks to the buttons.

    3. Keep only one Upgrade Option template before running the game. As described in section 5a, the script duplicates this template automatically. Extra manually created options are not registered by your Awake() method and may remain at their default values.

    4. Add RecalculateLayout(); at the end of SetUpgrades(), after the foreach loop. This call appears in the guide but is missing from your version.

    Also check that each WeaponData and PassiveData asset has its Icon sprite assigned, and that PlayerInventory’s Upgrade Window field references the correct UIUpgradeWindow.

    The if (level <= 1) return baseStats; lines you added are correct, but they address level-one data access rather than icon assignment or button clicks.

    Could you check the Console when the level-up screen opens? If there is a NullReferenceException, its line number should help confirm which UI path is failing.

    #20025
    Khôi Đỗ
    Level 2
    Participant
    Helpful?
    Up
    0
    ::

    Hi Terence, Thanks for your responding. I just realised that how silly I am, I set the upgrade option holder’s icon same name as item icon so the script unable detect which one is real icon. The error has fixed, smoothly now. By the way, may I ask do I need another script for creating fire wand weapon?

    #20026
    Terence
    Level 32
    Keymaster
    Helpful?
    Up
    0
    ::

    It’s been awhile since I’ve worked on the project so I don’t remember, but as I recall you don’t need to.

    Create a new Projectile Weapon and have it shoot multiple projectiles, then have it spawn projectiles that have Auto Aim enabled.

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

Go to Login Page →


Advertisement below: