(Unity) Попытка преобразовать скрипт пула объектов из UnityScript в C # — застрял на ошибке

#c# #unity3d #unityscript #object-pooling

#c# #unity3d #unityscript #объединение объектов

Вопрос:

Я нашел отличный скрипт объединения объектов, но он на UnityScript, а мой проект на C #. Я пытался преобразовать его, но застрял на одной ошибке, которую я не совсем понимаю. Вот мой скрипт:

 using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class EasyObjectPool : MonoBehaviour {
    private class PoolInfo{

    public string poolName;
    public GameObject prefab;
    public int poolSize;
    public bool canGrowPoolSize = true;

}

private class Pool{

    private List<PoolObject> list = new List<PoolObject>();
    public bool  canGrowPoolSize;

    public void  Add (PoolObject poolObject){
        list.Add(poolObject);
    }

    public int Count (){
        return list.Count;
    }


    public GameObject ObjectAt ( int index  ){

        PoolObject resu<
        if(index < list.Count) {
            result = list[index];
        }

        return resu<

    }
}
static public EasyObjectPool instance ;
PoolInfo[] poolInfo;

private Dictionary<string, Pool> poolDictionary  = new Dictionary<string, Pool>();


void Start () {

    instance = this;

    CheckForDuplicatePoolNames();

    CreatePools();

}

private void CheckForDuplicatePoolNames() {

    for (int index = 0; index < poolInfo.Length; index  ) {
        string poolName= poolInfo[index].poolName;
        if(poolName.Length == 0) {
            Debug.LogError(string.Format("Pool {0} does not have a name!",index));
        }
        for (int internalIndex = index   1; internalIndex < poolInfo.Length; internalIndex  ) {
            if(poolName == poolInfo[internalIndex].poolName) {
                Debug.LogError(string.Format("Pool {0} amp; {1} have the same name. Assign different names.", index, internalIndex));
            }
        }
    }
}

private void CreatePools() {

    foreach(PoolInfo currentPoolInfo in poolInfo){

        Pool pool = new Pool();
        pool.canGrowPoolSize = currentPoolInfo.canGrowPoolSize;

        for(int index = 0; index < currentPoolInfo.poolSize; index  ) {
            //instantiate
            GameObject go = Instantiate(currentPoolInfo.prefab) as GameObject;
            PoolObject poolObject = go.GetComponent<PoolObject>();
            if(poolObject == null) {
                Debug.LogError("Prefab must have PoolObject script attached!: "   currentPoolInfo.poolName);
            } else {
                //set state
                poolObject.ReturnToPool();
                //add to pool
                pool.Add(poolObject);
            }
        }

        Debug.Log("Adding pool for: "   currentPoolInfo.poolName);
        poolDictionary[currentPoolInfo.poolName] = pool;

    }
}

public GameObject GetObjectFromPool ( string poolName  ){
    PoolObject poolObject = null;

    if(poolDictionary.ContainsKey(poolName)) {
        Pool pool = poolDictionary[poolName];

        //get the available object
        for (int index = 0; index < pool.Count(); index  ) {
            PoolObject currentObject = pool.ObjectAt(index);

            if(currentObject.AvailableForReuse()) {
                //found an available object in pool
                poolObject = currentObject;
                break;
            }
        }


        if(poolObject == null) {
            if(pool.canGrowPoolSize) {
                Debug.Log("Increasing pool size by 1: "   poolName);

                foreach (PoolInfo currentPoolInfo in poolInfo) {    

                    if(poolName == currentPoolInfo.poolName) {

                        GameObject go = Instantiate(currentPoolInfo.prefab) as GameObject;
                        poolObject = go.GetComponent<PoolObject>();
                        //set state
                        poolObject.ReturnToPool();
                        //add to pool
                        pool.Add(poolObject);

                        break;

                    }
                }
            } else {
                Debug.LogWarning("No object available in pool. Consider setting canGrowPoolSize to true.: "   poolName);
            }
        }

    } else {
        Debug.LogError("Invalid pool name specified: "   poolName);
    }

    return poolObject;
}

}
 

Ошибка:
«Не удается неявно преобразовать тип ‘UnityEngine.GameObject’ в `PoolObject'»

для строк:

 PoolObject currentObject = pool.ObjectAt(index);
 

и

 return poolObject;
 

Этот скрипт ссылается на другой скрипт с именем PoolObject, но он не выдает мне никаких ошибок, поэтому я не подумал, что это связано с этими ошибками. Вот этот скрипт:

 using UnityEngine;
using System.Collections;

public class PoolObject : MonoBehaviour {

[HideInInspector]
public bool availableForReuse = true;


void Activate () {

    availableForReuse = false;
    gameObject.SetActive(true);

}


public void ReturnToPool () {

    gameObject.SetActive(false);
    availableForReuse = true;


}

public bool AvailableForReuse () {
    //true when isAvailableForReuse amp; inactive in hierarchy

    return availableForReuse amp;amp; (gameObject.activeInHierarchy == false);



}
}
 

Кто-нибудь скажет мне, что я здесь делаю не так?

Комментарии:

1. Какая из строк 106 и 144? Опубликуйте код в этих строках.

2. Извините, я не знал, что эта функция кода не нумерует строки. Я отредактировал свой вопрос

3. Есть PoolObject еще один класс, который вы не вставили выше?

4. Это имя скрипта, который фактически создает экземпляры объектов, но он не выдает мне никаких ошибок, поэтому я не подумал, что это связано. Я снова обновил свой вопрос с помощью этого скрипта.

5. Да, это то, что я подумал. Мой ответ ниже должен решить ваши проблемы. Удачи в игре!

Ответ №1:

Проблема 1

В функции GetObjectFromPool() вы пытаетесь вернуть a GameObject , но на самом деле вы даете ей a PoolObject .

Так что измените эту строку:

 public GameObject GetObjectFromPool(string poolName)
{
...
}
 

К этому:

 public PoolObject GetObjectFromPool(string poolName)
{
...
}
 

Теперь вы возвращаете PoolObject тип.

Проблема 2

То же самое происходит и в ObjectAt

 public GameObject ObjectAt(int index)
{           
    PoolObject result = null;

    if(index < list.Count)
       result = list[index];

    return resu<      
}
 

Просто поменяйтесь GameObject PoolObject местами еще раз, и все готово.


Проблема в обозримом будущем

Будет еще один класс , который вызывает GetObjectFromPool() , поэтому убедитесь , что если этому классу нужен GameObject , вы берете gameObject компонент из PoolObject .

Ответ №2:

pool.ObjectAt возвращает GameObject, а не присоединенный компонент типа PoolObject .

Измените ObjectAt на это:

 public PoolObject ObjectAt ( int index  ){

    PoolObject resu<
    if(index < list.Count) {
        result = list[index];
    }

    return resu<

}