String.Format, отображающий старые инстанцированные данные из данных SerializeField. Как это исправить? - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь отобразить всплывающую подсказку в Unity во время выполнения, которая содержит следующую информацию:

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

У меня все правильно настроено в скриптах, и функция GetDescription () всплывающей подсказки правильно извлекает информацию, которую онанужны для Spell Name, Cast Time и Damage из сериализованных полей, в которых есть нужная информация.Однако поле сериализации Description, несмотря на то, что оно заполнено, во всплывающей подсказке не отображается.

Когда я помещаю строку Debug.Log (описание) в функцию, консоль показывает, что содержимое описания пусто.У меня есть описание, хранящееся в строке с именем «description», и это [SerializeField], чтобы описание можно было установить в Инспекторе Unity.Это тот же подход к хранению другой информации о заклинании (имя заклинания, время сотворения и урон).

Когда я запускаю сборку игры и иду в иерархию, где находится текстовое поле всплывающей подсказки, яможет визуально подтвердить, что содержимое строки «описание» не добавляется к текстовому полю (я использую поле с расширенным текстом).

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 ()и это действительно относится к старому экземпляру данных в последовательномized field (который я изменил на FireTest с 10-секундным временем чтения).

Взрыв
Время чтения: 2,5 секунды
Урон: 5

UnityEngine.Debug: Log (Object)
UIManager: ShowTooltip(Vector3, IDescribable) (в Assets / Scripts / Managers / UIManager.cs: 179)
ActionButton: OnPointerEnter (PointerEventData) (в Assets / Scripts / Buttons / ActionButton.cs: 151)
UnityEngine.EventSystems.EventSystem: Update ()

Обновление:

После подключения некоторых команд Debug.Log похоже, что код ссылается на старый экземпляр данных, содержащихся в полях 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;
    }
}

1 Ответ

0 голосов
/ 20 декабря 2018

Понял - я случайно создал клон данных поля скрипта в другом игровом объекте, и игра использовала его вместо этого.Закрывая это как ответ - большое спасибо за помощь!=) * * Тысяча одна

...