字符串.显示SerializeField数据中的旧实例数据的格式-如何修复



我正试图在运行时在Unity中显示一个工具提示,其中包含以下信息:

Spell Name (string)
Cast Time (float)
Damage (int)
Description (string)

我在脚本中正确设置了所有内容,工具提示GetDescription((函数从具有所需信息的序列化字段中正确提取了拼写名称、施法时间和伤害所需的信息。但是,"说明"序列化字段(尽管已填充(不会显示在工具提示中。

当我放置调试时。Log(description(行进入函数后,控制台显示description的内容为空。我将描述存储在一个名为"description"的字符串中,它是[SerializeField],因此可以在Unity Inspector中设置描述。这与我存储其他法术信息(法术名称、施法时间和伤害(的方法相同。

当我运行游戏构建并转到工具提示文本字段所在的层次结构时,我可以直观地确认"描述"字符串的内容没有附加到文本字段(我使用的是启用Rich text的字段(。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
[Serializable]
public class Spell : IUseable, IMoveable, IDescribable
{
[SerializeField]
private string name;
[SerializeField]
private int damage;
[SerializeField]
private float castTime;
[SerializeField]
private string description;
public string GetDescription()
{
return string.Format("{0}n Cast time: {1} second(s) 
n Damage:{2} n {3}", name, castTime, damage, description);
}
}

当我运行构建并尝试工具提示时,我会得到这样的东西:

爆炸
施法时间:2.5秒
伤害:5

不过,它应该显示这样的内容:

爆炸
施法时间:2.5秒
伤害:5
制造强大的爆炸,伤害被爆炸击中的人

更新:

private void Awake()
{
toolTipTitle = toolTip.GetComponentInChildren<Text>();
}
public void ShowTooltip(Vector3 position, IDescribable description)
{
toolTip.SetActive(true);
toolTip.transform.position = position;
toolTipTitle.text = description.GetDescription();
}

更新:

我附加了一个调试。登录ShowTooltip((函数查看描述的内容。GetDescription((,它确实引用了序列化字段中数据的一个旧实例(我用10秒的强制转换时间将其更改为FireTest(。

爆炸
施法时间:2.5秒
伤害:5

UnityEngine。调试:日志(对象(
UIManager:ShowTooltip(Vector3,IDescriptionbable((位于Assets/Scripts/Managers/UIManager.cs:179(
ActionButton:OnPointerEnter(PointerEventData((位于Assets/Scripts/Buttons/ActionButton.cs:151(
UnityEngine.EventSystems.EventSystem:Update((

更新:

在附加一些调试之后。日志命令,看起来代码引用了SerializeFields中包含的名称、castTime和损坏数据的旧实例。这个旧实例没有描述字段,这解释了为什么没有将其添加到工具提示中。寻求有关如何强制代码从SerializeFields重新获取所需数据的建议,而不是依赖于缓存的数据值(老实说,不确定这是怎么可能的……但这些缓存的数据也出现在其他应该从这些字段中提取数据的地方,比如显示拼写名称并倒计时的选角栏,测试显示选角栏使用的是旧的实例化数据,而不是拼写书中的数据低参考:

代码:ActionButton.cs

public class ActionButton : MonoBehaviour, IPointerClickHandler, IClickable, IPointerEnterHandler, IPointerExitHandler
{
public IUseable MyUseable { get; set; }
[SerializeField]
private Text stackSize;
private Stack<IUseable> useables = new Stack<IUseable>();
private int count;
public Button MyButton { get; private set; }
public Image MyIcon
{
get
{
return icon;
}
set
{
icon = value;
}
}
public int MyCount
{
get
{
return count;
}
}
public Text MyStackText
{
get
{
return stackSize;
}
}    
[SerializeField]
private Image icon;
// Use this for initialization
void Start ()
{
MyButton = GetComponent<Button>();
MyButton.onClick.AddListener(OnClick);
InventoryScript.MyInstance.itemCountChangedEvent += new ItemCountChanged(UpdateItemCount);
}
// Update is called once per frame
void Update ()
{
}
public void OnClick()
{
if (HandScript.MyInstance.MyMoveable == null)
{
if (MyUseable != null)
{
MyUseable.Use();
}
if (useables != null && useables.Count > 0)
{
useables.Peek().Use();
}
}        
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
if (HandScript.MyInstance.MyMoveable != null && HandScript.MyInstance.MyMoveable is IUseable)
{
SetUseable(HandScript.MyInstance.MyMoveable as IUseable);
}
}
}
public void SetUseable(IUseable useable)
{
if (useable is Item)
{
useables = InventoryScript.MyInstance.GetUseables(useable);
count = useables.Count;
InventoryScript.MyInstance.FromSlot.MyIcon.color = Color.white;
InventoryScript.MyInstance.FromSlot = null;
}
else
{
this.MyUseable = useable;
}        
UpdateVisual();
}
public void UpdateVisual()
{
MyIcon.sprite = HandScript.MyInstance.Put().MyIcon;
MyIcon.color = Color.white;
if (count > 1)
{
UIManager.MyInstance.UpdateStackSize(this);
}
}
public void UpdateItemCount(Item item)
{
if (item is IUseable && useables.Count > 0)
{
if (useables.Peek().GetType() == item.GetType())
{
useables = InventoryScript.MyInstance.GetUseables(item as IUseable);
count = useables.Count;
UIManager.MyInstance.UpdateStackSize(this);
}
}
}
public void OnPointerEnter(PointerEventData eventData)
{
IDescribable tmp = null;
if (MyUseable != null && MyUseable is IDescribable)
{
tmp = (IDescribable)MyUseable;
// Need to implement!
// UIManager.MyInstance.ShowTooltip(transform.position);
}
else if (useables.Count > 0)
{
// Need to implement!
// UIManager.MyInstance.ShowTooltip(transform.position);
}
if (tmp != null)
{
UIManager.MyInstance.ShowTooltip(transform.position, tmp);
}
}
public void OnPointerExit(PointerEventData eventData)
{
UIManager.MyInstance.HideTooltip();
}
}

代码:SpellBook.cs

public class SpellBook : MonoBehaviour
{
private static SpellBook instance;
public static SpellBook MyInstance
{
get
{
if (instance == null)
{
instance = FindObjectOfType<SpellBook>();
}
return instance;
}
}
[SerializeField]
private Image castingBar;
[SerializeField]
private Text currentSpell;
[SerializeField]
private Text castTime;
[SerializeField]
private Image icon;
[SerializeField]
private CanvasGroup canvasGroup;
[SerializeField]
private Spell[] spells;
private Coroutine spellRoutine;
private Coroutine fadeRoutine;

// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public Spell CastSpell(string spellName)
{
Spell spell = Array.Find(spells, x => x.MyName == spellName);
castingBar.fillAmount = 0;
castingBar.color = spell.MyBarColor;
currentSpell.text = spell.MyName;
icon.sprite = spell.MyIcon;
spellRoutine = StartCoroutine(Progress(spell));
fadeRoutine = StartCoroutine(FadeBar());
return spell;
}
private IEnumerator Progress(Spell spell)
{
float timePassed = Time.deltaTime;
float rate = 1.0f / spell.MyCastTime;
float progress = 0.0f;
while (progress <= 1.0)
{
castingBar.fillAmount = Mathf.Lerp(0, 1, progress);
progress += rate * Time.deltaTime;
timePassed += Time.deltaTime;
castTime.text = (spell.MyCastTime - timePassed).ToString("F2");
if (spell.MyCastTime - timePassed < 0)
{
castTime.text = "0.00";
}
yield return null;
}
StopCasting();
}
private IEnumerator FadeBar()
{
float rate = 1.0f / 0.50f;
float progress = 0.0f;
while (progress <= 1.0)
{
canvasGroup.alpha = Mathf.Lerp(0, 1, progress);
progress += rate * Time.deltaTime;
yield return null;
}
}
public void StopCasting()
{
if (fadeRoutine != null)
{
StopCoroutine(fadeRoutine);
canvasGroup.alpha = 0;
fadeRoutine = null;
}
if (spellRoutine != null)
{
StopCoroutine(spellRoutine);
spellRoutine = null;
}
}
public Spell GetSpell(string spellName)
{
Spell spell = Array.Find(spells, x => x.MyName == spellName);
return spell;
}
}

弄清楚了——我意外地在另一个游戏对象中创建了脚本字段数据的克隆,而游戏却在使用它。按回答结束-非常感谢您的帮助!=(

最新更新