Unity3D: cómo agrupar objetos sin un generador de singleton
– UnityAssets3Free
buenas , soy kein y en esta ocasion os traigo
nueva pregunta curiosa
Normalmente, si usa un grupo de objetos, crea un singleton como en este video. Después de ver este video, descubrí lo confuso que puede ser singleton. ¿Hay alguna otra forma de agrupar objetos sin usar singletons? En cambio, quiero usar Eventos.
1 respuesta 1
Debería mantener el grupo en una clase que no sea singleton y manejar su grupo de objetos de juego de acuerdo con sus eventos. En cuanto a llamarlos con eventos, «Quiero usar eventos» no es una pregunta muy concreta. Debe configurar sus eventos para escuchar (método de suscripción) y llamarlos en código donde sea que ocurran, esto es invocar el método. Te sugiero que si no lo tienes claro, pruebes a usar el unity eventos (OnTriggerEnter, if(Input.GetMouseButtonDown(0))
en el Update
etc.) hasta que profundice lo suficiente en el tema para comprenderlos y crear los suyos propios con eventos de C# o UnityEvents
cuando necesario.
Encuentre dos scripts de plantilla, un grupo y un controlador de eventos para manipular sus objetos en la escena. Puede verificar esto en una escena vacía con sus respectivos dos objetos de juego para adjuntar y el objeto que desea en el grupo presionando ‘espacio’ y ‘A’ para crear desde el grupo y regresar al grupo respectivamente.
Gerente de piscina:
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour
private Queue<GameObject> objPool;
private Queue<GameObject> activeObj;
private int poolSize = 10;
public GameObject objPrefab;
void Start()
//queues init
objPool = new Queue<GameObject>();
activeObj = new Queue<GameObject>();
//pool init
for (int i = 0; i < poolSize; i++)
GameObject newObj = Instantiate(objPrefab);
objPool.Enqueue(newObj);
newObj.SetActive(false);
public GameObject GetRandomActiveGO()
GameObject lastActive = default;
if (activeObj.Count > 0)
lastActive = activeObj.Dequeue();
else
Debug.LogError("Active object queue is empty");
return lastActive;
//get from pool
public GameObject GetObjFromPool(Vector3 newPosition, Quaternion newRotation)
GameObject newObject = objPool.Dequeue();
newObject.SetActive(true);
newObject.transform.SetPositionAndRotation(newPosition, newRotation);
//keep actives to be retrieved
activeObj.Enqueue(newObject);
return newObject;
//return to pool
public void ReturnObjToPool(GameObject go)
go.SetActive(false);
objPool.Enqueue(go);
Controlador de eventos:
using UnityEngine;
public class EventHandler : MonoBehaviour
public delegate GameObject OnSpacePressed(Vector3 newPosition, Quaternion newRotation);
public OnSpacePressed onSpacePressed;
public delegate void OnAKeyPressed(GameObject go);
public OnAKeyPressed onAKeyPressed;
public PoolManager poolManager;
void Start()
onSpacePressed = poolManager.GetObjFromPool;
onAKeyPressed = poolManager.ReturnObjToPool;
void Update()
if (Input.GetKeyDown(KeyCode.Space))
onSpacePressed?.Invoke(new Vector3(0, 0, 0), Quaternion.identity);
//here I get a random active, however this would be called in the specific objects remove circumstances,
//so you should have a reference to that specific gameobje when rerunrning it to the pool.
if (Input.GetKeyDown(KeyCode.A))
GameObject go = poolManager.GetRandomActiveGO();
onAKeyPressed?.Invoke(go);
Editar: patrón Singleton
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T _instance;
public static T instance
get
if (_instance == null)
_instance = GameObject.FindObjectOfType<T>();
if (_instance == null)
_instance = new GameObject(typeof(T).Name).AddComponent<T>();
return _instance;
}
nota: si aun no se resuelve tu pregunta por favor dejar un comentario y pronto lo podremos de nuevo , muchas gracias
por hoy,espero que te funcione