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
- This topic has 3 replies, 2 voices, and was last updated 1 week, 1 day ago by
Terence.
-
AuthorPosts
-
October 9, 2026 at 10:34 pm #20023::
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(); } }October 10, 2026 at 3:14 pm #20024::Hi! From your code, the first thing I would check is the Icon Path in the
UIUpgradeWindowInspector.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 aNullReferenceException. 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:
-
Verify the template paths. The default
Icon/Item Iconexpects an object namedItem IconinsideIcon, relative to your Upgrade Option template. That object must have anImagecomponent. Likewise,Buttonmust point to the object with theButtoncomponent. Check the actual Inspector values, since changing defaults in the script does not update values already saved in the Inspector. -
Uncheck Raycast Target on the Upgrade Options Background’s Image component. Section 3b explains that this background can block clicks to the buttons.
-
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. -
Add
RecalculateLayout();at the end ofSetUpgrades(), after theforeachloop. 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 correctUIUpgradeWindow.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.October 10, 2026 at 3:28 pm #20025::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?
October 10, 2026 at 3:40 pm #20026 -
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: