- Home /
How to clear cached images from sprite renderer
I have a sprite renderer and an animator. I use them to display a png sequence of a lot of images. Then I want to continue with another sprite renderer and animator to show different image sequence. And so on.
My question is how to release the memory from each gameobject with the attached sprite renderer.
Sorry I am new to unity - any help appreciated.,
Destroy( texture );
releases the texture memory. But I'm not sure about sprites specifically - probably the same call or maybe Destroy( sprite );
will do the job.
One important thing to note here is that read-only
textures allocate pixel data on the GPU memory only, while read-write
textures allocate it both both on the GPU and CPU memory (so prefer RO).
Thank you @andrew-lukasik for your answer! Unfortunately it didn't work. I can see from the profiler that the Texture memory is never released.
I can tell you from my practical experience, where this was required for app not to crash - Destroy( texture )
, as a memory release mechanism, does work.
The devil is in the details. But I won't insist.
Answer by andrew-lukasik · Apr 11 at 02:14 PM
Here is an experiment. It:
reads all png images from given location as
Texture2D
s & converts them toSprite
sdisplays them all in sequence as animation frames
deallocates everything
repeats
Note the square wave-like memory allocation graph it produced and let it be a proof this allocation/deallocation bussines works just fine.
LetsRick.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using IO = System.IO;
public class LetsRick : MonoBehaviour
{
[SerializeField] string _directoryPath = "D:/rick-n-roll/";
[SerializeField] float _delayBetweenFrames = 0.16f;
SpriteRenderer _spriteRenderer = null;
IEnumerator Start ()
{
_spriteRenderer = gameObject.AddComponent<SpriteRenderer>();
var wait = new WaitForSeconds( 0.5f );
string[] files = IO.Directory.GetFiles( _directoryPath );
if( files.Length!=0 )
{
List<Sprite> frames = new List<Sprite>(128);
while( true )
{
// load all images as sprites, at once:
foreach( string filePath in files )
{
var bytes = IO.File.ReadAllBytes( filePath );
Texture2D texture = new Texture2D( 2 , 2 , TextureFormat.RGB24 , 0 , false );
if( ImageConversion.LoadImage( texture , bytes , true ) )
{
Sprite sprite = Sprite.Create( texture , new Rect(0,0,texture.width,texture.height) , new Vector2( 0.5f , 0.5f ) );
frames.Add( sprite );
}
else Debug.LogWarning($"image load failed, path: \"{filePath}\"");
}
// display all images in sequence:
var frameDuration = new WaitForSeconds( _delayBetweenFrames );
for( int i=0 ; i<frames.Count ; i++ )
{
_spriteRenderer.sprite = frames[i];
yield return frameDuration;
}
// free memory up:
for( int i=frames.Count-1 ; i!=-1 ; i-- )
{
Object.Destroy( frames[i].texture );
Object.Destroy( frames[i] );
}
frames.Clear();
// a lof of time to check it out in the profiler:
yield return wait;
}
}
else Debug.LogWarning($"no files found for path: \"{_directoryPath}\"");
}
}
Thank you so much for your time! I tried it and I can see it works as for the memory. I can see the images on the scene tab but not on the game tab. I guess I am doing something wrong..
Ok works fine with a small change!
When we create the sprite we should change new Vector2( texture.width*0.5f , 0 ) to something like new Vector2(0.5f, 0.5f). This sets the pivot point.
In the documentation it is said "This is a Vector2 relative to the rect where Vector2(0.0f, 0.0f) is the bottom left and Vector2(1.0f, 1.0f) is the top right.".
Otherwise the sprite will be moved to a crazy position and this was the reason I couldn't see it on Game tab.
Good point! I totally missed that important detail
Your answer
Follow this Question
Related Questions
Animated sprite's bounds not in sync with its visuals 0 Answers
Syncing a sprite mask to an animated sprite renderer every frame 1 Answer
Animating player in Unity 0 Answers
Sprite falls outside the collider2D 0 Answers
2d sprite Animation - Fire at frame 2 Answers