Forum begins after the advertisement:
[Part 15] ItemData / WeaponData casting issue
Home › Forums › Video Game Tutorial Series › Creating a Rogue-like Shoot-em Up in Unity › [Part 15] ItemData / WeaponData casting issue
- This topic has 4 replies, 2 voices, and was last updated 4 months, 2 weeks ago by Hào Quách.
-
AuthorPosts
-
July 27, 2024 at 12:08 am #15388::
Hi sir, i have some trouble with my code and i really dont know to solve, it took me over 3 days and still dont know how to solve it. Error at PlayerInventory.css file part 15 My problem is: “Cannot convert type ItemData to WeaponData via a reference conversion, boxing conversion, unboxing converison, wrapping conversion or null type conversion.
July 27, 2024 at 12:41 am #15390::Can you post your
PlayerInventory
code here and highlight the line causing the problem?July 27, 2024 at 10:59 am #15395::using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro;using Debug = UnityEngine.Debug;using Image = UnityEngine.UI.Image; public class PlayerInventory : MonoBehaviour { [System.Serializable] public class Slot { public Item item; public Image image; public void Assign(Item assignedItem) { item = assignedItem; if (item is Weapon) { Weapon w = item as Weapon; image.enabled = true; image.sprite = w.data.icon; } else { Passive p = item as Passive; image.enabled = true; image.sprite = p.data.icon; } Debug.Log(string.Format("Assigned {0} to player.", item.name)); } public void Clear() { item = null; image.enabled = false; image.sprite = null; } public bool IsEmpty() { return item != null; } } public List<Slot> weaponSlots = new List<Slot>(6); public List<Slot> passiveSlots = new List<Slot>(6); [System.Serializable] public class UpgradeUI { public TMP_Text upgradeNameDisplay; public TMP_Text upgradeDescriptionDisplay; public Image upgradeIcon; public Button upgradeButton; } [Header("UI Elements")] public List<WeaponData> availableWeapons = new List<WeaponData>(); //List of upgrade options for weapons public List<PassiveData> availablePassives = new List<PassiveData>(); //List of upgrade options for passive items public List<UpgradeUI> upgradeUIOptions = new List<UpgradeUI>(); //List of UI for upgrade options present in the scene PlayerStats player; void Start() { player = GetComponent<PlayerStats>(); } // Checks if the inventory has an item of a certain type. public bool Has(ItemData type) { return Get(type); } public Item Get(ItemData type) { if (type is WeaponData) return Get(type as WeaponData); else if (type is PassiveData) return Get(type as PassiveData); return null; } // Find a passive of a certain type in the inventory. public Passive Get(PassiveData type) { foreach (Slot s in passiveSlots) { Passive p = s.item as Passive; if (p.data == type) return p; } return null; } // Find a weapon of a certain type in the inventory. public Weapon Get(WeaponData type) { foreach (Slot s in weaponSlots) { Weapon w = s.item as Weapon; if (w.data == type) return w; } return null; } //Removes a weapon of.... public bool Remove(WeaponData data, bool removeUpgradeAvailability = false) { // Remove this weapon from the upgrade pool. if (removeUpgradeAvailability) availableWeapons.Remove(data); for (int i = 0; i < weaponSlots.Count; i++) { Weapon w = weaponSlots[i].item as Weapon; if (w.data == data) { weaponSlots[i].Clear(); w.OnUnequip(); Destroy(w.gameObject); return true; } } return false; } // Removes a passive of a particular type, as specified by <data>. public bool Remove(PassiveData data, bool removeUpgradeAvailability = false) { // Remove this passive from the upgrade pool. if (removeUpgradeAvailability) availablePassives.Remove(data); for (int i = 0; i < weaponSlots.Count; i++) { Passive p = weaponSlots[i].item as Passive; if (p.data == data) { weaponSlots[i].Clear(); p.OnUnequip(); Destroy(p.gameObject); return true; } } return false; } // // public bool Remove(ItemData data, bool removeUpgradeAvailability = false) { if (data is PassiveData) return Remove(data as PassiveData, removeUpgradeAvailability); else if (data is WeaponData) return Remove(data as WeaponData, removeUpgradeAvailability); return false; } // // public int Add(WeaponData data) { int slotNum = -1; // Try to find an empty slot. for (int i = 0; i < weaponSlots.Capacity; i++) { if (weaponSlots[i].IsEmpty()) { slotNum = i; break; } } // If there is no empty slot, exit. if (slotNum < 0) return slotNum; // Otherwise create the weapon in the slot. // Get the type of the weapon we want to spawn. Type weaponType = Type.GetType(data.behaviour); if (weaponType != null) { // Spawn the weapon GameObject. GameObject go = new GameObject(data.baseStats.name + " Controller"); Weapon spawnedWeapon = (Weapon)go.AddComponent(weaponType); spawnedWeapon.Initialise(data); spawnedWeapon.transform.SetParent(transform); // Set the weapon to be a child of the player spawnedWeapon.transform.localPosition = Vector2.zero; spawnedWeapon.OnEquip(); // Assign the weapon to the slot. weaponSlots[slotNum].Assign(spawnedWeapon); // Close the level up UI if it is on. if (GameManager.instance != null && GameManager.instance.choosingUpgrade) GameManager.instance.EndLevelUp(); return slotNum; } else { Debug.LogWarning(string.Format( "Invalid weapon type specified for {0}. ", data.name )); } return -1; } // Finds an empty slot and adds a passive of a certain type, returns // the slot number that the item was put in. public int Add(PassiveData data) { int slotNum = -1; // Try to find an empty slot. for (int i = 0; i < passiveSlots.Capacity; i++) { if (passiveSlots[i].IsEmpty()) { slotNum = i; break; } } // If there is no empty slot, exit. if (slotNum < 0) return slotNum; // Otherwise create the passive in the slot. // Get the type of the passive we want to spawn. GameObject go = new GameObject(data.baseStats.name + " Passive"); Passive p = go.AddComponent<Passive>(); p.Initialise(data); p.transform.SetParent(transform); // Set the weapon to be a child of the player p.transform.localPosition = Vector2.zero; // Assign the passive to the slot. passiveSlots[slotNum].Assign(p); if (GameManager.instance != null && GameManager.instance.choosingUpgrade) { GameManager.instance.EndLevelUp(); } player.RecalculateStats(); return slotNum; } // If we don't know what item is being added, this function will determine that. public int Add(ItemData data) { if (data is WeaponData) return Add(data as WeaponData); else if (data is PassiveData) return Add(data as PassiveData); return -1; } public void LevelUpWeapon(int slotIndex, int upgradeIndex) { if (weaponSlots.Count > slotIndex) { Weapon weapon = weaponSlots[slotIndex].item as Weapon; // Don't level up the weapon if it is already at max level. if (!weapon.DoLevelUp()) { Debug.LogWarning(string.Format( "Failed to level up {0}.", weapon.name )); return; } } if (GameManager.instance != null && GameManager.instance.choosingUpgrade) { GameManager.instance.EndLevelUp(); } } public void LevelUpPassiveItem(int slotIndex, int upgradeIndex) { if (passiveSlots.Count > slotIndex) { Passive p = passiveSlots[slotIndex].item as Passive; if (!p.DoLevelUp()) { Debug.LogWarning(string.Format( "Failed to level up {0}.", p.name )); return; } } if (GameManager.instance != null && GameManager.instance.choosingUpgrade) { GameManager.instance.EndLevelUp(); } player.RecalculateStats(); } // Determines what upgrade options should appear. void ApplyUpgradeOptions() { // Make a duplicate of the available weapon / passive upgrade lists // so we can iterate through them in the function. List<WeaponData> availableWeaponUpgrades = new List<WeaponData>(availableWeapons); List<PassiveData> availablePassiveItemUpgrades = new List<PassiveData>(availablePassives); // Iterate through each slot in the upgrade UI. foreach (UpgradeUI upgradeOption in upgradeUIOptions) { // If there are no more available upgrades, then we abort. if (availableWeaponUpgrades.Count == 0 && availablePassiveItemUpgrades.Count == 0) return; // Determine whether this upgrade should be for passive or active weapons. int upgradeType; if (availableWeaponUpgrades.Count == 0) { upgradeType = 2; } else if (availablePassiveItemUpgrades.Count == 0) { upgradeType = 1; } else { // Random generates a number between 1 and 2. upgradeType = UnityEngine.Random.Range(1, 3); } // Generates an active weapon upgrade. if (upgradeType == 1) { // Pick a weapon upgrade, then remove it so that we don't get it twice. WeaponData chosenWeaponUpgrade = availableWeaponUpgrades[UnityEngine.Random.Range(0, availableWeaponUpgrades.Count)]; availableWeaponUpgrades.Remove(chosenWeaponUpgrade); // Ensure that the selected weapon data is valid. if (chosenWeaponUpgrade != null) { // Turns on the UI slot. EnableUpgradeUI(upgradeOption); // Loops through all our existing weapons. If we find a match, we will // hook an event listener to the button that will level up the weapon // when this upgrade option is clicked. bool isLevelUp = false; for (int i = 0; i < weaponSlots.Count; i++) { Weapon w = weaponSlots[i].item as Weapon; if (w != null && w.data == chosenWeaponUpgrade) { // If the weapon is already at the max level, do not allow upgrade. if (chosenWeaponUpgrade.maxLevel <= w.currentLevel) { //DisableUpgradeUI(upgradeOption); isLevelUp = false; break; } // Set the Event Listener, item and level description to be that of the next level. upgradeOption.upgradeButton.onClick.AddListener(() => LevelUpWeapon(i, i)); // Apply button functionality Weapon.Stats nextLevel = chosenWeaponUpgrade.GetLevelData(w.currentLevel + 1); upgradeOption.upgradeDescriptionDisplay.text = nextLevel.description; upgradeOption.upgradeNameDisplay.text = nextLevel.name; upgradeOption.upgradeIcon.sprite = chosenWeaponUpgrade.icon; isLevelUp = true; break; } } // If the code gets here, it means that we will be adding a new weapon, instead of // upgrading an existing weapon. if (!isLevelUp) { upgradeOption.upgradeButton.onClick.AddListener(() => Add(chosenWeaponUpgrade)); // Apply button functionality upgradeOption.upgradeDescriptionDisplay.text = chosenWeaponUpgrade.baseStats.description; // Apply initial description upgradeOption.upgradeNameDisplay.text = chosenWeaponUpgrade.baseStats.name; // Apply initial name upgradeOption.upgradeIcon.sprite = chosenWeaponUpgrade.icon; } } } else if (upgradeType == 2) { // NOTE: We have to recode this system, as right now it disables an upgrade slot if // we hit a weapon that has already reached max level. PassiveData chosenPassiveUpgrade = availablePassiveItemUpgrades[UnityEngine.Random.Range(0, availablePassiveItemUpgrades.Count)]; availablePassiveItemUpgrades.Remove(chosenPassiveUpgrade); if (chosenPassiveUpgrade != null) { // Turns on the UI slot. EnableUpgradeUI(upgradeOption); // Loops through all our existing passive. If we find a match, we will // hook an event listener to the button that will level up the weapon // when this upgrade option is clicked. bool isLevelUp = false; for (int i = 0; i < passiveSlots.Count; i++) { Passive p = passiveSlots[i].item as Passive; if (p != null && p.data == chosenPassiveUpgrade) { // If the passive is already at the max level, do not allow upgrade. if (chosenPassiveUpgrade.maxLevel <= p.currentLevel) { //DisableUpgradeUI(upgradeOption); isLevelUp = false; break; } upgradeOption.upgradeButton.onClick.AddListener(() => LevelUpPassiveItem(i, i)); // Apply button functionality Passive.Modifier nextLevel = chosenPassiveUpgrade.GetLevelData(p.currentLevel + 1); upgradeOption.upgradeDescriptionDisplay.text = nextLevel.description; upgradeOption.upgradeNameDisplay.text = nextLevel.name; upgradeOption.upgradeIcon.sprite = chosenPassiveUpgrade.icon; isLevelUp = true; break; } } if (!isLevelUp) // Spawn a new passive item { upgradeOption.upgradeButton.onClick.AddListener(() => Add(chosenPassiveUpgrade)); // Apply button functionality Passive.Modifier nextLevel = chosenPassiveUpgrade.baseStats; upgradeOption.upgradeDescriptionDisplay.text = nextLevel.description; // Apply initial description upgradeOption.upgradeNameDisplay.text = nextLevel.name; // Apply initial name upgradeOption.upgradeIcon.sprite = chosenPassiveUpgrade.icon; } } } } } void RemoveUpgradeOptions() { foreach (UpgradeUI upgradeOption in upgradeUIOptions) { upgradeOption.upgradeButton.onClick.RemoveAllListeners(); DisableUpgradeUI(upgradeOption); // Call the DisableUpgradeUI method here to disable all UI options before applying upgrades to them } } public void RemoveAndApplyUpgrades() { RemoveUpgradeOptions(); ApplyUpgradeOptions(); } void DisableUpgradeUI(UpgradeUI ui) { ui.upgradeNameDisplay.transform.parent.gameObject.SetActive(false); } void EnableUpgradeUI(UpgradeUI ui) { ui.upgradeNameDisplay.transform.parent.gameObject.SetActive(true); } }
i dont know if i correct, but since i try to change code in class WeaponData: (ScriptableObject to ItemData) it fixed :D
July 27, 2024 at 11:16 pm #15397::Oh yes, you need to put
ItemData
instead ofScriptableObject
because theWeaponData
script inherits fromItemData
.July 28, 2024 at 3:46 pm #15400 -
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: