Noticias

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

Ayuda juego para terminar facultad! scrip de golpe en juego de lucha

Iniciado por Joako, Agosto 19, 2015, 04:54:11 PM

Tema anterior - Siguiente tema
Agosto 19, 2015, 04:54:11 PM Ultima modificación: Agosto 19, 2015, 04:57:05 PM por Joako
Buenas, la cosa es asi, me queda una sola materia en la facultad para recibirme y esa materia llamada multimedia para aprobar necesito entregar un juego echo por mi mismo en unity, vengo bastante bien ya tengo el mapa el personaje y todo pero no me marca bien los golpes. Obviamente en la facultad no exigen un super juego pero la idea es mas o menos asi: Son dos artistas marciales que si gopean en la cara quiero que sume 3 puntos y si golpea en el torso quiero que sume 1 punto, de programacion se bastante pero no conosco las funciones de unity a la perfeccion y me he trabado, es obvio que mis scrips estan mal ya que no funciona como deberia jajaja pero aqui los dejo para que los vean, y diganme como lo harian ustedes. Desde ya muchas gracias. Controlpublic var velocidad = 10.0F;
public var velocidadA = 10.0F;
public var rotacion = 100.0F;
private var anim : Animator;
private var col : CapsuleCollider;
public var ataque : Ataque;
public static var puntos : int = 0;
function Start () {
    
        // initialising reference variables
        anim = GetComponent("Animator");                      
        col = GetComponent("CapsuleCollider");    
         
}function FixedUpdate () {
       
        //movimiento con rotacion
        transform.Translate( 0, 0, Input.GetAxis("Vertical") * velocidad * Time.deltaTime);
        transform.Rotate(0, Input.GetAxis("Horizontal") * rotacion * Time.deltaTime, 0);        //movimiento sin rotacion
        //transform.Translate( 0, 0, Input.GetAxis("Vertical") * velocidad * Time.deltaTime);
        //transform.Translate(Input.GetAxis("Horizontal") * velocidad * Time.deltaTime, 0, 0);        if(Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.A)){
            anim.Play("CaminarI");
            //mover();
        }else if(Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D)){
            anim.Play("CaminarD");
            //mover();
        }else if(Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A)){
            anim.Play("CaminarI");
            //mover();
        }else if(Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.D)){
            anim.Play("CaminarD");
            //mover();
        }else if(Input.GetKey(KeyCode.W)){
            anim.Play("Caminar");
            //mover();
        }else if(Input.GetKey(KeyCode.S)){
            anim.Play("CaminarA");
            //mover();
        }else if(Input.GetKey(KeyCode.A)){
            anim.Play("CaminarI");
            //mover();
        }else if(Input.GetKey(KeyCode.D)){
            anim.Play("CaminarD");
            //mover();
        }        if(Input.GetKeyDown(KeyCode.Keypad4)){
            anim.Play("GolpeIzqAlto");
            ataque.ataque("alto");
        }
        if(Input.GetKeyDown(KeyCode.Keypad5)){
            anim.Play("GolpeDerAlto");
            ataque.ataque("alto");
        }
        if(Input.GetKeyDown(KeyCode.Keypad1)){
            anim.Play("GolpeIzqBajo");
            ataque.ataque("bajo");
        }
        if(Input.GetKeyDown(KeyCode.Keypad2)){
            anim.Play("GolpeDerBajo");
            ataque.ataque("bajo");
        }
        if(Input.GetKeyDown(KeyCode.Keypad6)){
            anim.Play("GolpeLargo");
            ataque.ataque("alto");
        }
        if(Input.GetKeyDown(KeyCode.Keypad3)){
            anim.Play("Patada");
            ataque.ataque("bajo");
        }        if(Input.GetKey(KeyCode.Keypad7)){
            anim.SetBool("Guardia", true);
            anim.Play("GuardiaAlta");
        }else if(Input.GetKey(KeyCode.Keypad8)){
            anim.SetBool("Guardia", true);
            anim.Play("GuardiaBaja");
        }else{
            anim.SetBool("Guardia", false);
        }        if(Input.GetKeyDown(KeyCode.O)){
            anim.Play("Victoria");
        }
        if(Input.GetKeyDown(KeyCode.P)){
            anim.Play("Derrota");
        }
        
}este scrip controla al personaje ya se que tiene muchos errores pero primero quiero que anden bien los golpes para pulirlo. Ataquepublic var control : Control;
public var colision : Colision;function Start () {
    
}function Update () {}function ataque(Tipo : String){
    
    if(Tipo=="alto" && colision.bool){
        control.puntos = control.puntos + 3;
    }else if(Tipo=="bajo" && colision.bool){
        control.puntos = control.puntos + 1;
    }
}este solo tiene la funcion ataque Colision public var desplazamiento : float = -0.4;
public var control : Control;
var bool = false;//var golpeIzqAlto : int = Animator.StringToHash("Base Layer.GolpeIzqAlto");
//var anim : Animator;
//var estado : AnimatorStateInfo;function Start () {
    }function Update () {
    
    
    
}
function OnTriggerEnter(Enemigo : Collider){    if(Enemigo.gameObject.name=="Personaje 1"){
        bool = true;
        Debug.Log("Hit =" +control.puntos);
    }
    
}function OnTriggerStay(Enemigo : Collider){    if(Enemigo.gameObject.name=="Personaje 1"){
        bool = true;
        Enemigo.transform.Translate(0,0, desplazamiento);
        Debug.Log("Hit =" +control.puntos);
    }
    
}function OnTriggerExit(Enemigo : Collider){    if(Enemigo.gameObject.name=="Personaje 1"){
        bool = false;
        Debug.Log("Hit =" +control.puntos);
    }
    
} Este es lo que controla las colisiones que seguramente pienso que aca debe estar el error.El personaje tiene objetos en las manos obviamentes invisibles y con el trigger activado que es lo que colisiona contra el otro personaje y dispara la funcion. La cuetsion es que no marca siempre el golpe, solo sale a veces y no siempre que coliciona sumando realmente cuando le da la gana, no se muy buen el comportamiento de esas funciones creo que deberia funcionar pero no lo hace, diganme como lo harian ustedes o que le coregirian a esto que hice rapido y desprolijamente jajaja. Muchas gracais y disculpen als molestias. 

De entrada quitaria el OnTriggerStay y el OnTriggerExit. Dejaria el translate en el OnTriggerEnter.Y entiendo que tienen colliders, marcados trigger, etc.

Bien, hice lo que me dijiste y sigue funcionando mal, una vez que colisiona pone al bool en true y nunca vuelve a false. Deberia resolverlo de algun otro metodo, alguna idea? y gracias por la respuesta

Agosto 21, 2015, 12:32:58 AM #3 Ultima modificación: Agosto 21, 2015, 12:33:47 AM por Antonio
Si no entendí mal tu código, cuando pulsas la tecla correspondiente, se activa la animación y se activa también la función Ataque, si en ese momento en el que pulsó la tecla, y resulta que el collider de ese ataque está tocando al enemigo, pues se suma los puntos. Esto dará el problema de que si al pulsar la tecla, el collider no está tocando al enemigo, pues no se contará el ataque. Que de hecho, lo raro es que lo cuente.Resulta que estás mandando la instrucción de ataque al principio, cuando todavía no ha aplicado la animación (por ejemplo, si es un puñetazo, has hecho la comprobación al principio cuando todavía no ha preparado el brazo para estirarlo y pegarle al contrincante). A veces te puede funcionar, si por otra animación o por la posición en la que está, el personaje resulta que tiene ese collider ya tocando al enemigo en el momento en que pulsas la tecla de ese ataque, pues entonces sí contará.Observa también que en las teclas, has usado Input.GetKeyDown, eso quiere decir que sólo mirará esa función en el ciclo en que la tecla de no estar pulsada, pasa a estarlo, en tu script, usas los onTriggers para manejar la variable bool durante el proceso, pero de poco sirve si sólo vas a mirar 1 frame.

En general, creo que deberías planear otro enfoque. Por ejemplo.

- Al pulsar la tecla de ataque, sólo se activa la animación, no se activa ninguna función ahí.
- En el código ataque, crea 1 variable tipo objeto, que sea la del collider, (nombre ¿"esferaCollider"?) (puedes ponerlos todos en un array seguramente), y crea también 2 funciones, una que active el gameObject elegido ( esferaCollider.SetActive (true); )  y otra función que lo desactive. ( esferaCollider.SetActive (false); ). Pon también que las esferas se desactiven en la función Start, para que no tengas que ir desactivándolas manualmente.
- En el inspector, vete a la animación del ataque que corresponda, si eliges el objeto, la 3º pestaña es la de las animaciones, y abajo, podrás ver un apartado que te permite ponerle los eventos. Pon la animación en el momento en que el personaje va a empezar a dar el golpe, y ahí, crea un evento para activar la función de aparecer del collider. (Simplemente, pon el nombre de la función), y también, avanza la animación hasta que el personaje haya terminado el golpe, y ahí, crea otro evento que llame a la función desactivación del collider). Con esto, si pones el renderer para poder ver los colliders un momento, deberías poder ver como estos objetos aparecen en el momento de dar el golpe y desaparecen al terminarlo. Pero no hemos acabado.
- Dentro de la esfera, deberá tener otro script con los on triggers como has hecho, en este caso, al igual que dice iRobb, yo aconsejaría usar sólo 1 en este caso, la OnTriggerEnter, que mire, si ha entrado con otro collider, y ese otro collider es el enemigo, entonces, es cuando se da el aviso a la función de ataque y se le dice que sume los puntos. (¿ves la diferencia?, tu estás desde el jugador, activando la función para intentar ver el momento en que ha colisionado, yo digo de que hagas la acción y mandes la función cuando colisione, siendo este el disparador del evento, y no el pulsar la tecla). Para activar la función, bueno, puedes usar el SendMessage ("ataque"); sobre el objeto padre, o puedes usar los GetComponent para llegar hasta ella, en fin, nada nuevo.  Pero falta una cosa más, ahora que ya hemos contabilizado ese ataque, creo que lo suyo sería desactivar la esfera collider, vaya a ser que por lo que sea, salga y vuelva a entrar en el collider enemigo, contabilizando el ataque otra vez. Sabemos que la esfera se quitará sola cuando acabe la animación, pero yo creo que no estaría mal llamar a la función de desactivación también en el caso de que haya golpeado. 

Así, de esa manera, no necesitarías la variable bool para mirar si está dentro o no, y también te aseguras de que la puntación sólo se cuenta si llega el golpe.

 

Agosto 21, 2015, 01:21:58 AM #4 Ultima modificación: Agosto 21, 2015, 01:46:17 AM por Joako
entiendo mas o menos lo que dices, igual a futuro pensaba sacar la funcion de ahi, habia echo todo rapido para una vez que funcione pulirlo pero veo que eso tambien me jugo en contra jajaja intentare plasmar a codigo todo lo que me has dicho, muchas gracias!Adngel eres un genio!!No sabia que podia poner eventos en las animacions. Una pregunta más, como diferenciarias un golpe bajo de uno alto?? ya que siempre me esta sumando lo mismo ahora y la idea es que sume mas puntos cuando impacta un golpe alto, pero si se complica mucho lo dejo asi ya que con esto puedo aprobar tranquilamente jajaja ahora tambien intentare hacer el tema de la guardia con la misma idea que active un objeto cuando se esta cubriendo. Y muchisimas gracias por la ayuda!!

Agosto 21, 2015, 02:29:16 AM #5 Ultima modificación: Enero 01, 1970, 01:00:00 AM por Antonio
Bueno, se me ocurren varias maneras.

La 1º idea puede que sea más simple, al lanzar el ataque y mandar la función  Atacar, compara la altura del collider respecto al suelo, (con el collider puedes acceder al transform del objeto, y con él, a la posición), y no sé... si la altura Y es mayor que 1, ¿que sea ataque alto, si no, ataque bajo?.
La 2º idea que se me ocurre, es colocar colliders más pequeños al enemigo que tomen más o menos su silueta y ponerlos a ellos como los colliders receptores de daño.  (En el OnTriggerEnter, en vez de mirar si es (Enemigo.gameObject.name == Personaje1), pues mirar por ejemplo el layer, (Enemigo.gameObject.layer == 12), los layers puedes configurarlos eligiendo el objeto y escogiendo la pestaña que hay encima del inspector.https://yadi.sk/i/BhkeDI6EiZqwC" rel="external nofollow">https://yadi.sk/i/BhkeDI6EiZqwC (este enemigo tiene un Ragdoll aplicado, y cada pieza, tiene su propio script para recibir daño).Luego, si el collider entra en el layer, no mandar sólo la función Atacar, si no que mira primero en ese enemigo que ha cogido, su script de "pieza", este script tendrá una variable que será la que diga si es una pieza de golpe alto o bajo. Luego, lees el dato, y continuas con la otra función, este método es más engorroso, pero viene bien si necesitas algo más de precisión en las colisiones del personaje.  (Recuerda configurar en Edit -> Project Setting -> Physics las capas de colisiones, para que los colliders del enemigo, no se choquen entre sí).
  

Claro yo le intente hacer un ragdoll pero en la facultad me exigen diseñar yo el personaje desde cero usando 3dmax y poniendole esqueleto del mismo programa e importar eso a unity, al aplicarle el ragdoll se me rompia la textura y hasta se movia medio loco, no se si sera por el esqueleto de 3Dmax, vere cual es la opcion mas sencilla, ahora me concentrare en la guardia, muchas gracias y disculpa las molestias, despues te subo un video para que veas como queda

Etiquetas: