SpriteRenderer меняет спрайт во время выполнения, не работает в сборке Android?

Если вы попытаетесь создать тестовую сцену с помощью простого скрипта, который будет менять спрайт каждый период времени.

Спрайт не меняется, но если вы попытаетесь зарегистрировать измененное имя спрайта, вы увидите, что оно изменилось успешно. А это значит, что не меняется только визуал.

Тестирование на Unity 6000.0.3f1 и на Android S24 Ultra

Мой TestSpriteRendererChange.cs сценарий

using System.Collections;
using UnityEngine;

public class TestSpriteRendererChange : MonoBehaviour
{
    [SerializeField] private SpriteRenderer spriteRenderer;
    [SerializeField] private Sprite[] sprites;

    private void Start()
    {
        StartCoroutine(ChangeSprites());
    }

    private IEnumerator ChangeSprites()
    {
        var index = 0;

        foreach (var sprite in sprites)
        {
            Debug.Log($"before sprite: {spriteRenderer.sprite.name}");

            spriteRenderer.sprite = sprite;

            Debug.Log($"after sprite: {spriteRenderer.sprite.name}");

            yield return new WaitForSeconds(0.1f);

            index++;
        }

        if (index == sprites.Length)
        {
            index = 0;

            StopCoroutine(nameof(ChangeSprites));
            StartCoroutine(nameof(ChangeSprites));
        }
    }
}

Поведение в редакторе Unity

Поведение на устройстве Android

Эта проблема связана только с URP 2D, она отлично работает во встроенных RP 2D-проектах.

Хорошо. Единственное соображение: я думал, что Android работает со скоростью 30 кадров в секунду, поэтому 0,1 с будут равны 3 кадрам. Любопытен тот факт, что его форма меняется, а не текстура, но графические возможности значительно меньше. Получаете ли вы какие-либо дополнительные сообщения в файлах журнала проигрывателя?

BugFinder 27.05.2024 18:47

@BugFinder Время не проблема, я увеличил его до 1f, что составляет одну секунду, и проблема та же

CODEHUB 27.05.2024 20:16

Хорошо, но, поскольку об этом не упоминалось, это было хорошее место для начала. Необходимость переделки компонента кажется большим молотком, и хотя, конечно, он действительно сбрасывается, это похоже на то, о чем вам следует сообщить Unity.

BugFinder 27.05.2024 20:51

Да, я подал отчет в Unity

CODEHUB 27.05.2024 22:21
0
4
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это была настоящая ошибка в Unity 6000.0.3f1, поэтому я сделал следующее.

Чтобы обойти эту проблему, я изменил свой сценарий следующим образом:

Я изменил свой TestSpriteRendererChange.cs на следующий: -

using System.Collections;
using UnityEngine;
 
public class TestSpriteRendererChange : MonoBehaviour
{
    [SerializeField] private GameObject spriteGO;
    [SerializeField] private Sprite[] sprites;
 
    private void Start()
    {
        StartCoroutine(ChangeSprites());
    }
 
    private IEnumerator ChangeSprites()
    {
        var index = 0;
 
        foreach (var sprite in sprites)
        {
            // check if SpriteRenderer exists
            var hasComponent = spriteGO.TryGetComponent(out SpriteRenderer sr);
 
            // we could cash reference to sortingLayer and sortingOrder to avoid reset
            if (hasComponent)
            {
                // we remove the component if exists
                Destroy(sr);
            }
 
            // wait for end of frame to avoid null reference error
            yield return new WaitForEndOfFrame();
 
            // we add the SpriteRenderer component again
            var spriteRenderer = spriteGO.AddComponent<SpriteRenderer>();
 
            spriteRenderer.sprite = sprite;
 
            Debug.Log($"after sprite: {spriteRenderer.sprite.name}");
 
            yield return new WaitForSeconds(1f);
 
            index++;
        }
 
        if (index == sprites.Length)
        {
            index = 0;
 
            StopCoroutine(nameof(ChangeSprites));
            StartCoroutine(nameof(ChangeSprites));
        }
    }
}

Проблема решается удалением компонента SpriteRenderer и его повторным добавлением.

Дайте мне знать, если есть лучшее решение.

Другие вопросы по теме