ObjectPool [РЕШЕНО]

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

ObjectPool [РЕШЕНО]

Сообщение neozman 11 сен 2013, 17:45

Взял скрипт из игры AngryBots "Spawner" - обжект пул и переделал его под C#. Все идентично, но работает по разному: В джава - все нормально, а в шарпе создаются начальные объекты, потом считываются по 1 разу каждый, а дальше все. Но несмотря на это, по дебагам объекты считываются.

Вот код:

Синтаксис:
Используется csharp
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class GameObjectPool : MonoBehaviour
{
       
        static GameObjectPool Pool;
        public ObjectCache[] caches;
       
        public Hashtable activeCachedObjects;
       
        [Serializable]
       
        public class ObjectCache
        {
                [SerializeField]
                public GameObject prefab;      
                [SerializeField]
                public int cacheSize = 10;
               
                private int cacheIndex = 0;
                private GameObject[] objects;
               
                [HideInInspector]
                public void Initialize()
                {
                        objects = new GameObject[cacheSize];
                        for (var i = 0; i < cacheSize; i++)
                        {
                                objects[i] = MonoBehaviour.Instantiate (prefab) as GameObject;
                                objects[i].SetActive (false);
                                objects[i].name = objects[i].name + i;
                        }
                }
               
                public GameObject GetNextObjectInCache()
                {
                        GameObject obj = null;
                       
                        for (var i = 0; i < cacheSize; i++)
                        {
                                obj = objects[cacheIndex];
       
                                if (!obj.activeSelf) {  break; }
       
                                // If not, increment index and make it loop around
                                // if it exceeds the size of the cache
                                cacheIndex = (cacheIndex + 1) % cacheSize;
                        }
                               
                        if (obj.activeSelf)
                        {
                                Debug.LogWarning (
                                        "Spawn of " + prefab.name +
                                        " exceeds cache size of " + cacheSize +
                                        "! Reusing already active object.", obj);
                                GameObjectPool.Unspawn(obj);
                        }
                       
                        cacheIndex = (cacheIndex + 1) % cacheSize;
                    return obj;
                }              
        }
       
    void Awake()
        {
                Pool = this;
                int amount = 0;
               
                for (var i = 0; i < caches.Length; i++)
                {
                        caches[i].Initialize ();
                        amount += caches[i].cacheSize;
                }
               
                activeCachedObjects = new Hashtable(amount);
        }
       
        public static GameObject Spawn ( GameObject prefab, Vector3 position, Quaternion rotation )
        {
                ObjectCache cache = null;
                if ( Pool != null )
                {
                        for ( var i = 0; i < Pool.caches.Length; i++)
                        {
                                if ( Pool.caches[i].prefab == prefab )
                                {
                                        cache = Pool.caches[i];
                                }
                        }
                }
               
                if ( cache == null )
                {
                        return GameObject.Instantiate ( prefab, position, rotation ) as GameObject;
                }
               
                GameObject obj = cache.GetNextObjectInCache();
               
                obj.transform.position = position;
                obj.transform.rotation = rotation;
               
                obj.SetActive(true);


                Pool.activeCachedObjects[obj] = true;

               
                return obj;
        }
       
        public static void Unspawn( GameObject objectToDestroy )
        {
                if ( Pool != null && Pool.activeCachedObjects.ContainsKey(objectToDestroy) )
                {
                        Debug.Log (Pool.activeCachedObjects.ContainsKey(objectToDestroy).ToString ());
                        objectToDestroy.SetActive(false);
                        Pool.activeCachedObjects[objectToDestroy] = false;
                       
                }
                else
                {
                        Unspawn ( objectToDestroy );
                }
        }
               

}


И на всякий прикладываю JS

Синтаксис:
Используется javascript
#pragma strict

static var spawner : Spawner;

var caches : ObjectCache[];

var activeCachedObjects : Hashtable;


class ObjectCache {
        var prefab : GameObject;
        var cacheSize : int = 10;

        private var objects : GameObject[];
        private var cacheIndex : int = 0;

        function Initialize ()
        {
                objects = new GameObject[cacheSize];

                // Instantiate the objects in the array and set them to be inactive
                for (var i = 0; i < cacheSize; i++)
                {
                        objects[i] = MonoBehaviour.Instantiate (prefab) as GameObject;
                        objects[i].SetActive (false);
                        objects[i].name = objects[i].name + i;
                }
        }

        function GetNextObjectInCache () : GameObject {
                var obj : GameObject = null;

                // The cacheIndex starts out at the position of the object created
                // the longest time ago, so that one is usually free,
                // but in case not, loop through the cache until we find a free one.
                for (var i : int = 0; i < cacheSize; i++) {
                        obj = objects[cacheIndex];

                        // If we found an inactive object in the cache, use that.
                        if (!obj.activeSelf)
                                break;

                        // If not, increment index and make it loop around
                        // if it exceeds the size of the cache
                        cacheIndex = (cacheIndex + 1) % cacheSize;
                }

                // The object should be inactive. If it's not, log a warning and use
                // the object created the longest ago even though it's still active.
                if (obj.activeSelf) {
                        Debug.LogWarning (
                                "Spawn of " + prefab.name +
                                " exceeds cache size of " + cacheSize +
                                "! Reusing already active object.", obj);
                        Spawner.Destroy (obj);
                }

                // Increment index and make it loop around
                // if it exceeds the size of the cache
                cacheIndex = (cacheIndex + 1) % cacheSize;

                return obj;
        }
}

function Awake () {
        // Set the global variable
        spawner = this;

        // Total number of cached objects
        var amount : int = 0;

        // Loop through the caches
        for (var i = 0; i < caches.length; i++) {
                // Initialize each cache
                caches[i].Initialize ();

                // Count
                amount += caches[i].cacheSize;
        }

        // Create a hashtable with the capacity set to the amount of cached objects specified
        activeCachedObjects = new Hashtable (amount);
}

static function Spawn (prefab : GameObject, position : Vector3, rotation : Quaternion) : GameObject {
        var cache : ObjectCache = null;

        // Find the cache for the specified prefab
        if (spawner) {
                for (var i = 0; i < spawner.caches.length; i++) {
                        if (spawner.caches[i].prefab == prefab) {
                                cache = spawner.caches[i];
                        }
                }
        }

        // If there's no cache for this prefab type, just instantiate normally
        if (cache == null) {
                return Instantiate (prefab, position, rotation) as GameObject;
        }

        // Find the next object in the cache
        var obj : GameObject = cache.GetNextObjectInCache ();

        // Set the position and rotation of the object
        obj.transform.position = position;
        obj.transform.rotation = rotation;

        // Set the object to be active
        obj.SetActive (true);
        spawner.activeCachedObjects[obj] = true;

        return obj;
}

static function Destroy (objectToDestroy : GameObject) {
        if (spawner && spawner.activeCachedObjects.ContainsKey (objectToDestroy)) {
                objectToDestroy.SetActive (false);
                spawner.activeCachedObjects[objectToDestroy] = false;
        }
        else {
                objectToDestroy.Destroy (objectToDestroy);
        }
}


2 дня бьюсь, ничего не нашел. :(
Последний раз редактировалось neozman 11 сен 2013, 21:26, всего редактировалось 1 раз.
neozman
UNIт
 
Сообщения: 94
Зарегистрирован: 23 июн 2013, 10:16

Re: ObjectPool

Сообщение neozman 11 сен 2013, 18:31

Прошу прощения за то, что тем наплодил. Очень хочется проблему решить. :(

Нашел косяк. Совершенно в другом. Объект просто не успевал инициализорваться из-за того, что вместо метода OnEnable, стоял Start() -.-
neozman
UNIт
 
Сообщения: 94
Зарегистрирован: 23 июн 2013, 10:16


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 17