Instantiate, Destroy e Instantiate de nuevo

CrIpI

Sé que no se puede hacer de esta manera, la idea es que estoy haciendo una mazmorra con varias habitaciones y quiero que cuando salga el personaje de una habitación se quede el estado de la habitación exactamente como estaba para cuando vuelva a entrar. Por lo menos la vida de los enemigos.

¿Qué se guarda? El GameObject, transform... La información de todas las habitaciones las dispone un script que no se destruye.

Por ejemplo:

1- Entras en una habitación y realizas Instantiate de los enemigos.
2- Al salir de la habitación actualizas los datos.
3- ?
4- Destruyes los objetos para generar la nueva habitación.
5- Vuelves a entrar en la habitación
6- ?

Gracias.

B

A ver, quieres decir que quieres que las habitaciones y sus elementos se queden tal cual estaban, no?

Es tan fácil como almacenar los datos de las habitaciones en una clase, incluyendo los bichos.

¿Cómo generas las habitaciones actualmente? Lo haría algo así yo:

public class Room
{
	public int width;
	public int height;
	public List<Enemy> Enemies;
}

public class Enemy
{
	public int health;
	public Vector3 lastPosition;
}

Y bueno, es tan simple como cuando salgas de la habitación se almacenen esos datos en la Room, y para cuando vuelvas a entrar los cargas y pim pam.

Si quieres te hago una demo para que veas como funciona!

2 respuestas
CrIpI

#2 No te preocupes. Vamos que como dice en el titulo... Instantiate, Destroy e Instantiate con la información que guardas.

1 respuesta
B

#3 Si no te gusta repetir tanto el proceso de Instantiate/Destroy, puedes evitar el Destroy y simplemente desactivar la sala entera, cuando necesites verla otra vez actualizas la información y vuelves a activar los elementos de esa sala.

Derivación de un pool system ^^

1 respuesta
CrIpI

#4 No se como funciona internamente unity pero creo que eso consumiría demasiado. Son como 40 salas a lo mejor.

1 respuesta
B

#5 Si las desactivas chupa igual que si no estuvieran, básicamente! Además que el hecho de estar instanciando y destruyendo todo el tiempo acumula mucha basura en el motor, las técnicas de pooling están más que recomendadas.

1 respuesta
CrIpI

#6 Pues no tenía ni idea. Pensaba que eso consumiría más. Pues veré a ver que me beneficia más.

VicoViper

No destruyas una habitación a la que vas a volver... no creo que valga la pena... igualmente, yo te recomendaría que si lo vas a hacer, todos los valores de las rooms y los enemigos los almacenases en un script anclado al nivel... y así puedes destruir y reinstanciar sin riesgos.

Creas variable, instancias en ella, modificas y pa'lante.

Pero vamos... que creo que en este caso, lo mejor sería no destruir para luego crear...

#2 Yo suelo ser un poco perro con estas cosas, ahora mismo estoy trabajando en 2D, y me ahorro una variable y le meto la salud a los enemigos en el 3er valor del vector3 :D ...

#9 Son los traumas de la carrera y los ejercicios de ensamblador que eran del estilo: "utiliza el menor número de variables y llamadas a memoria posibles"
Te volvías creativo... No tenías más remedio U_U

2 respuestas
B

#8 xDD Joder, ni que la variable a parte te provocara un infarto por mover los dedos 4 veces más

CrIpI

#8 A mi todo lo contrario. Que cada vez que necesitara una nueva variable, que la declarara por si alguien cogía después mi código que estuviera bien claro.

nOckS

El problema de hacer Destroy continuamente es que genera basura, de modo que hará que el Garbage Collector entre en acción.
Si tiene muchos objetos que necesitas destruir pero tienes que reutilizar, mírate Object Pools. Hay un GitHub con Object Pools ya implementadas para Unity, pero no consigo encontrarlo.
Básicamente lo que haces con esto es instanciar X objetos de golpe, desactivarlos cuando sea oportuno, y reactivarlos cuando sea necesario de nuevo, reusando el espacio de memoria asignado a ese objeto, de manera que es mucho más óptimo.
Recuerda también que es aconsejable crear un Pool por cada tipo de objeto que necesites.

Saludos.

1 respuesta
CrIpI

#11 Por lo que he entendido eso se hace con el status.

1 respuesta
nOckS

#12 A qué te refieres con "status"? Al estado de una habitación en un momento dado?
Pero eso lo guardas en una clase por ejemplo, como te ha dicho Midgard, y en tu script de habitación creas una función SetStatus() donde repoblas el estado guardado al salir de la misma.

Lo de Object Pooling te lo he comentado porque hablas de Instanciar y Destruir continuamente (aunque no sé cada cuanto tiempo en realidad) 40 o más objetos.

1 respuesta
CrIpI

#13 Al status de unity. Creo que es asi gameObject.setStatus(true); y desaparece de la escena y deja de operar, como un estado de suspension hasta que vuelves a activarlo.

1 respuesta
nOckS

#14 Supongo que te refieres al gameobject.SetActive(), porque no encuentro ningún SetStatus() :S

El único problema es que depende de cual sea tu plataforma te puede dar problemas, ya puede generar lag y causar un parón al activar los objetos de nuevo (y más si lo haces con todos de golpe).

En PC es posible que no lo notes mucho, pero en móvil, justo hoy he estado haciendo pruebas, y con un par de objetos no me ha estado dando problemas en la mayoría de los casos, pero sí que había veces que generaba un micro-parón.

1 respuesta
CrIpI

#15 Ese !! xD tengo un lio ya de lenguajes... perdona.

Usuarios habituales