String.Format显示来自SerializeField数据的旧实例化数据 - 如何修复?

问题描述 投票:3回答:1

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

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

我已经在脚本中正确设置了所有内容,并且工具提示GetDescription()函数正确地从具有所需信息的序列化字段中提取拼写名称,施法时间和损坏所需的信息。但是,描述序列化字段尽管已填充,但未显示在工具提示中。

当我将Debug.Log(description)行放入函数时,控制台显示描述的内容为空。我将描述存储在名为“description”的字符串中,它是[SerializeField],以便可以在Unity Inspector中设置描述。这与我存储其他法术信息(法术名称,施法时间和伤害)的方法相同。

当我运行游戏构建并转到工具提示文本字段所在的层次结构时,我可以直观地确认“description”字符串的内容未被附加到文本字段(我正在使用启用了富文本的字段)。

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();
}

更新:

我将一个Debug.Log附加到ShowTooltip()函数来查看description.GetDescription()的内容,它确实是指序列化字段中的旧数据实例(我将其更改为FireTest,投射时间为10秒)。

爆炸 演出时间:2.5秒 伤害:5

UnityEngine.Debug:日志(对象) UIManager:ShowTooltip(Vector3,IDescribable)(在Assets / Scripts / Managers / UIManager.cs:179) ActionButton:OnPointerEnter(PointerEventData)(在Assets / Scripts / Buttons / ActionButton.cs:151) UnityEngine.EventSystems.EventSystem:更新()

更新:

附加一些Debug.Log命令后,看起来代码引用了SerializeFields中包含的旧数据实例,包括name,castTime和damage。这个旧实例没有描述字段,这解释了为什么它没有被添加到工具提示中。寻求有关如何强制代码从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;
    }
}
unity3d serialization string.format
1个回答
0
投票

弄清楚了 - 我不小心在另一个游戏对象中创建了一个脚本字段数据的克隆,游戏正在使用它。结束了这个回答 - 非常感谢你的帮助! =)

© www.soinside.com 2019 - 2024. All rights reserved.