Noticias

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

Duda, ¿Cómo aplicar la desviación a una bala? (Solucionado)

Iniciado por Antonio, Agosto 06, 2015, 02:29:03 AM

Tema anterior - Siguiente tema
Agosto 06, 2015, 02:29:03 AM Ultima modificación: Agosto 06, 2015, 12:32:55 PM por Antonio
Buenas noches.

Resulta que estaba yo tan feliz añadiendo funciones mi paranoya de proyecto, y estaba aplicando el desvío de las balas, el juego es un Third Person Shooter, cuando el jugador mueve la cámara, se desplaza, o dispara, la cruceta se va abriendo, y se va cerrando también cuando el jugador mantiene la cámara apuntando al objetivo, la velocidad a la que se cierra, también se ve afectada por los atributos del arma que lleve, En fin, hasta ahí va todo bien.

Ahora la cosa es que al rayo de dirección, le aplico el "desvío", pero malamente, porque el desvío no queda relativo a la dirección del disparo, si no relativo al escenario. (Es decir, dependiendo de a donde dispare, el desvío a veces hace que las balas vayan hacia atrás... :S ). ¿Alguien sabe como funciona el traspaso ese de plano XY a puntos del mundo?.  El script donde esta lleva cerca de las 600 líneas, pero la parte del desvío en cuestión es esta:
void ShootRay ()
{

        //Buscando el punto de origen donde se instancia el disparo. Será desde el centro de la pantalla hacia el frente...
   float x = Screen.width / 2;
   float y = Screen.height / 2;

   Ray ray = Camera.main.ScreenPointToRay (new Vector3 (x, y, 0));
   RaycastHit hit;

        //Esto es que al disparar, también creo un pequeño LineRenderer para dejar un poco el efecto de la bala.
   GameObject go = Instantiate (bulletPrefab, transform.position, Quaternion.identity) as GameObject;
   LineRenderer line = go.GetComponent <LineRenderer> ();

        //Estos 2 valores, los uso mayormente para el lineRenderer.
   Vector3 startPos = weaponManager.ActiveWeapon.bulletSpawn.TransformPoint (Vector3.zero);
   Vector3 endPos = Vector3.zero;

        //De acuerdo, aquí lanzo el rayo de disparo. (desde el centro de la pantalla, hacia el infinito).
   if (Physics.Raycast (ray, out hit, Mathf.Infinity, myLayerMask))
   {

      //Bien, aqui empieza el asunto del desvio. El rayo que lancé, ha colisionado con algún objeto y ha devuelto el hit.point
            //hit.point es un Vector3 con la posición del punto donde ha dado y a donde se va a dirigir el disparo de mi arma,
            //disparando directamente a ese punto, pues sale el disparo bueno.
            //lo que quiero es añadir un poco la desviación (dependiendo del valor de ExtendingCross.spreadValue, que oscila entre 15 y 45
            //pero funciona bien, es fiable). Por ello...

            //Creo los offsets para el desvio.
      float DesvioX = 0;
      float DesvioY = 0;

            //Si el defaultSpread es >= 16. se aplica el desvio (en caso contrario, la cruceta está tan cerrada que no se nota diferencia
            //Por eso, si defaultSpread es <16, los Desvios serán 0 directamente.
      if (ExtendingCross.spreadValue >= ExtendingCross.defaultSpread+1)
      {
         float Rn = Random.Range (0,100); //Empiezo con el DesvioX, esto es para elegir si se desviará a la izq o a la derecha.
         if (Rn < 50)
         {
            DesvioX = -1;
         }else{
            DesvioX = 1;
         }

                //Aqui en la siguiente línea, el Desvio (1 o -1, se multiplica por spreadValue que tendrá un valor
                //entre 15 y 45 menos defaultSpread que tiene el valor 15.
                //De modo que al final queda DesviotX * (spreadValue - 15);
                //Si spreadValue es 15, 15-15= 0, no hay desvio,
                //Si SpreadValue es 20, 20-15= 5, y así va de momento
         DesvioX = DesvioX * (ExtendingCross.spreadValue - ExtendingCross.defaultSpread );

         Rn = Random.Range (0,100);//Esto es lo mismo pero para el DesvioY, esto elegira si se desviará para arriba o para abajo.
         if (Rn < 50)
         {
            DesvioY = -1;
         }else{
            DesvioY = 1;
         }
         DesvioY = DesvioY * (ExtendingCross.spreadValue - ExtendingCross.defaultSpread );
      }

            //Bien, esta línea está MAL, por lo dicho, no cai y esto está colocando las cosas en la zona del mundo XYZ, no relativo a la pantalla.
            //¿Alguna ida aqui O.ò ?

      Vector3 Destiny = new Vector3 (hit.point.x+ DesvioX,hit.point.y+DesvioY,hit.point.z);


            //Lo siguiente es ya lanzar el disparo que va desde el arma, hacia el punto de colisión que encontró el rayo anterior. (Que siempre está
            //en el centro de la pantalla y al que intento aplicarle el desvio.

            float distance = Vector3.Distance (Camera.main.transform.position, hit.point);
      //RaycastHit[] hits = Physics.RaycastAll (startPos, hit.point - startPos, distance);//Esta linea funciona bien.
      RaycastHit[] hits = Physics.RaycastAll (startPos, Destiny - startPos, distance);//Esta es la linea que estoy probando para aplicarle el desvio.

      foreach (RaycastHit hit2 in hits) //Y bueno, aqui ya son los objetos detectados, 3 casos de momento, si es destruible, si es enemigo  y si tiene Rigidbody.
      {
         if (hit2.transform.GetComponent<Obj_Destructible> ())//Si es destruible, lo rompemos.
         {
            hit2.transform.GetComponent<Obj_Destructible> ().destruct = true;
         }

         if (hit2.transform.GetComponent<Enemy_DamageCollider> ())//Si es un enemigo
         {
            AtacandoEnemigo (hit2.transform);               
         }else{
            //Posteriormente, si no es un enemigo, pues miraremos si tiene Rigidbody para empujarlo.
            if (hit2.transform.GetComponent<Rigidbody> ())
            {
               Vector3 direction = hit2.transform.position - transform.position;
               direction = direction.normalized;
               hit2.transform.GetComponent <Rigidbody> ().AddForce (direction * weaponManager.ActiveWeapon.Power);
            }
         }
      }

      //endPos = hit.point;
      endPos = Destiny;//Este es el end.Point con el Desvio en teoria, pero eso, hay que arreglarlo arriba.
   } else { //if(rayo 1)  // Esto es si no ha tocado nada, porque ha disparado al cielo o quien sabe que.
      endPos = ray.GetPoint (100); //Pues simplemente coge un punto que haya en el centro de la pantalla, a 100 unidades al fondo.
   }

        //Esto es ya para ajustar el line renderer de las balas.
   go.GetComponent <Utility_LineRendererShortener> ().currentPos = startPos;
   go.GetComponent <Utility_LineRendererShortener> ().targetPos = endPos;

   line.SetPosition (0, startPos);
   line.SetPosition (1, endPos);
}
Bueno, mucho tocho, aunque en verdad no hace tantas cosas, pero eso, ahí tengo que aplicar el DesvioX y DesvioY para desplazar el hit.point, pero no se me ocurre muy bien como hacerlo para que sea relativo a la cámara.

¿Alguna idea? @_@
 

Puedes probar esto:
// calculate camera relative direction to move:
    m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
    m_Move = v*m_CamForward + h*m_Cam.right;
Lo he sacado directamente del script del ThirdPersonUserControl, pues le he estado echando un ojo y justamente el personaje se mueve relativo a la cámara! Prueba a ver, pero igual mejor le pegas un repaso al script que tampoco es muy largo

Porque no pruebas a una vez que obtienes el rayo en XYZ justo antes de hacer la bala sumarle a esa direcion asi:DirecionDisparoXYZ += new Vector3(Random.Range[-1,1],Random.Range[-1,1],Random.Range[-1,1]); //Mediante esos valores puedes dar distintos recoils con solo esa linea tendras cierta desviacion , la cosa se complica un poco si quieres que cuanto mas rato dispares mas se desvie, pero una vez consigas desviarlo solo es darle vuelta, prueba a lo que te e dicho, una vez tengas la direccion a la miras desde el centro, sumarle ese Vector.Un saludo

Visita http://www.programacionwh.com encontraras tutoriales y muchas cosas .


Tambien puedes visitar mi canal de YouTube https://www.youtube.com/channel/UClSCTn0wPN1iFjED0yaoJUA



Agosto 06, 2015, 12:14:47 PM #3 Ultima modificación: Agosto 06, 2015, 12:28:54 PM por Antonio
Vale,  viendo lo de la cámara que no había caido, al final he conseguido que funcione aplicado esta línea en vez de la línea mala.
Vector3 Destiny = hit.point + cam.right * DesvioX + cam.up * DesvioY;
Destiny es el punto donde se dirigirá la bala, originalmente era el hit.point, pero ahora le sumo los vectores del cam.right y cam.up (una referencia de la cámara principal) pero además como son de valor 1, pues los puedo multiplicar fácilmente por los desvios para modificar la longitud. 

El caso del Random.Range (-1,2)
DirecionDisparoXYZ += new Vector3(Random.Range[-1,1],Random.Range[-1,1],Random.Range[-1,1]);

También me ha servido para darme cuenta de una cosa, al principio lo descarté, porque el Range daba también los valores 0, que al principio no quería, (por eso he puesto la condicinal del 50%, para elegir entre 1 o -1, eso lo hice porque no quería un desvío que fuera 0,0, pero sin ello, pues resulta que los desvío siempre serán hacia las diagonales, por lo que me lo he replanteado y he decidido reaplicar lor Rangos otra vez,  Además dejándolo en float para que dé también decimales y así reducir la posibilidad de que salga 0,0  , que aun así, si sale, pues tampoco es el fin del mundo, el jugador también se merece algo de suerte!.

 
            float DesvioX = 0;
      float DesvioY = 0;

      if (ExtendingCross.spreadValue >= ExtendingCross.defaultSpread+1)//Hay probabilidad de fallo.
      {
         float Rn = Random.Range (-1.0f,1.0f);
         DesvioX = Rn * (ExtendingCross.spreadValue - ExtendingCross.defaultSpread ) * 0.015f;

         Rn = Random.Range (-1.0f,1.0f);
         DesvioY = Rn * (ExtendingCross.spreadValue - ExtendingCross.defaultSpread ) * 0.015f;
      }

      Vector3 Destiny = hit.point + cam.right * DesvioX + cam.up * DesvioY;

      RaycastHit[] hits = Physics.RaycastAll (startPos, Destiny - startPos, distance);
Bueno, pues me gusta como ha quedado  

 

Si como dices deberias usar floats en vez de enteros, la verdad que no cai , probablemente por las horas,me alegro de que te funcioneUn saludo ;=)

Visita http://www.programacionwh.com encontraras tutoriales y muchas cosas .


Tambien puedes visitar mi canal de YouTube https://www.youtube.com/channel/UClSCTn0wPN1iFjED0yaoJUA



Etiquetas: