Unity3D — Почему переменная всегда верна, несмотря на то, что я установил в инспекторе?

Я установил переменную как SerializeField, чтобы выбрать значение из инспектора. Однако значение не меняется и всегда имеет «истинное» значение.

Я пытался сделать его общедоступным, изменить имя, повторно импортировать компонент, сбросить компонент... И, похоже, ничего не дает никакого эффекта, единственное, что работает, - это изменение значения в методе пробуждения.

public class AudioController : MonoBehaviour
{

    [SerializeField] private bool playSoundsAtColision; //WHY IS TRUE??? Is false in the inspector...

    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (this.playSoundsAtColision)
            Debug.Log("playSoundsAtColision = " + this.playSoundsAtColision + " by: " + gameObject.name, gameObject);
    }
}


Вот изображение всего кода: https://i.imgur.com/rT5BdhT.png (где вы можете видеть, что переменная только объявлена, затем проверена и напечатана, и другого доступа к ней больше нигде нет)

Вот что происходит, несмотря на то, что я установил в инспекторе: https://i.imgur.com/FLFugq8.png

Спасибо за вашу помощь заранее!


person Guillem Poy    schedule 23.04.2019    source источник
comment
Во-первых, вы должны включить свой код в свой вопрос, а не в виде изображения. Во-вторых, просматривая изображение, я не вижу весь ваш код, так как буквально все ваши функции закрыты (нажмите + слева от функции, чтобы открыть ее), кроме одной, и мы не можем видеть конец этой функции. Так что никто не может помочь вам с тем, что вы предоставили. У меня есть подозрение, что ваш метод пробуждения устанавливает для него значение false, поэтому не имеет значения, что вы указываете в инспекторе.   -  person AresCaelum    schedule 23.04.2019
comment
Я также вижу, что вы выполнили поиск по этой переменной, однако я понятия не имею, когда появился этот результат поиска или какие параметры вы использовали для выполнения этого поиска. Пробовали ли вы просто переписать сценарий с другим компонентом и посмотреть, будут ли у вас те же результаты? (Поэтому вместо этого создайте класс AudioController2, так как это поможет нам понять, является ли это проблемой сериализации)   -  person AresCaelum    schedule 23.04.2019
comment
Если он работает в методе Awake(), то почему бы не установить для логического значения значение false, а затем изменить его в инспекторе на true всякий раз, когда вам это нужно? ‹/б›   -  person Gray_Rhino    schedule 23.04.2019
comment
- Поскольку вы используете ключевое слово this, вы также должны отслеживать экземпляр класса (возможно, это вызывает проблему, хотя я не уверен) ‹/b› - Убедитесь, что вы не меняете значение в других сценариях.   -  person Gray_Rhino    schedule 23.04.2019
comment
@Gray_Rhino, как правило, если это частный член данных, и если его переменная упоминается только в этих 3 местах в этом скрипте, то вероятность того, что другой скрипт изменит значение, маловероятна. Вот почему в моем комментарии я упоминаю, что мы не знаем, какие были параметры для поиска ссылок или когда этот поиск ссылок был выполнен. Если он установит значение false в бодрствующем состоянии, то изменение его в инспекторе не будет иметь никакого значения, по этой причине я также указал, что мы не можем видеть, какой код находится в его методах на его скриншоте.   -  person AresCaelum    schedule 23.04.2019
comment
@OP, вы также должны включить скриншот компонентов ваших объектов (всех) и изменить оператор отладки, чтобы указать имя объекта, с которым возникла проблема. Также, если для каждого объекта должен быть разрешен только 1 экземпляр этого скрипта, вы можете добавить атрибут DisallowMultipleComponent.   -  person AresCaelum    schedule 23.04.2019
comment
@Eddge Вот код: github.com/guplem/Proj2/blob/feature/sound/Proj2/Assets/Scripts/ Я подумал, что в этом нет необходимости, потому что переменная используется только в тех строках, которые я написал в вопросе. Поиск выполняется по ссылкам, поэтому, если что-то использует эту переменную, это должно отображаться при поиске ссылок. Я также сделал поиск по имени, и я получил тот же результат. В методе пробуждения переменная не изменяется. Однако, если я изменю значение при пробуждении, значение изменится, как и ожидалось, но если я прокомментирую его и использую инспектор, это не так.   -  person Guillem Poy    schedule 23.04.2019
comment
Можете ли вы попробовать добавить атрибут, о котором я упоминал выше, я просто хочу исключить возможность того, что несколько этих скриптов находятся в одном и том же игровом объекте, или попробуйте создать новый скрипт AudioController, но как AudioControllerTest или что-то в этом роде.   -  person AresCaelum    schedule 23.04.2019
comment
Спасибо! Это и стало причиной такого поведения. Я проверил, что в префабе нет двух повторяющихся компонентов, а в варианте префаба они есть. Извините, я все еще привыкаю к ​​этому.   -  person Guillem Poy    schedule 23.04.2019


Ответы (2)


Проверить, если:

  1. Вы привязываете свойство, пока игра работает в автономном режиме — когда вы выходите из автономного режима, свойства сбрасываются.
  2. Вы не установили свойство в своем коде. Чтобы изменить логическое значение по умолчанию (true), вам нужно установить значение в поле playSoundsAtColision:

    public class AudioController : MonoBehaviour 
    {
    
        [SerializeField] public bool playSoundsAtColision = false; //you just shoud change the variable to public and default value to false or true
    
        private void OnCollisionEnter2D(Collision2D collision)
        {
            if (this.playSoundsAtColision)
                Debug.Log("playSoundsAtColision = " + this.playSoundsAtColision + " by: " + gameObject.name, gameObject);
        }
    }
    
person TopchetoEU    schedule 23.04.2019
comment
Гм, ваш код не нуждается в атрибуте SerializeField, поскольку общедоступная переменная в Unity автоматически сериализуется (если она сериализуема, что и логическое). Не говоря уже о том, что частное сериализованное поле инициализируется без необходимости устанавливать значение по умолчанию. ОП упомянул, что он уже пробовал № 2 из ваших предложений. поэтому № 1 должен быть просто комментарием, а не ответом. - person AresCaelum; 23.04.2019

Проблема заключалась в том, что компонент существовал несколько раз.

Я проверил, что в префабе нет двух повторяющихся компонентов, а в варианте префаба они есть. Я все еще привыкаю к ​​этому.

Как сказал AresCaelum, использование атрибута DisallowMultipleComponent должно помочь избежать подобных проблем.

person Guillem Poy    schedule 08.04.2020