Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Cambiar variable "global"

Iniciado por juanma_teso, Octubre 24, 2015, 05:47:21 PM

Tema anterior - Siguiente tema
Hola a todos! Resulta que tengo un bool "In***ctivo" que me desactiva y activa el input del juego, otro bool "EditarCamara" que activa y desactiva el input para mover y girar la cámara, como el input (getAxis por ahora) son el mismo para los dos, cuando uno está true el otro será false (lógico ) hasta ahora para hacer las pruebas "In***ctivo" empezaba true y el otro false, luego los cambiaba localmente, la cuestión es, tiene que haber una forma más limpia para hacer esto, estaba dudando en usar mensajes o delegados pero ambos se escaparon a mi educación :'( junto a una clase gestor que cada vez que cambiara un bool mandara a cada clase que tenga uno de estos booleanos la actualización, así que estoy leyendo y dudando porque la manera que yo lo sé hacer es tener todas las instancias en el gestor y cambiar una a una... Gracias!!

Usar eventos seria tu solución, o bien no entendí nada... 

entiendo los de cambiar las variables pero lo demas no lo entiendo
a lo que mas o menos entiendo es que tienes esas 2 variables que estan en varios objetos y quieres que esas variables en todos los objetos cambien al hacer un cambio en una, almenos eso es lo que entiendo, si es asi tendrias que declarar las variables como static

Pero, pero. Pues una clase común para todos. Te creas una clase que herede de mono y luego heredas de esa para todos los que traten con esas variables.

Octubre 24, 2015, 08:16:37 PM #4 Ultima modificación: Octubre 24, 2015, 08:16:58 PM por juanma_teso
Gracias por responder!! Es exactamente lo que ha dicho http://unityspain.com/profile/27425-oaken3d/?do=hovercard" data-mentionid="27425" href="<___base_url___>/profile/27425-oaken3d/">@Oaken3d, tengo dos booleanos(de momento) en objetos diferentes (3 de momento), lo que me gustaría hacer y no tengo muy claro es cómo, al cambiar en uno de estos objetos un booleano se cambiarán en el resto. Especifico un poco más:Tengo un botón que activa la edición de la cámara y desactiva el movimiento (activado = true, desactivado = false)Tengo el script del movimiento y rotación de la cámara (true = editable, false = no se puede editar)y tengo el script del movimiento del jugador (true = input activo, false = estate quieto jaja)Con estas variables queda así: editable = activado y in***ctivo != activado.Sé que podría hacer referencias y cambiar directamente cuando pulse el botón, o podría estar cogiendo el valor del botón cada frame (mala idea jajaj), pero intento hacer algo del estilo:
void PulsacionBoton ()
{
    botonActivo != botonActivo;
    gestor.CambiarBool();
}
Y no es que sea un capricho (o eso creo), me parece la forma correcta de hacerlo, porque no me gustaría hacer 100 referencias (exagerando) a objetos si por ejemplo tengo un menú en el que también tengo que desactivar el in***ctivo o tengo en otro objeto  algún bool que debe ser opuesto al in***ctivo. Que creo que así será.Gracias http://unityspain.com/profile/18127-francoe1/?do=hovercard" data-mentionid="18127" href="<___base_url___>/profile/18127-francoe1/">@francoe1, buscaré info sobre eventos, hasta ahora sólo los había usado en animaciones :/Gracias http://unityspain.com/profile/27231-irobb/?do=hovercard" data-mentionid="27231" href="<___base_url___>/profile/27231-irobb/">@iRobb, pero no creo que tenga que usar herencia, los objetos no tienen nada que ver el uno con el otro, lo único en común aparte del bool es que tienen transform jajaj

Lo único que se me ocurre parecido a lo que digo es tener una función en cada objeto que tenga un bool con esta necesidad de ser opuesta al in***ctivo o a otro bool
void CambiarBool ()
{
    myBool = !myBool;
}
entonces cuando la función X sea ejecutada, cambie el bool de su propia clase y después llame al gestor para que éste cambie el bool de los objetos que tenga que cambiar, pero aún así tendría que estar haciendo una referencia a todos los objetos.Otra opción que estoy mirando ahora es ésta pero no me queda del todo claro 

Octubre 24, 2015, 11:52:24 PM #6 Ultima modificación: Octubre 24, 2015, 11:52:57 PM por Oaken3d
como te dije, declara la variable como static, me imagino que esos 3 objetos usan el mismo script, si es asi solo declara esas variables static
public static bool botonActivo;
o cual sea la variable que nesecites

No, los 3 son scripts diferentes, no tienen nada que ver, sólo tienen en común el booleano.

bueno suena sencillo entonces, por que no haces las variables publicas que quieres y solo pasas el valor de esas variables a las que quieres en los scripts, o tambien igual hacer variables staticas y tambien tomar el valor de esas variables y pasarlas a la de los scripts

Necesitas hacerlo con Eventos...Por Ejemplo al Apretar "P" se llama al evento Edición, luego compruebas en cada script o componente las llamadas del evento.Practica, en nuestro Script o Componente "Manager" hacemos lo siguiente1 -Creamos el delegado de tipo void.
public delegate void CambiarModo();

2 -Luego creamos una instancia de ese delegado para nuestro evento
 
public static event CambiarModo ChangeMode;
3 -Luego tendríamos que comprobar cuando es llamado este evento. Dijimos al apretar "P"
 
if(Input.KeyDown(GetKeyCode.P))if(ChangeMode != null)ChangeMode();
4 -Ya tenemos el evento creado, ahora necesitamos saber cuando es este llamado desde nuestra Camara y Desde el Jugador.!Importante¡ Hacer lo siguiente solo en nuestra función Start , Awake o cualquier otra que solo se llame una vez.
comprobamos cuando se llama el evento ChangeMode en nuestro Script "Manager" y luego llamamos una función Lambda que nos va a cambiar el valor de nuestra variable IsEditable
Manager.ChangeMode += ()=> {IsEditable = !IsEditable;};
 Te dejo el Código de este ejemplo para que lo analices
public class Manager : MonoBehaviour
{
public delegate void Event_ChangeMode();
public static event Event_ChangeMode ChangeMode;

void Update()
{
   if(Input.GetKeyDown(KeyCode.P))if(ChangeMode != null)ChangeMode();
}
}

public class Player : MonoBehaviour
{
public bool IsEditable = false;

void Start()
{
   Manager.ChangeMode += () => {IsEditable = !IsEditable;};
}
}

public class Camara : MonoBehaviour
{
public bool IsEditable = false;

void Start()
{
   Manager.ChangeMode += () => {IsEditable = !IsEditable;};
}
}

public class Otro : MonoBehaviour
{
public bool IsEditable = false;

void Start()
{
   Manager.ChangeMode += () => {IsEditable = !IsEditable;};
}
}

Te invito a pasar por mi Canal de Youtube donde podes encontrar varios cursos sobre Unity3D y programacion.

Muchas gracias @francoe1! Me parece un buen tuto, habían cosas que no me quedaban claras pero yo creo que esa es la idea fundamental...@Oaken3d es la idea inicial, pero quería evitarme hacer todas las instancias porque al final iba a terminar llamando a 30 objetos diferentes y sería un lío jajaDe momento lo tengo hecho con instancias pues sólo tengo 4 objetos que dependan entre sí, tengo que echarle algo de cabeza y hacer un par de algoritmos para ver como cuadro todo... Gracias a los 3!! 

Etiquetas: