我正在制作一个有 4 个法术位的用户界面。我这样做是为了当我的玩家与一个大部头游戏对象发生碰撞时,它会被添加到我的玩家的 unequippedSpells 数组中,该数组位于我的 SpellSystem 脚本中。
private void OnCollisionEnter2D(Collision2D other)
{
Debug.Log("Finding Player");
if (other.gameObject.CompareTag("Player")) {
Debug.Log("Player Found");
Spell fireball = gameObject.AddComponent<Spell>();
fireball.spellData = fireballData;
fireball.spellType = fireballType;
spellSystem.AddSpell(fireball);
spriteRenderer.enabled = false;
}
}
public void AddSpell(Spell spell) {
Array.Resize(ref unequippedSpells, unequippedSpells.Length + 1);
spellEquipped = false;
}
然后我想制作一个显示装备的法术的库存 ui 东西。我想做到这一点,如果玩家有一个空的法术位,法术将从未装备状态变为装备状态,法术 ui 将显示所有装备的法术,所以我做了一个 equippedspell() 函数,它是
public void EquipSpell(Spell spell, GameObject spellSlots) {
int index = Array.IndexOf(equippedSpells, spell);
if (index != -1) {
Array.Resize(ref equippedSpells, equippedSpells.Length + 1);
equippedSpells[equippedSpells.Length + 1] = spell;
Array.Resize(ref unequippedSpells, unequippedSpells.Length - 1);
GameObject labelObject = spellSlots.transform.GetChild(1).gameObject;
TextMeshProUGUI label = labelObject.GetComponentInChildren<TextMeshProUGUI>();
Debug.Log(label.text);
label.text = spell.name;
spellSlots.GetComponent<SlotStat>().hasSpell = true;
}
}
SpellSystem 脚本的 update() 函数是
private void Update() {
if (equippedSpells.Length < spellSlots.Length && !spellEquipped) {
if (spellSlots[equippedSpells.Length].GetComponent<SlotStat>().hasSpell == false) {
EquipSpell(unequippedSpells[unequippedSpells.Length - 1], spellSlots[equippedSpells.Length]);
spellEquipped = true;
}
}
}
但是当我运行游戏时出现错误
IndexOutOfRangeException:索引超出数组范围。 SpellSystem.Update ()(位于 Assets/Scripts/Spells/SpellSystem.cs:24)
我将在下面放置拼写系统的完整代码和示例拼写
using System.Data;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class Spell : MonoBehaviour {
public SpellDataSO spellData;
public SpellTypeSO spellType;
}
public class SpellSystem : MonoBehaviour
{
public Spell[] equippedSpells;
public Spell[] unequippedSpells;
public GameObject[] spellSlots;
private bool spellEquipped;
private void Update() {
if (equippedSpells.Length < spellSlots.Length && !spellEquipped) {
if (spellSlots[equippedSpells.Length].GetComponent<SlotStat>().hasSpell == false) {
EquipSpell(unequippedSpells[unequippedSpells.Length - 1], spellSlots[equippedSpells.Length]);
spellEquipped = true;
}
}
}
public void EquipSpell(Spell spell, GameObject spellSlots) {
int index = Array.IndexOf(equippedSpells, spell);
if (index != -1) {
Array.Resize(ref equippedSpells, equippedSpells.Length + 1);
equippedSpells[equippedSpells.Length + 1] = spell;
Array.Resize(ref unequippedSpells, unequippedSpells.Length - 1);
GameObject labelObject = spellSlots.transform.GetChild(1).gameObject;
TextMeshProUGUI label = labelObject.GetComponentInChildren<TextMeshProUGUI>();
Debug.Log(label.text);
label.text = spell.name;
spellSlots.GetComponent<SlotStat>().hasSpell = true;
}
}
public void UnequipSpell(Spell spell) {
int index = Array.IndexOf(unequippedSpells, spell);
if (index != -1) {
Array.Resize(ref unequippedSpells, unequippedSpells.Length + 1);
unequippedSpells[unequippedSpells.Length + 1] = spell;
Array.Resize(ref equippedSpells, equippedSpells.Length - 1);
}
}
public void AddSpell(Spell spell) {
Array.Resize(ref unequippedSpells, unequippedSpells.Length + 1);
spellEquipped = false;
}
public Spell[] GetEquppedSpells() {
return equippedSpells;
}
public Spell[] GetUnequippedSpells() {
return unequippedSpells;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fireball : MonoBehaviour
{
public SpellSystem spellSystem;
public SpellDataSO fireballData;
public SpellTypeSO fireballType;
public SpriteRenderer spriteRenderer;
private void OnCollisionEnter2D(Collision2D other)
{
Debug.Log("Finding Player");
if (other.gameObject.CompareTag("Player")) {
Debug.Log("Player Found");
Spell fireball = gameObject.AddComponent<Spell>();
fireball.spellData = fireballData;
fireball.spellType = fireballType;
spellSystem.AddSpell(fireball);
spriteRenderer.enabled = false;
}
}
}
我知道问题出在 Update() 函数中,因为错误指的是第 24 行
private void Update() {
if (equippedSpells.Length < spellSlots.Length && !spellEquipped) {
if (spellSlots[equippedSpells.Length].GetComponent<SlotStat>().hasSpell == false) {
EquipSpell(unequippedSpells[unequippedSpells.Length - 1], spellSlots[equippedSpells.Length]);
spellEquipped = true;
}
}
}
具体指
EquipSpell(unequippedSpells[unequippedSpells.Length - 1], spellSlots[equippedSpells.Length]);
EquipSpell(unequippedSpells[unequippedSpells.Length - 1], spellSlots[equippedSpells.Length]);
在这一行中,您有两个数组可以触发此异常。
spellSlots[equippedSpells.Length]
unequippedSpells[unequippedSpells.Length - 1]
我们知道 1. 不是问题,因为它是在那行之前的第二个
if
中调用的。因此,2. 是问题。
最有可能的是,
unequippedSpells
是 Empty(Length == 0),这意味着您正在尝试访问 unequippedSpells[-1]
.
不应该为未装备的法术和装备好的法术使用数组并调整它们的大小,而应该使用列表。这样会更干净。对于您的问题,请使用 Linq 中的
unequipedSpells.Last()
。这将返回列表的最后一个元素,这将解决您的问题。