Noticias

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

Prolemas con script de puerta y llave

Iniciado por Miguel Torrealba, Septiembre 02, 2015, 07:09:48 AM

Tema anterior - Siguiente tema
He estado creando en estos dias un script para una puerta y una llave, pero tengo un problema que el script no reconoce cual es la llave correcta , asi que cuando agarro una llave se habren todas y no identifica cual es cual, son 2 script uno de la llave y otro de la puerta. Codigo LLave
using UnityEngine;
using System.Collections;public class LlavesScript : MonoBehaviour {    public AudioClip SonidoRecogerLlave;
        // Use this for initialization
    void Start () {    }
    
    // Update is called once per frame
    void OnTriggerStay (Collider other) {        if (other.tag == "Player") 
        {
                Debug.Log("Click para recoger");
                {
                        if (Input.GetMouseButton(0))
                        {
                            NotificationCenter.DefaultCenter().PostNotification(this,"llaveRecogida");
                            AudioSource.PlayClipAtPoint(SonidoRecogerLlave,transform.position);
                            Debug.Log ("Tienes la llave");
                        }
                }
        }
    }
} Codigo puertausing UnityEngine;
using System.Collections;public class PuertaScript : MonoBehaviour {    private float AngleY = 90.0f;    
    
    private float targetValue = 0.0f;
    private float currentValue = 0.0f;
    private float easing = 0.05f;    public bool Abierta = false;
    public bool tieneLlave = false;    public AudioClip sonidoPuertaCerrada;
    public AudioClip sonidoPuertaAbierta;    public GameObject Target;  //bisagra    public GameObject llave;
    public string nombre;    void Start ()
    {
        NotificationCenter.DefaultCenter().AddObserver(this,"llaveRecogida");
    }
    
    void  Update (){
        
        
        currentValue = currentValue + (targetValue - currentValue) * easing;
        Target.transform.rotation = Quaternion.identity; // set rotation to zero
        Target.transform.Rotate(0, currentValue, 0); // apply full Rotation        if (Input.GetMouseButton (0)) {
                        Debug.Log ("click");
                }
    
        if (targetValue == AngleY && currentValue == 0) {tieneLlave =false;}
        
    }    void OnTriggerStay (Collider other){
    
                        if (Abierta == false) {
                                if (other.gameObject.tag == "Player" && tieneLlave) {
                                        if (Input.GetMouseButtonDown (0)) {
                                                targetValue = AngleY;
                                                currentValue = 0;
                                                Abierta = true;
                                                audio.clip = sonidoPuertaAbierta;
                                                audio.loop = false;
                                                audio.Play (); 
                                
                                        }
                                }                        }
                
       if (other.gameObject.tag == "Player" && !tieneLlave) {
            if (Input.GetMouseButtonDown(0)){
                        Debug.Log ("ESTA CERRADO");
                        audio.clip = sonidoPuertaCerrada;
                        audio.loop = false;
                        audio.Play ();     
                }            if (Abierta){
                targetValue = 0;
                currentValue = 0;
                }
        }        }    void llaveRecogida (Notification notificacion){
    
                if (llave.name == "Llave1") {
                        tieneLlave = true;
        }  
        }
}   ya intente todo lo que se Ayuda por favor!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

En principio ese script solo te debería funcionar con una llave, la que tenga nombre "LLave1".

Septiembre 02, 2015, 02:04:22 PM #2 Ultima modificación: Enero 01, 1970, 01:00:00 AM por Antonio
Este script abre la puerta si el jugador tiene el objeto "Llave1", si usas este mismo script en varias puertas, pues todas se deberían abrir si el jugador tiene ese objeto "Llave1". Lo que tienes que hacer es quitar esa constante, y poner una variable.

- Arriba entre las variables, crea una variable de tipo string. (Acuérdate de ponerle el public delante para que puedas cambiarla en el inspector).
- Abajo, en la función "llaveRecogida", quitá el "Llave1" y pone en su lugar el nombre de la variable que has creado.
- En el inspector de unity, selecciona la puerta y en el campo de esa variable que has creado, pones el nombre del objeto que necesite, Llave1, Llave2, Orbe Mágico, etc...

En cada puerta tendrás que escribirle ese campo en el inspector, pero si cada puerta usa una llave diferente, pues en algún momento tendrías que decirle qué llave es.

clone la puerta con su respectiva llave, Ya estableci la variable de string pero ahora el problema es que cuando clickeo una llave se desaparecen las dos y se abren las dos puertas y estableci diferentes nombres a cada una de las puertas a la variable en el inspector . Para que entiendas mejor como funciona el script es asi :La llave tiene un script asignado que es de notificationCenter que sirve para dar una  notificacion a una funcion en otro script , entonces cuando el jugador colisiona con la llave y hace click eso manda una notificacion a una funcion que es la que esta en la puerta , que hace que active un booleano que dice que si tiene la llave .Y en la puerta tengo un target que la bisagra y ese target lo hago hijo de la puerta (la mesh) y tengo un activador que es el activa la puerta para que ejecute la accion de abrir la puerta cuando el jugador colisione con el y haga click . Entonces el script lo que hace o lo que deberia hacer es , cuando el jugador colisione con la puerta y haga click y si tiene la llave la habra . (todo el script puerta esta asignado al activador). ahora el problema es : Que cuando hago click en una llave desaparecen las dos y se habren las dos y que si hago click en una se habren todas Codigo Llaveusing UnityEngine;
using System.Collections;
public class LlavesScript : MonoBehaviour {    public AudioClip SonidoRecogerLlave;
    
    // Use this for initialization
    void Start () {
    }
    
    // Update is called once per frame
    void OnTriggerStay (Collider other) {
        if (other.tag == "Player") 
        {
                Debug.Log("Click para recoger");
                {
                        if (Input.GetMouseButton(0))
                        {
                            NotificationCenter.DefaultCenter().PostNotification(this,"llaveRecogida");
                            AudioSource.PlayClipAtPoint(SonidoRecogerLlave,transform.position);
                            Debug.Log ("Tienes la llave");
                        }
                }
        }
    }
}
Puertausing UnityEngine;
using System.Collections;
public class PuertaScript : MonoBehaviour {    private float AngleY = 90.0f;    //angulo de rotacion cuando la puerta se abre
    
    private float targetValue = 0.0f;
    private float currentValue = 0.0f;
    private float easing = 0.05f;
    public bool Abierta = false;
    public bool tieneLlave = false;
    public AudioClip sonidoPuertaCerrada;
    public AudioClip sonidoPuertaAbierta;
    public GameObject Target; // bisagra    public GameObject llave;
    public string nombre;
    void Start ()
    {
        NotificationCenter.DefaultCenter().AddObserver(this,"llaveRecogida");
    }
    
    void  Update (){
        
        
        currentValue = currentValue + (targetValue - currentValue) * easing;
        Target.transform.rotation = Quaternion.identity; // set rotation to zero
        Target.transform.Rotate(0, currentValue, 0); // apply full Rotation
        if (Input.GetMouseButton (0)) {
                        Debug.Log ("click");
                }
    
        if (targetValue == AngleY && currentValue == 0) {tieneLlave =false;}
        
    }
    void OnTriggerStay (Collider other){
    
                        
                        if (Abierta == false) {
                                if (other.gameObject.tag == "Player" && tieneLlave) {
                                        if (Input.GetMouseButtonDown (0)) {
                                                targetValue = AngleY;
                                                currentValue = 0;
                                                Abierta = true;
                                                audio.clip = sonidoPuertaAbierta;
                                                audio.loop = false;
                                                audio.Play (); 
                                
                                        }
                                }
                                        
                        if (other.gameObject.tag == "Player" && !tieneLlave) {
                                if (Input.GetMouseButtonDown (0)) {
                                        Debug.Log ("ESTA CERRADO");
                                        audio.clip = sonidoPuertaCerrada;
                                        audio.loop = false;
                                        audio.Play ();     
                                }
                                if (Abierta) {
                                        targetValue = 0;
                                        currentValue = 0;
                                }
                        }
                }
        }
    void llaveRecogida (Notification notificacion){
    
            if (llave.name == nombre)
        {
                        
                    tieneLlave = true;
                        llave.SetActive(false);
        }
        }
}
 lo he retocado un poco pero es asi como quedo , Gracias por responder y espero que me ayudes porque ya intente todo y no se como hacer para que la puerta idetifique su llave.Existe otro metodo para que el script reconozca cual gameobjet Tiene ??? y si lo clono es igual ??? .  

Septiembre 03, 2015, 03:53:04 AM #4 Ultima modificación: Septiembre 03, 2015, 04:01:42 AM por Antonio
Desde aquí no lo voy a poder saber. En el trigger de la llave no veo error, efectivamente cuando se pulse el botón del ratón debería activarse la función de recoger la llave, en tu caso estás usando ese Notification Center que yo no conozco. Parece que lo usas para activar la función "llave Recogida", si el problema es que esta función se está activando en múltiples objetos, mis sospechas caen primeramente en ese "Notification Center". ¿Estás seguro de que está preparado para activar la función de sólo 1 objeto?

En fin, alternativas a ese script, creo que podría ser un SendMessage.

 
//Código de la Llave

using UnityEngine;
using System.Collections;

public class LlavesScript : MonoBehaviour
{
    public GameObject Puerta;
    public AudioClip SonidoRecogerLlave;
   
    void OnTriggerEnter (Collider other)
    {
        if (other.tag == "Player") 
            Debug.Log("Click para recoger");
    }  

    void OnTriggerStay (Collider other)
    {
        if ((other.tag == "Player") && (Input.GetMouseButton(0)))
        {
            Puerta.SendMessage ("llaveRecogida");
            AudioSource.PlayClipAtPoint(SonidoRecogerLlave,transform.position);
            Debug.Log ("Tienes la llave");
            Detroy (gameObject);
        }
    }
}
 
//Script de la puerta

using UnityEngine;
using System.Collections;

public class PuertaScript : MonoBehaviour
{
    private Vector3 targetDir;
    private float easing = 0.05f;

    bool Abriendose = false;
    bool tieneLlave = false;

    public AudioClip sonidoPuertaCerrada;
    public AudioClip sonidoPuertaAbierta;

    public GameObject Target; // bisagra

    void  Update ()
    {
        if (Abriendose)
        {
            float velocidad = easing * Time.deltaTime;
            //Si no multiplicas por el deltaTime, la velocidad no será similar en los distintos ordenadores.
            Target.tranform.forward = Vector3.RotateTowards(Target.transform.forward, targetDir, velocidad, 0.0F);
           
            float angle = Vector3.Angle (targetDir, Target.transform.forward);
            if (angle < 0.01f)
            {
                Abriendose = false;
            }
        }
       
    }

    void OnTriggerStay (Collider other)
    {
        if ((other.gameObject.tag == "Player") && (Input.GetMouseButtonDown (0)))
        {
            Debug.Log ("click");
           
            if (tieneLlave)
            {
                targetDir = Target.tranform.right;
                Abriendose = true;
                tieneLlave = false;
               
                audio.clip = sonidoPuertaAbierta;
                audio.loop = false;
                audio.Play ();
            }else{
                Debug.Log ("ESTA CERRADO");
               
                audio.clip = sonidoPuertaCerrada;
                audio.loop = false;
                audio.Play ();
            }
        }
    }

    void llaveRecogida ()
    {
        tieneLlave = true;
    }
}

En este caso, sin el notifiaction center, verás que el script de la llave tiene un dato extra, en él tienes que poner el objeto de la puerta a la que se corresponde esa llave. Al cogerla, le mandará un SendMesage ordenandole que se active la función llaveRecogida, lo que hará que cuando el jugador llegue a la puerta, esta actúe en consecuencia.

También he añadido algunos cambios al código de la puerta, aunque aun no la he probado, pero la cosa es que eso de ir calculando una rotación, poner la rotación a 0 y volverla a rotar, me parecía demasiado lio, además de que la condición para decidir cuando la puerta esta abierta, también la vi algo conflictiva.

Septiembre 03, 2015, 07:27:41 PM #5 Ultima modificación: Septiembre 03, 2015, 07:31:06 PM por Miguel Torrealba
Si esta bien pero ahora la consola me envia un error de que la funcion llave recogida no ha recibido el mensaje del script de la llave  y no abre la puerta, Después de leer foros vi que es algo sobre el emparentamiento de objetos porque no recibe el mensaje . Para que tengas una idea de como emparento mis objetos , aqui te los dejo .0.Puerta  (Objeto vacio)         1.Activador   (Script Puerta)         1.Bisagra                    2.Puerta Malla         1.llave   (Script llave)                   2.Cilidro                    2.Cubo Hay esta el orden del objeto de la puerta con su respectiva llave , Los tengo ordenados así para no confundirme , pero si necesario cambiar el orden lo haré . Si quieres ver el mensaje de consola aquí te lo dejo...Mensaje de consolaSendMessage llaveRecogida has no receiver!
UnityEngine.GameObject:SendMessage(String)
LlavesScript:OnTriggerStay(Collider) (at Assets/LlavesScript.cs:22)
 P.D-El script funciona perfecto excepto lo del mensaje , cuando hago click reproduce el sonido y todo dela puerta cerrada , buen trabajo espero que ayudes .. Gracias por responder    

[quote author=Miguel Torrealba" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="20599" data-ipsquote-contentcommentid="107302 date=1441301261]Si esta bien pero ahora la consola me envia un error de que la funcion llave recogida no ha recibido el mensaje del script de la llave  y no abre la puerta, Después de leer foros vi que es algo sobre el emparentamiento de objetos porque no recibe el mensaje . Para que tengas una idea de como emparento mis objetos , aqui te los dejo .0.Puerta  (Objeto vacio)         1.Activador   (Script Puerta)         1.Bisagra                    2.Puerta Malla         1.llave   (Script llave)                   2.Cilidro                    2.Cubo Hay esta el orden del objeto de la puerta con su respectiva llave , Los tengo ordenados así para no confundirme , pero si necesario cambiar el orden lo haré . Si quieres ver el mensaje de consola aquí te lo dejo...Mensaje de consolaSendMessage llaveRecogida has no receiver!
UnityEngine.GameObject:SendMessage(String)
LlavesScript:OnTriggerStay(Collider) (at Assets/LlavesScript.cs:22)
 P.D-El script funciona perfecto excepto lo del mensaje , cuando hago click reproduce el sonido y todo dela puerta cerrada , buen trabajo espero que ayudes .. Gracias por responder    [/quote]es simple, el mensaje esta indicando que estas enviando un mensaje a un método que no existe en el GameObject receptor. Ese método seguramente unity lo busco en todas las clases asignadas a ese objeto. El error esta en la línea 22 del script LLlaveScript.cs (que es el emisor).En el parámetro tipo string pasale un nombre de un método válido para ese objeto receptor o no envies el mensaje.
También esta la posibilidad de que el nombre este bien pero el receptor no posea asignado el script con una clase que contenga ese método,  por lo cual solo se debería asignar el script tal vez faltante en el gameobject receptor.

Bye Bye



Septiembre 04, 2015, 12:16:24 AM #7 Ultima modificación: Enero 01, 1970, 01:00:00 AM por Antonio
Mirando el script que puse de la llave, vemos que la instrucción del SendMessage es: 
Puerta.SendMessage ("llaveRecogida");
Esta lo que hace es decirle al objeto Puerta que active la función llaveRecogida, si no la encuentra, es porque el objeto "Puerta" no tiene ningún script con una función "llaveRecogida" (puede ser porque no tenga el script, o porque el nombre sea diferente).

Asegúrate que en la variable Puerta, estás poniendo el objeto de la puerta que tiene el script con la función. Según tu esquema, entiendo que sería el objeto "Activador".

Etiquetas: