Пропадают ссылки на компоненты.

Программирование на Юнити.

Пропадают ссылки на компоненты.

Сообщение DikSan 05 авг 2020, 23:21

Всем привет. Есть класс Player, который имеет открытое свойство Transform, хранящее ссылку на Transform. Ссылка получается через Transform = transform. Ссылка приходит не нулевая. Есть еще один класс PlayerController, прикрепленный к тому же объекту. В методе Start он через GetComponent получает ссылку на класс Player. И далее в этом же методе Start этот класс получает ссылку на Transform объекта, обращаясь к свойствам класса Player, и сохраняет их в своих свойствах. Эти Transform'ы никто снаружи не меняет. Да и далее по сообщениям внутри свойств это было бы видно. Вот код классов.
Класс Player:
Синтаксис:
Используется csharp
    [HideInInspector] private Transform transform1;
public Transform Transform
    {
        get
        {
            Debug.Log("[Player] Transform Asked. IsNull: " + (transform1 == null));
            return transform1;
        }
        set
        {
            Debug.Log("[Player] Transform Changed! IsNull: " + (value == null));
            transform1 = value;
        }
    }

    protected override void Awake()
    {
        base.Awake();
        Transform = transform;
        Debug.Log("[Player] Awake");
    }

Класс PlayerController:
Синтаксис:
Используется csharp
    private Transform _transform;
 public Transform Transform {
        get
        {
            Debug.Log("[PlayerController] Transform Asked. IsNull: " + (_transform == null));
            return _transform;
        }
        set
        {
            Debug.Log("[PlayerController] Transform Changed! IsNull: " + (value == null));
            _transform = value;
        }
    }

    Player player;
    private void Start()
    {
        Debug.Log("[PlayerController] Start");
        player = GetComponent<Player>();
        Debug.Log("[PlayerController] Player Is Null: " + (player == null));
       
        Transform = player.Transform;
    }
    private void GamepadLook(Vector2 value)
    {
        sbyte signX = (sbyte)Mathf.Sign(value.x);
        if (value.x != 0)
        {
            if (IsFacingRight && value.x < 0) { Flip(); IsFacingRight = false; }
            if (!IsFacingRight && value.x > 0) { Flip(); IsFacingRight = true; }
        }
    }
    void Flip()
    {
        Debug.Log("[PlayerController] 2Transform Is null: " + (Transform == null));
        if (Transform == null)
        {
            Transform = Player.Instance.Transform;
        }
        Transform.Rotate(0f, 180f, 0f);
    }
 

Теперь к проблеме. При первом запуске игры загружается меню. При нажатии любой клавиши загружается игровая сцена с игроком, на котором эти скрипты весят. Игрок нормально передвигается, все работает корректно. Далее после возврата обратно в меню сцена с игроком выгружается. При повторном входе в игру сцена снова загружается, но на второй раз персонаж уже не ходит и (до добавления проверок на null) юнька выдавала исключение MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. При этом игрок на сцене просто сразу есть. Не исчезает, не телепортируется, не умирает, не создается из префаба. После того, как в методе Flip переприсваивается значение далее ссылка всегда указывает куда нужно.
При загрузке игровой сцены сообщения выходят в следующем порядке:
[Player] Transform Changed! IsNull: False
[Player] Awake
[PlayerController] Start
[PlayerController] Player Is Null: False
[Player] Transform Asked. IsNull: False
[PlayerController] Transform Changed! IsNull: False
И при попытке подвигать стик:
[PlayerController] Transform Asked. IsNull: True
[PlayerController] 2Transform Is null: True
[PlayerController] Transform Asked. IsNull: True
[Player] Transform Asked. IsNull: False
[PlayerController] Transform Changed! IsNull: False
[PlayerController] Transform Asked. IsNull: False
И после этого уже при движении стика постоянно
[PlayerController] 2Transform Is null: False
[PlayerController] Transform Asked. IsNull: False
У меня закрадывается подозрение, что это сборщик мусора чистит ссылочки, но кто знает, может я чего-то очевидного не вижу.
P.S. Я понимаю, что можно не заморачиваться, а просто взять в Старте ссылки на компонент с помощью еще одного GetComponent, но все же хотелось бы узнать в чем причина такого поведения.
Последний раз редактировалось DikSan 06 авг 2020, 09:46, всего редактировалось 2 раз(а).
DikSan
UNIт
 
Сообщения: 52
Зарегистрирован: 23 июн 2017, 16:34

Re: Пропадают ссылки на компоненты.

Сообщение DikSan 06 авг 2020, 09:42

Попробовал в Старте просто присвоить Transform = transform, но так же выдаёт сMissingReferenceException.
DikSan
UNIт
 
Сообщения: 52
Зарегистрирован: 23 июн 2017, 16:34

Re: Пропадают ссылки на компоненты.

Сообщение Jarico 06 авг 2020, 11:17

Зачем ты себе усложняешь код? Проще было без set обойтись

Синтаксис:
Используется csharp
private Transform _transform;

public Transform Transform
{
get
{
return _transform;
}
}

void Start(){
_transform = transform;
}

 
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт

Re: Пропадают ссылки на компоненты.

Сообщение DikSan 06 авг 2020, 11:23

Set Был добавлен во время попытки найти ошибку, чтобы узнать, когда _transform перезаписывается, если это вдруг где-то происходит. И благодаря этому set'у я теперь знаю, что значение записывается только в методе Start ну и потом уже только в GamepadLook, когда двигается стик
DikSan
UNIт
 
Сообщения: 52
Зарегистрирован: 23 июн 2017, 16:34

Re: Пропадают ссылки на компоненты.

Сообщение DikSan 06 авг 2020, 11:38

Новые подробности (проблемы). При добавлении на сцену нескольких объектов со SpriteRenderer и ParticleSystem начинает выскакивать ошибка при загрузке сцены:
In order to call GetTransformInfoExpectUpToDate, RendererUpdateManager.UpdateAll must be called first.
Использую URP. Материал Sprite-Unlit-Default и для спрайтов и для частиц.
При этом если в SpriteRenderer установлен спрайт размером 128*128 (Без фильтров и сглаживания, кастомный пивот {0.5, 0.07}), то ошибка выскакивает при каждой загрузке сцены. Если же установлен другой спрайт, размером 64*64 (Без фильтров и сглаживания, кастомный пивот {0.5, 0.859375}), то ошибка выбрасывается всего один раз при первой загрузке сцены. Даже после выхода из Play Mode и входа обратно ошибка больше не появляется, пока не будет что-то изменено в настройках спрайта. После изменения (например положения пивота) ошибка снова 1 раз выскакивает.
Не знаю связаны ли эти ошибки, но все же мало ли.
P.S. Также 1-2 дня назад юнити вылетела и выкинула Fatal Error ... Index 22. Текст не запомнил, не заскринил. По этому загадочному индексу ничего не нашел. Потом в течение часа-двух после этого редачил различные скрипты, в том числе и PlayerController, после чего и перестал находиться transform, до всего этого все работало нормально. Все места, где этот transform используется приведены в моем первом сообщении и вся работа с ним максимально прозрачна, поэтому "Так посмотри те места, где ты редачил последний раз, там и проблема" не поможет. Ошибка, описанная в данном сообщении появлялась и ранее.
DikSan
UNIт
 
Сообщения: 52
Зарегистрирован: 23 июн 2017, 16:34

Re: Пропадают ссылки на компоненты.

Сообщение Jarico 06 авг 2020, 12:40

DikSan писал(а):Set Был добавлен во время попытки найти ошибку, чтобы узнать, когда _transform перезаписывается, если это вдруг где-то происходит.


Брейкпоинты ставь в коде и смотри что откуда вызывается... (в Visual Studio отладку включи и подключи к юнити)
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт

Re: Пропадают ссылки на компоненты.

Сообщение aquafina 01 сен 2020, 22:14

Jarico писал(а):Зачем ты себе усложняешь код? Проще было без set обойтись

Синтаксис:
Используется csharp
private Transform _transform;

public Transform Transform
{
get
{
return _transform;
}
}

void Start(){
_transform = transform;
}

 


Синтаксис:
Используется csharp
private Transform _transform;

public Transform Transform => _transform;

void Start(){
_transform = transform;
}

 


или так...
aquafina
UNец
 
Сообщения: 1
Зарегистрирован: 01 сен 2020, 22:11

Re: Пропадают ссылки на компоненты.

Сообщение Jarico 02 сен 2020, 09:46

aquafina писал(а):
Jarico писал(а):Зачем ты себе усложняешь код? Проще было без set обойтись

Синтаксис:
Используется csharp
private Transform _transform;

public Transform Transform
{
get
{
return _transform;
}
}

void Start(){
_transform = transform;
}

 


Синтаксис:
Используется csharp
private Transform _transform;

public Transform Transform => _transform;

void Start(){
_transform = transform;
}

 


или так...


Разницы в производительности не будет, компилятор все равно в get сделает
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 5