Unity: Come usare la classe Resources caricando asset dinamicamente senza impazzire

Anche se uso, sperimento e creo prototipi con Unity3d da più di un anno e mezzo, non ho mai avuto necessità di caricare degli asset dinamicamente a runtime.

Dal principio sono stato ingannato dalla semplicità dei metodi di System.IO che hanno funzionato da subito, perfettamente, nell'editor.

Metodi SYSTEM.IO usati:

// check if resource exists
System.IO.File.Exists(fileName)

// custom method to count png in a specified folder
int CountPNGinDirectoryPath(string dirPath){
   string[] totalFiles = System.IO.Directory.GetFiles(path);
   int counter = 0;
   foreach (string item in totalFiles){
      if (item.EndsWith(".png")){
         counter++;
      }
   }
   return counter;
}

 

Ottimo!
Ora esportiamo e compiliamo per iOS


ERROR



Resources classe e directory:

Dopo alcune ricerche ho trovato il pezzo mancante, che all'inizio avevo saltato perchè mi sembrava troppo complicato rispetto a SYSTEM.IO.

Dalla documentazione di Unity::
The Resources class allows you to find and access Objects including assets.
[...]
All assets in the "Resources" folders will be included in a build.


Quindi la classe Resources serve ad operare sulle risorse/asset presenti nella/nelle cartelle "Resources", e nelle build verranno inclusi tutti gli assets presenti nella cartella, indipendentemente dal fatto che siano o meno necessari per quella determinata build/piattaforma.

Per prima cosa bisogna creare una o più cartelle Resources (se sono piu` di una a Runtime verranno trattate come fossero una unica), e spostare gli asset su cui si ha necessità di accesso o manipolazione a runtime sotto quest'ultima o una sotto-directory.

In seconda istanza per accedere ai suddetti assets è necessario usare i metodi della classe Resources inserendo i path come se la cartella Resources fosse la "root" del percorso, ed usando solo "/" (slash) e non "\" (backslash).
L'estensione dei file deve essere esclusa e le lettere maiuscole e minuscole devono essere corrette, in quanto il percorso usato nei metodi è "case-sensitive".

Per esempio un asset chiamato image.png nella cartella Background sotto Resources, sarà chiamata nei metodi di Resources accedendo con "Background/image".


I metodi corrispettivi usando Resources invece di SYSTEM.IO:

 

myTexture = (Texture2D)Resources.Load(resourceString, typeof(Texture2D));
// check if file exists - Resource.Load is null if resource does not exists
if (!myTexture) {
   // create 2d texture to fill the sprite
   myTexture = new Texture2D(1,1);
}

int CountPNGinDirectoryPath(string dirPath){
   int counter = 0;
   Object[] maps = Resources.LoadAll(dirPath);
   counter = maps.Length;
   Resources.UnloadUnusedAssets();
   return counter;
}

Commenti