Noticias

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

Torreta que gira mal

Iniciado por ramunda, Julio 28, 2015, 05:56:29 PM

Tema anterior - Siguiente tema
Hola muy buenas ya estoy de nuevo por aqui :),Sere breve Tengo una torreta muy molona la cual me dispara si estoy en el rango que quiero con este script que le puse:(lo dejo por si a alguien mas le sirve)
using UnityEngine;
using System.Collections;

public class enemigoataca : MonoBehaviour {

public Transform player;
public float range = 50.0f;
public float bulletImpulse= 70.0f;

private bool onRange= false;

public Rigidbody projectile;

void Start(){
   float rand = Random.Range (1.0f, 2.0f);
   InvokeRepeating("Shoot", 1, rand);
}

void Shoot(){
   
   if (onRange){
      
      Rigidbody bullet = (Rigidbody)Instantiate(projectile, transform.position + transform.forward, transform.rotation);
      bullet.AddForce(transform.forward*bulletImpulse, ForceMode.Impulse);
      
      Destroy (bullet.gameObject, 2);
   }
   
   
}

void Update() {
   
   onRange = Vector3.Distance(transform.position, player.position)<range;
   
   if (onRange)
      transform.LookAt(player);
}


}
Bien esto se pone en un Empty GO y se pone el el cañon de la metralleta o lo que sea y dispara.Bien ahora la Torreta:es esta de la foto, bien el problema es que ponga donde le ponga este scrip que a continuación pondre la torreta se gira hacia mi(jugador), si pero qde que manera da mas vueltas que una peonza arriba abajo, de da la vuelta de queda de lado etc....lo que no encuentro es la manera de que solo se gire circularmente osea dando la vuelta no que se ponga bocabajo o bocarriba.... El script que tengo en ella:
using UnityEngine;
using System.Collections;

public class TurretScript: MonoBehaviour
{

public Transform Target;
public float RotationSpeed;

void Update()
{
   var direction = Target.transform.position - transform.position;
   
   direction.y = transform.position.y;
   
   var rot = Quaternion.LookRotation(direction, Vector3.up);      
   transform.rotation = Quaternion.RotateTowards(
      transform.rotation,
      rot,
      RotationSpeed * Time.deltaTime);
}
}
Agradeceria una ayudaita , muchas gracias de antemano!!!P.D, tampoco veo la manera de que dispare mas rapido...con la fuerza lo unico que consigo es que corra mas rapido la bala no el tiempo de disparo.  

Puedes bloquear las rotaciones si el objeto tiene rigidbody, pero igual es más cómodo que rotes solo en Y la torreta. Se me ocurre que en vez de Quaterniones podrías usar vectores3, dime a ver si así te funciona:
//Update
    float angulo = Vector3.Angle(transform.forward, (target.position - transform.position));
    transform.rotate = new Vector3 (0, angulo, 0);
 

@juanma_teso , muchas gracias por la respuesta. 
using UnityEngine;
using System.Collections;

public class rotatorreta : MonoBehaviour {

public Transform Target;
public float RotationSpeed;

void Update()
{
   var direction = Target.transform.position - transform.position;
   
   direction.y = transform.position.y;

   float angulo = Vector3.Angle(transform.forward, (Target.position - transform.position));
   transform.rotate = new Vector3 (0, angulo, 0);
   
   ///var rot = Quaternion.LookRotation(direction, Vector3.up);      
   ///transform.rotation = Quaternion.RotateTowards(
      //transform.rotation,
      //rot,
      ///RotationSpeed * Time.deltaTime);
}
}
quedaría algo asi?, pero me da un error en la variable rotate, deberia definirla?, pero n le veo la manera.Espero respuesta y gracias de nuevo. 

Julio 29, 2015, 03:55:37 PM #3 Ultima modificación: Julio 29, 2015, 03:56:45 PM por antoniomdk
Hola buenas. "rotate" no es una propiedad, es un método, por tanto tienes que usar:
transform.Rotate(new Vector3 (0, angulo, 0));
O más recomendable:
transform.Rotate(new Vector3 (0, angulo, 0) * Time.deltatime);
Con esto no te aseguro que la torreta rote correctamente, esta es la función correcta y dentro de ella ya tienes que poner un vector que se adecue.Yo te recomiendo si quieres que la torreta siga al personaje, lo siguiente:
int sign = Vector3.Cross(transform.position, Target.position).z < 0 ? -1 : 1;
transform.Rotate(Vector3.up * sign * Time.deltatime);
Ten en cuenta que he cogido el eje Z, pero lo puedes cambiar depende de la orientación que tenga tus objetos y demás. Y he cogido el Vector Up pero lo puedes cambiar también por la orientación que deseessSaludos!

[quote author=antoniomdk" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15833" data-ipsquote-contentcommentid="100905">Hola buenas. "rotate" no es una propiedad, es un método, por tanto tienes que usar:
transform.Rotate(new Vector3 (0, angulo, 0));
O más recomendable:
transform.Rotate(new Vector3 (0, angulo, 0) * Time.deltatime);
Con esto no te aseguro que la torreta rote correctamente, esta es la función correcta y dentro de ella ya tienes que poner un vector que se adecue.Yo te recomiendo si quieres que la torreta siga al personaje, lo siguiente:
int sign = Vector3.Cross(transform.position, Target.position).z < 0 ? -1 : 1;.Rotate(Vector3.up * sign * Time.deltatime);
Ten en cuenta que he cogido el eje Z, pero lo puedes cambiar depende de la orientación que tenga tus objetos y demás. Y he cogido el Vector Up pero lo puedes cambiar también por la orientación que deseessSaludos![/quote]Hola ,@antoniomdk , muchas gracias por tu respuesta , el codigo no da error alguno pero la torreta no me sigue solo va hacia adelante o hacia atras muyyy lentamente.Deberia girar sobre su eje y seguir mi posición. de echo tiene varios "trozos articulados especialmente para ello" pero solo va alante y atras, le he cambiado el UP por un right o un left y el efecto es el mismo....la z por la y ..lo mismo.

Julio 30, 2015, 02:45:55 AM #5 Ultima modificación: Julio 30, 2015, 02:48:27 AM por antoniomdk
Hola ramunda, prueba a usar Vector3.forward y lo de la velocidad simplemente que en esta linea de código 
transform.Rotate(Vector3.forward * sign * Time.deltatime);
Lo multipliques por una constante o una variable así:
transform.Rotate(Vector3.forward * sign * Time.deltatime * 10);
Y el .z solo tienes que cambiarlo en caso de que no te detecte si esta a la izquierda o a la derecha el jugador de la torreta.

[quote author=antoniomdk" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15833" data-ipsquote-contentcommentid="100943">Hola ramunda, prueba a usar Vector3.forward y lo de la velocidad simplemente que en esta linea de código 
transform.Rotate(Vector3.forward * sign * Time.deltatime);
Lo multipliques por una constante o una variable así:
transform.Rotate(Vector3.forward * sign * Time.deltatime * 10);
Y el .z solo tienes que cambiarlo en caso de que no te detecte si esta a la izquierda o a la derecha el jugador de la torreta.[/quote]Valeee eres un genio!!, pro la torreta no me sigue da vueltas sin cesar pero no me sigue a mi ella gira sola. Asi es como lo tengo:
var direction = Target.transform.position - transform.position; esto deberia funcionar....pero no xd
Que puede ser? gracias!!! 

Lo que pasa es que no se detiene, todo el tiempo la estás rotando con 1 o -1, rota hasta que se pase, y así siempre. O haces una condicional que te diga que "ya estás en la mira" y pare de rotar, con un Vector3.dot() o giras la torreta según el ángulo (como el primer ejemplo que te puse, pero bien escrito ), que si bien tampoco dejará de girar, girará muy poquito cuando estés en la mira...

Agosto 01, 2015, 01:04:52 AM #8 Ultima modificación: Agosto 01, 2015, 01:10:25 AM por antoniomdk
Lo que debería pasar es que cuando la torreta se pasa al personaje girando, automáticamente debe girar al lado contrario y al final debería apuntar siempre a este.Prueba a mezclar ambos códigos tal que así:
using UnityEngine;
using System.Collections;

using UnityEngine;
using System.Collections;

public class rotatorreta : MonoBehaviour {

public Transform Target;
public float RotationSpeed;

void Update()
{
        float angulo = Vector3.Angle(transform.forward, (Target.position - transform.position));
        if(angulo > 0.0f){
           int sign = 0;
      sign = Vector3.Cross(transform.position, Target.position).z < 0 ? -1 : 1;
      transform.Rotate(Vector3.forward * sign * Time.deltaTime * 10);
        }
}
}
 

[quote author=antoniomdk" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15833" data-ipsquote-contentcommentid="101020">Lo que debería pasar es que cuando la torreta se pasa al personaje girando, automáticamente debe girar al lado contrario y al final debería apuntar siempre a este.Prueba a mezclar ambos códigos tal que así:
using UnityEngine;using System.Collections;

using UnityEngine;
using System.Collections;

public class rotatorreta : MonoBehaviour {

public Transform Target;
public float RotationSpeed;

void Update()
{
        float angulo = Vector3.Angle(transform.forward, (Target.position - transform.position));
        if(angulo > 0.0f){
           int sign = 0;
      sign = Vector3.Cross(transform.position, Target.position).z < 0 ? -1 : 1;
      transform.Rotate(Vector3.forward * sign * Time.deltaTime * 10);
        }
}
}
 [/quote]sigue girando y girando sin parar  

Mira como veo que el post se alarga demasiado te he hecho el script de nuevo, no suelo hacer estas cosas pero es para poner fin ya al tema, para la próxima vez complícate un poco más la cabeza y no esperes que te lo den mascado. Porque fíjate el script que he tardado 5 minutos que sencillo es:
using UnityEngine;
using System.Collections;

public class Torreta : MonoBehaviour {
public Transform target;
public float rotationSpeed;
public bool useXaxis = false;
private Transform myTransform;

    void Start(){
   myTransform = transform;
}
void Update()
{
   Quaternion toRot = Quaternion.LookRotation (target.position);
   if(!useXaxis)
      toRot.x = 0;
   myTransform.rotation = Quaternion.Lerp (myTransform.rotation, toRot, rotationSpeed * Time.deltaTime);

}
}
pd: Si no te funciona ya es cosa de como tienes orientado el mundo y demás, el script es totalmente funcional porque yo mismo lo acabo de probar, espero que con esto se cierre ya el tema.

[quote author=antoniomdk" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15833" data-ipsquote-contentcommentid="101054">Mira como veo que el post se alarga demasiado te he hecho el script de nuevo, no suelo hacer estas cosas pero es para poner fin ya al tema, para la próxima vez complícate un poco más la cabeza y no esperes que te lo den mascado. Porque fíjate el script que he tardado 5 minutos que sencillo es:
using UnityEngine;using System.Collections;

public class Torreta : MonoBehaviour {
public Transform target;
public float rotationSpeed;
public bool useXaxis = false;
private Transform myTransform;

    void Start(){
   myTransform = transform;
}
void Update()
{
   Quaternion toRot = Quaternion.LookRotation (target.position);
   if(!useXaxis)
      toRot.x = 0;
   myTransform.rotation = Quaternion.Lerp (myTransform.rotation, toRot, rotationSpeed * Time.deltaTime);

}
}
pd: Si no te funciona ya es cosa de como tienes orientado el mundo y demás, el script es totalmente funcional porque yo mismo lo acabo de probar, espero que con esto se cierre ya el tema.[/quote]No se como agradecértelo antoniomdk, he estado haciendo mil pruebas y mas pruebas y esta ultima tuya es la mas acertada que de momento he conseguido.Desgraciadamente la torreta sigue pegandose al suelo en vez de girar derecha o izquierda.Cerramos el post sin problema , seguire probando hasta que algun dia encontrare la solución.Pero de verdad gracias por tu tiempo y dedicación.Un saludo muy cordial y un abrazo.  

Sinceramente me sabe mal, pero ya no es problema de código en serio, revisa si tienes rotado la torreta o si es hija de algún objeto que este rotado, en condiciones normales de ejes tiene que funcionar, ademas si quieres que gire solo de lado a lado no tildas la 3ra variable y si quieres que se oriente completamente tíldala, revisa todas las variables la velocidad, etc. Yo creo que lo que pasa es que el modelo lo has importado de lado o lo que sea, de hecho haz la prueba coloca un cubo y le añades el script y verás que se orienta hacia el objetivo. Saludos.

Agosto 03, 2015, 12:05:08 AM #13 Ultima modificación: Agosto 03, 2015, 12:10:28 AM por ramunda
[quote author=antoniomdk" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="15833" data-ipsquote-contentcommentid="101056">Sinceramente me sabe mal, pero ya no es problema de código en serio, revisa si tienes rotado la torreta o si es hija de algún objeto que este rotado, en condiciones normales de ejes tiene que funcionar, ademas si quieres que gire solo de lado a lado no tildas la 3ra variable y si quieres que se oriente completamente tíldala, revisa todas las variables la velocidad, etc. Yo creo que lo que pasa es que el modelo lo has importado de lado o lo que sea, de hecho haz la prueba coloca un cubo y le añades el script y verás que se orienta hacia el objetivo. Saludos.[/quote]Antonio, gracias de nuevo hermano, lo probe en un cubo para ver el resultado y la verdad y con todos mis respetos...no gira:(Pero mira, para que veas que SI sirve de algo vustra ayuda y tiempo, y SI , que dedico mas de lo que pensais en intentar aprender y solucionar antes de daros el palo XDPrueba este script.....esta en Javascript lo se no es lo mejor pero asi lo he conseguido.Puedo decirle que valor le doy a la variable X,Y,Z , la velocidad y si gira sobre su eje sin despilfarrarse por los suelos ...digamos que ha sido como un ....milagro jajaja pero lo consegui y todo gracias a ti y  demas participantes.A todos GRACIAS!!! aqui esta el script.
								

Agosto 03, 2015, 02:53:10 AM #14 Ultima modificación: Agosto 03, 2015, 02:55:16 AM por GSG3D
Utiliza esto...
Quaternion newRotation = Quaternion.LookRotation(target.transform.position - transform.position); //depende la posicion de los ejes tambien

firtsAxis.rotation = Quaternion.Slerp(firtsAxis.rotation, newRotation, speed * Time.deltaTime);
Y luego bloquea la rotacion que quieras mediante codigo o por rigibody.
Esto es para un eje, si tienes otro agrega este mismas lineas pero cambiando el eje ("firstAxis").
Saludos!

Etiquetas: