Noticias

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

Como acceder a la variable de una instancia/clon sin que afecte al resto

Iniciado por Auronity, Octubre 01, 2017, 10:12:39 PM

Tema anterior - Siguiente tema
Hola, llevo muy poco en Unity. Estoy creando una aplicación en la que coloco marcadores (instancias) en un mapa a partir del gameObject "Marcador". Hasta ahi todo bien, el problema viene cuando intento programar la selección/deseleccion de los marcadores, es decir, cuando haga click en uno de ellos quiero que su variable "selected" sea TRUE, y que la de los demás marcadores sea FALSE, pero no consigo modificar la variable de la instancia individualmente, sino la del prefab en sí (todos los marcadores). Cuando hago Debug y selecciono un marcador me devuelve un TRUE por cada marcador creado. ¿Como puedo solucionarlo?
 
Gracias, espero que se entienda mi problema

Cita de: Auronity date=1506888759¿Como puedo solucionarlo?
   


SIn codigo... te diria imposible. podria ser varias cosas, una por ej que la variable de interes sea public static.

No pretendo hacerlo sin codigo, solo quiero saber como hago en el script que una variable se cambie solo en una instancia y no en las demás.

Cita de: Auronity date=1506892213No pretendo hacerlo sin codigo, solo quiero saber como hago en el script que una variable se cambie solo en una instancia y no en las demás.
   


"no hacerlo sin codigo"? nada se hace sin codigo... estas subiendo al foro un problema que estas teniendo con una variable, y no mostras el codigo en cuestion, asi es casi imposible saber que lo causa.


int cloneName;
private bool selected;
void Start () {
   cloneName = GetInstanceID ();
   selected = false;
   Debug.Log (cloneName + " " + selected);
if (Input.GetKeyDown (KeyCode.Mouse0)) {
      RaycastHit hit;
      Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
      if (Physics.Raycast (ray,out hit, 1000f) && hit.collider) {
         cloneName = GetInstanceID();
         selected = true;
         Debug.Log (cloneName + " " + selected);

 
vale, no sabia a que te referías, Aqui esta el código.

esta incompleto de todos lados, donde cierra la llave del raycast? hay un y getKeyDwon raycast en start? es asi el codigo?

Fallo mio xD, corrijo
 
 
 

int cloneName;
private bool selected;
void Start () {
   cloneName = GetInstanceID ();
   selected = false;
   Debug.Log (cloneName + " " + selected);
}
.
.
.
void Update () {
if (Input.GetKeyDown (KeyCode.Mouse0)) {
      RaycastHit hit;
      Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
      if (Physics.Raycast (ray,out hit, 1000f) && hit.collider) {
         cloneName = GetInstanceID();
         selected = true;
         Debug.Log (cloneName + " " + selected);
      }
}
}

 
 

He probado lo de this.variable = valor; y no me funciona, lo anterior no lo entiendo, pongo los scripts del objeto que instancia los clones y el del objeto clonado:
 
 
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Marcadores : MonoBehaviour {
public GameObject Marker;
GameObject marcador;
Vector3 centro;
// Use this for initialization
void Start () {
   centro = new Vector3 (transform.localPosition.x, transform.localPosition.y, 500);
}

// Update is called once per frame
void Update () {
   if (Input.GetKeyDown (KeyCode.Mouse1)) {
      marcador = Instantiate (Marker, centro, Quaternion.identity) as GameObject;
   }
}
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GestorMarcadores : MonoBehaviour {
int cloneName;
private bool selected;
// Use this for initialization
void Start () {
   cloneName = GetInstanceID ();
   selected = false;
   Debug.Log (cloneName + " " + selected);
}

// Update is called once per frame
void Update () {
   //Seleccionar
   if (Input.GetKeyDown (KeyCode.Mouse0)) {
      RaycastHit hit;
      Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
      if (Physics.Raycast (ray,out hit, 1000f) && hit.collider) {
         cloneName = GetInstanceID();
         selected = true;
         Debug.Log (cloneName + " " + selected);
      
   //Deseleccionar
      } else if (!Physics.Raycast (ray, out hit, 1000f) || !hit.collider) {
         selected = false;
         Debug.Log (cloneName + " " + selected);
      }
   }
}
}

 
Esto me esta empezando a dar dolor de cabeza xD, haga lo que haga si creo varias instancias y selecciono una, en la consola siempre me debuguean TRUE los dos clones

Gracias por la ayuda, al final, trasteando con el Update y el OnMouseOver he conseguido que solo la instancia que hago click este selected=true y las demas false, seguramente vuelva a preguntar otro problema ya que ahora toca hacer que cuando seleccione una instancia me salga un cuadro para introducir texto donde le editaria la variable 'nombre'.
 
Un saludo

jejeje, yo tube el problema contrario hace tiempo, una vez que queria que me pasase eso que te pasaba a ti..., queria cambiar una variable de todas la instancias que habia de ese objeto.... y no sabia como.... al final lo que hice fue crear una public static Class llamada globalVariables(sin monobehaviour) , y meter ahi todas la variables(todas public static) que quieres que sean "globales"
 
y entonces los objetos en vez de tener cada uno su variable, accedian a la variable "global", ya que esta es accesible/modificable por cualquier otra class/script/object
 
jejeje
 
introducir en nombre nuevo puedes hacerlo facilmente en la funcion OnGUI, tendras que guardar una variable del objeto golpeado por el raycast (hit.collider.gameObject) definida en la class, porejemplo: "private GameObject objectHitted;"
 


..... //en el raycast
objectHitted = hit.collider.gameObject;
...
void OnGUI() {
   string newName = objectHitted.name;
   newName = GUI.TextField(new Rect(10,10,200,40), newName);
   objectHitted.name = newName;
}

 
 
 
ah, si quieres que la "caja" de texto aparezca en la posicion del raton utiliza Input.mousePosition
 
ejemplo:
 

void OnGUI() {
   string newName = objectHitted.name;
   newName = GUI.TextField(new Rect(Input.mousePosition.x, Screen.height - Input.mousePosition.y, 200, 40), newName);
   objectHitted.name = newName;
}

 
nose porque mousePosition devuelve el valor Y invertido con respecto a la pantalla, por eso hago Screen.height - Input.mousePosition.y
 
si alguien es capaz de explicarme porque esto es asi en Unity se lo agradeceria, porque a mi personalmente me parece casi un bug tener que andar trasformando la posicionY del raton porque las funciones GUI funcionan alrreves... y los objetos GUI funcionan con un valor float entre 0 y 1 que representa la pantalla... osea, por un lado tiene sus ventajas pero para mi que al final es mas lio.... porque no es todo igual?
 
yo antes de Unity hacia todo en relacion al width y height de la pantalla, si queria poner un elemento del UI a tres cuartas partes del horizontal de la pantalla, (lo hacia todo via script) lo que hacia era poner como posicion del elemento "screen.width*0.75f"(en un script) y a correr... y el raton me dava la posicion Y correcta.... 
 
no me estoy quejando de Unity, jeje, me parece buen "material" :) facil e intuitivo, bastante potente, te ahorra mucho tiempo en muchas tareas.... y eso de poder modificar script en tiempo de ejcucion.. sin tener que volver a compilar.... casi me da un orgasmo la primera vez que lo descubri... (antes habia programado con spectrum(el de casettes (basic)), darkBasik(mas basic) y tambien con blueJ (java))
 
....ay! tenia que haberte conocido antes motor grafico de mis amores....

Cita de: Igor date=1507037652nose porque mousePosition devuelve el valor Y invertido con respecto a la pantalla, por eso hago Screen.height - Input.mousePosition.y
   


Porque en OnGUI en general (para custom inspectors y ventanas tambien) tenes que usar Event.current.mousePosition:
 
https://docs.unity3d.com/ScriptReference/Event-mousePosition.html
 
El input.mousePosition "funciona mejor" para el gameplay ,pero si era un tipico problema de toda la vida, el y invertido.
 
 


Etiquetas: