/// <summary> /// Comando ejecutado en el servidor que será el encargado de verificar que los jugadores han sido stuneados /// </summary> public void CmdUseSkill() { // recuperamos como parametro los objetos golpeados por el overlapSphere var colls = Physics.OverlapSphere(transform.position, impactRadius); foreach (Collider col in colls) { // Intentamos recuperar el componente NetPlayerHealth en el obhjeto colisionado por el overlapsphere NetPlayerHealth enemy = col.GetComponent <NetPlayerHealth> (); // Si el objeto impactado tiene el script de vida, significará que se trate de un jugador susceptible de ser stuneado if (enemy != null && col.gameObject != gameObject) { // Si cumple las condiciones, lo stuneamos enemy.TakeStunt(stuntTime); } } // Ponemos el contador de tiempo de coolDown al valor definido coolDownTimer = coolDown; // Activamos los efectos de la habilidad SkillEffect(); // Solicitamos que se realicen las acciones necesarias en las instancias RpcUseSkill(); }
/// <summary> /// Realiza el cálculo del RayCast para el disparo y activación de animación /// Será llamado mediante Message por el objeto padre Player. TOdas las armas /// deberían tener un método con el mismo nombre para poder ser disparadas. /// </summary> public void CallShoot(Vector3 direction) { if (!GrenadeLauncher) { // Si aún no podemos disparar, salimos del método if (Time.time < nextTimeToShoot) { return; } // Calculamos el momento en el que el jugador podrá volver a disparar nextTimeToShoot = Time.time + shootDelay; // Si no quedan balas, emitimos un sonido especial de aviso y salimos del método. if (magazine <= 0) { audioSource.PlayOneShot(noAmmoSound); return; } // Efecto de particulas del arma shootParticles.Play(); // Efecto de sonido del arma audioSource.Play(); // Animación de disparo animator.SetTrigger("Shoot"); // Guardamos la información de si el RayCast ha golpeado algo o no bool impact = false; // Información del objeto golpeado RaycastHit hitInfo; // Realizamos el Raycast desde la cámara impact = Physics.Raycast(head.position + direction, direction, out hitInfo, range, shootableLayer); // A modo de testeo, podemos mostrar por consola el nombre del objeto impactado por el Raycast if (impact) { Debug.Log(hitInfo.transform.name); // Instanciamos el sistema de partículas en el punto de impacto GameObject impactParticleTemp = Instantiate(impactParticle, hitInfo.point, Quaternion.LookRotation(hitInfo.normal)); // Destruimos las particulas tras 1 segundos. Destroy(impactParticleTemp, 1f); if (hitInfo.transform.gameObject.layer != LayerMask.NameToLayer("Player")) { // Instanciamos el Decal en el punto de impacto GameObject decalTemp = Instantiate(impactDecal, hitInfo.point + hitInfo.normal * 0.01f, Quaternion.LookRotation(-hitInfo.normal)); // Hacmeos que el decal sea hijo del objeto impactado decalTemp.transform.parent = hitInfo.transform; // Destruimos el decal tras 20 segundos Destroy(decalTemp, 20f); } // Añadimos fuerza para mover objetos con RigidBody if (hitInfo.rigidbody != null) { hitInfo.rigidbody.AddForce(-hitInfo.normal * impactForce); } // Verificamos si el objeto impactado dispone de un componente NetPlayerHealth NetPlayerHealth enemy = hitInfo.transform.GetComponent <NetPlayerHealth> (); // Si dispone de el, significará que es otro jguador, así que le aplico el daño del arma if (enemy != null) { // Si el disparo debe stunear if (shootStunt) { // Llamamos a la función del enemigo de ser stuneado con la duración preestablecida enemy.TakeStunt(stuntDuration); } // El método TakeDamage devuelve true, si somos nosotros los que lo hemos matado if (enemy.TakeDamage(damage)) { // Incrementamos el número de muertes GetComponentInParent <Score> ().kills++; } } } if (!unlimitedAmmo) { // Tras realizar el disparo, reducimos la bala en el cargador magazine--; UpdateAmmoDisplay(); } } else { // Si aún no podemos disparar, salimos del método if (Time.time < nextTimeToShoot) { return; } // Calculamos el momento en el que el jugador podrá volver a disparar nextTimeToShoot = Time.time + shootDelay; // Si no quedan balas, emitimos un sonido especial de aviso y salimos del método. if (magazine <= 0) { audioSource.PlayOneShot(noAmmoSound); return; } // Efecto de particulas del arma shootParticles.Play(); // Efecto de sonido del arma audioSource.Play(); // Animación de disparo animator.SetTrigger("Shoot"); GameObject granada = Instantiate(grenadePref, transform.position, transform.rotation); Rigidbody rb = granada.GetComponent <Rigidbody>(); rb.AddForce(transform.forward * fuerzaDisparo, ForceMode.VelocityChange); if (!unlimitedAmmo) { // Tras realizar el disparo, reducimos la bala en el cargador magazine--; UpdateAmmoDisplay(); } } }