Если вы попытаетесь создать тестовую сцену с помощью простого скрипта, который будет менять спрайт каждый период времени.
Спрайт не меняется, но если вы попытаетесь зарегистрировать измененное имя спрайта, вы увидите, что оно изменилось успешно. А это значит, что не меняется только визуал.
Тестирование на 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-проектах.
@BugFinder Время не проблема, я увеличил его до 1f, что составляет одну секунду, и проблема та же
Хорошо, но, поскольку об этом не упоминалось, это было хорошее место для начала. Необходимость переделки компонента кажется большим молотком, и хотя, конечно, он действительно сбрасывается, это похоже на то, о чем вам следует сообщить Unity.
Да, я подал отчет в Unity
Это была настоящая ошибка в 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 и его повторным добавлением.
Дайте мне знать, если есть лучшее решение.
Хорошо. Единственное соображение: я думал, что Android работает со скоростью 30 кадров в секунду, поэтому 0,1 с будут равны 3 кадрам. Любопытен тот факт, что его форма меняется, а не текстура, но графические возможности значительно меньше. Получаете ли вы какие-либо дополнительные сообщения в файлах журнала проигрывателя?