La gestió de memòria és un aspecte crucial en el desenvolupament de jocs amb Unity, especialment quan es tracta de jocs complexos o que han de funcionar en dispositius amb recursos limitats. Una gestió de memòria eficient pot millorar significativament el rendiment del joc i evitar problemes com ara les caigudes de rendiment o els bloquejos.

Conceptes Clau

  1. Memòria Dinàmica vs. Memòria Estàtica:

    • Memòria Dinàmica: S'assigna i es desassigna durant l'execució del programa. Exemple: objectes creats amb new en C#.
    • Memòria Estàtica: S'assigna en temps de compilació i es manté durant tota l'execució del programa. Exemple: variables estàtiques.
  2. Garbage Collection (GC):

    • Unity utilitza un sistema de Garbage Collection per gestionar la memòria dinàmica. El GC allibera memòria que ja no és accessible per l'aplicació, però pot causar pauses en l'execució del joc.
  3. Fragmentació de Memòria:

    • La fragmentació de memòria es produeix quan hi ha espais lliures no contigus en la memòria, cosa que pot dificultar l'assignació de grans blocs de memòria.

Bones Pràctiques per a la Gestió de Memòria

  1. Evitar l'Assignació Dinàmica Excessiva

  • Reutilitzar Objectes: En lloc de crear i destruir objectes constantment, reutilitza'ls. Per exemple, utilitza un object pool per gestionar objectes que es creen i destrueixen freqüentment.

    public class ObjectPool : MonoBehaviour
    {
        public GameObject objectPrefab;
        private Queue<GameObject> pool = new Queue<GameObject>();
    
        public GameObject GetObject()
        {
            if (pool.Count > 0)
            {
                GameObject obj = pool.Dequeue();
                obj.SetActive(true);
                return obj;
            }
            else
            {
                return Instantiate(objectPrefab);
            }
        }
    
        public void ReturnObject(GameObject obj)
        {
            obj.SetActive(false);
            pool.Enqueue(obj);
        }
    }
    

  1. Minimitzar l'Ús de Strings

  • Evitar la Concatenació de Strings: La concatenació de strings pot generar molta memòria dinàmica. Utilitza StringBuilder en lloc de concatenar strings directament.

    using System.Text;
    
    StringBuilder sb = new StringBuilder();
    sb.Append("Hello");
    sb.Append(" ");
    sb.Append("World");
    string result = sb.ToString();
    

  1. Optimitzar l'Ús de Col·leccions

  • Utilitzar Col·leccions Adequades: Tria la col·lecció adequada per a cada situació. Per exemple, utilitza List<T> en lloc de ArrayList per evitar conversions de tipus.

    List<int> numbers = new List<int>();
    numbers.Add(1);
    numbers.Add(2);
    

  1. Gestionar Correctament els Recursos

  • Alliberar Recursos No Utilitzats: Assegura't d'alliberar recursos com ara textures, àudio i altres actius quan ja no es necessiten.

    void OnDestroy()
    {
        if (texture != null)
        {
            Destroy(texture);
        }
    }
    

  1. Utilitzar el Profiler de Unity

  • Profiler: Utilitza el Profiler de Unity per identificar problemes de memòria i optimitzar el teu joc. El Profiler et permet veure quanta memòria s'està utilitzant i quins objectes estan ocupant més memòria.

    Unity Profiler

Exercicis Pràctics

Exercici 1: Implementar un Object Pool

Descripció: Implementa un sistema d'object pool per gestionar projectils en un joc de disparar.

Passos:

  1. Crea un prefab de projectil.
  2. Implementa una classe ProjectilePool que gestioni la creació i reutilització de projectils.
  3. Modifica el codi del joc per utilitzar el ProjectilePool en lloc de crear i destruir projectils constantment.

Solució:

public class ProjectilePool : MonoBehaviour
{
    public GameObject projectilePrefab;
    private Queue<GameObject> pool = new Queue<GameObject>();

    public GameObject GetProjectile()
    {
        if (pool.Count > 0)
        {
            GameObject projectile = pool.Dequeue();
            projectile.SetActive(true);
            return projectile;
        }
        else
        {
            return Instantiate(projectilePrefab);
        }
    }

    public void ReturnProjectile(GameObject projectile)
    {
        projectile.SetActive(false);
        pool.Enqueue(projectile);
    }
}

Exercici 2: Optimitzar l'Ús de Strings

Descripció: Optimitza un codi que concatena strings en un bucle.

Codi Original:

string result = "";
for (int i = 0; i < 100; i++)
{
    result += i.ToString() + ", ";
}

Solució:

using System.Text;

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
{
    sb.Append(i.ToString());
    sb.Append(", ");
}
string result = sb.ToString();

Conclusió

La gestió de memòria és essencial per garantir que el teu joc funcioni de manera eficient i sense problemes. Mitjançant la implementació de bones pràctiques com la reutilització d'objectes, l'optimització de l'ús de strings i col·leccions, i l'alliberament de recursos no utilitzats, pots millorar significativament el rendiment del teu joc. Utilitza el Profiler de Unity per identificar i solucionar problemes de memòria, i assegura't de provar i optimitzar constantment el teu codi.

Curs de Unity

Mòdul 1: Introducció a Unity

Mòdul 2: Programació Bàsica en Unity

Mòdul 3: Treballant amb Actius

Mòdul 4: Física i Col·lisions

Mòdul 5: Interfície d'Usuari (UI)

Mòdul 6: Àudio en Unity

Mòdul 7: Programació Avançada

Mòdul 8: Física Avançada i IA

Mòdul 9: Optimització i Rendiment

Mòdul 10: Publicació i Més Enllà

© Copyright 2024. Tots els drets reservats