Unity не может получить доступ к переменной сценария префаба - PullRequest
0 голосов
/ 21 января 2020

Я работаю над 3D-игрой на Unity, но недавно возникла проблема. Я не могу получить доступ к переменной из скрипта другого префаба. Я пробовал это раньше, когда объект, к которому нужно получить доступ, не был префабом, и он работал правильно.

Это скрипт, который пытается получить доступ к переменной «slashtime», но при запуске он возвращает 0 хотя в другом скрипте переменная постоянно меняется.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class collision : MonoBehaviour
{
    public GameObject sword;
    public float slashtime;



    private void Update()
    {
        slashtime=sword.GetComponent<movement>().slashtime;
    }

    private void OnTriggerEnter(Collider collider)
    {



        if (collider.tag == "sword" && slashtime+1f > Time.time)
        {

            Destroy(gameObject);
        }
    }


}

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Вы можете использовать это. Это также работает.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;    

public class collision : MonoBehaviour
{
    public GameObject sword;
    public float slashtime;

    private void OnTriggerEnter(Collider collider)
    {
        sword = collider.gameObject;
        slashtime=sword.GetComponent<movement>().slashtime;
        if (collider.tag == "sword" && slashtime+1f > Time.time)
        {
            Destroy(gameObject);
        }
    }
}
  • Причина, по которой ваш код не работает, потому что когда вы пишете какой-то код в обновлении, он вызывает каждый кадр. поэтому, когда ваш объект уничтожен, обновите вызов этого кода, и он показал ошибку.
0 голосов
/ 21 января 2020

Немного переработав ваш код, с пояснениями ниже:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class collision : MonoBehaviour
{
    [SerializeField]
    private GameObject _sword;
    private float _slashTime;

    private void Start()
    {
        _slashTime = GameObject.Find("Movement").GetComponent<Movement>().GetSlashTime();
    }    

    private void OnTriggerEnter(Collider collider)
    {           
        if (collider.CompareTag("sword") && _slashTime + 1f > Time.time)
        {
            Destroy(gameObject); // What is gameObject in this context?  the _sword?  something else?
        }
    }
}
  1. Использовать личные свойства. Почему? Поскольку это увеличивает модульность и защищает объекты, с которыми вы работаете, от случайного перезаписи их значений.
  2. В связи с этим используйте методы publi c для получения / изменения значений в других объектах. Методы Publi c - это ваш API.
  3. Условно начинать имена частных свойств с подчеркивания.
  4. Как я уже говорил в моем комментарии выше, вам сначала нужно Find() ваш желаемый объект, прежде чем вы сможете попытаться GetComponent<T>().
  5. Как уже говорили другие, попытка GetComponent<T>() в Update() является вычислительно дорогой. Лучше получить этот компонент на Start(), а затем поговорить с ним по мере необходимости (в данном случае во время столкновения).
  6. CompareTag() - более современный / приемлемый способ проверки тега.

EDIT:

[SerializeField] будет сохранять свойство частным, а также делать его доступным для редактора Unity. Это хорошо для отладки и связывания объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...