- Home /
FPS damage arrow? (raycast shoot)
Hello! how to i make the damage arrows depending the site of enemy shoot? thanks you! enemy shoot script:
using UnityEngine;
using System.Collections;
public class EnemyShoot : MonoBehaviour {
public float Damage;
public Camera EnemyCam;
public float Force;
public GameObject HitEffect;
public float Range;
public float FireRate = 0f;
private float NextTimeToFire = 0f;
public float MaxAmmo;
public float CurrentAmmo;
public bool Reloading;
public float ReloadTime;
public float ReloadAmmo;
public ParticleEmitter MuzzleFlash;
public Transform LightPosition;
public Transform Light;
public AudioClip ShootSound;
void Start ()
{
CurrentAmmo = MaxAmmo;
}
void Update ()
{
if(CurrentAmmo <= 0)
{
CurrentAmmo = 0;
StartCoroutine(Reload());
}
if(Time.time >= NextTimeToFire)
{
NextTimeToFire = Time.time + 1f/FireRate;
Fire();
}
}
IEnumerator Reload()
{
Reloading = true;
yield return new WaitForSeconds(ReloadTime);
CurrentAmmo = ReloadAmmo;
Reloading = false;
}
void Fire()
{
if(CurrentAmmo > 0)
{
MuzzleFlash.Emit();
CurrentAmmo--;
audio.Play();
audio.clip = ShootSound;
Instantiate(Light, LightPosition.position, LightPosition.rotation);
RaycastHit hit;
if (Physics.Raycast(EnemyCam.transform.position, EnemyCam.transform.forward, out hit, Range))
{
Debug.Log(hit.transform.name);
PlayerHealth target = hit.transform.GetComponent<PlayerHealth>();
if(target != null)
{
target.TakeDamagePlayer(Damage);
}
if(hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * Force);
}
Instantiate(HitEffect, hit.point, Quaternion.LookRotation(hit.normal));
}
}
}
}
Answer by julio-hb · Jan 14, 2019 at 10:51 PM
as of what I understand, you want the arrow to do different damage based on where it hit? (like a headshot would deal more damage than a arrow to the knee?)
personally, I would set up different tags to check here I hit the character e.g:
arms,legs, torso, head ect. would have different colliders, and tags
then in line ca. 75 you would check which part this is hit, using hit.transform.tag.
heres some code that might be useful
Transform target = hit.transform;
if(target != null)
{
switch(target.tag)
{
case "arm":
target.GetComponent<PlayerHealth>().TakeDamagePlayer(arm_damage);
break;
case "leg":
target.GetComponent<PlayerHealth>().TakeDamagePlayer(leg_damage);
break;
case "torso":
target.GetComponent<PlayerHealth>().TakeDamagePlayer(torso_damage);
break;
case "head":
target.GetComponent<PlayerHealth>().TakeDamagePlayer(head_damage);
break;
}
}
kinda hardcoded, but you should get the point.
Answer by Cornelis-de-Jager · Jan 14, 2019 at 11:50 PM
@julio-hb has given and example of one type of Damage system. I would like to give an example of another that I tend to use. Its very simple and very scaleable (especially when you add armor/damage reduction)
The basic idea behind it is that each part of the body has its own collider, these objects will be children to the Player object. The Player object will have the health/stats/info about the player and is kept in a single game object that does not have a collider. When something hits each collider / When a body part gets hit, it calls a the appropriae function in the Player
script.
Ok, thats the concept, now lets see an implementation - I have also added slow effect as well as damage effect to show how this system is versitile and flexible:
/// <Summary>
/// Basic player script
/// </Summary>
public class Player : MonoBehaviour {
public int health;
public float speed;
void FixedUpdate () {
// Do normal movement and stuff
}
///////////////// DAMAGE //////////////////
public void DamagePlayer (int damage) {
health = health - damage > 0 : health - damage ? 0;
if (health == 0)
Die();
}
///////////////// SLOW //////////////////
public void SlowPlayer (float slow, float time) {
StartCoroutine (ApplySlow (slow, time))
}
IEnumerator ApplySlow (float slow, float time) {
var tempSlow = slow <= speed ? slow : speed;
speed -= tempSlow;
yield return new WaitForSeconds (time);
speed += tempSlow;
}
///////////////// FORCE //////////////////
public void ApplyForce (Vector3 force) {
GetComponent<RigidBody> ().AddForce(force);
}
///////////////// SLOW //////////////////
void Die() {
// Handle Death
}
}
/// <Summary>
/// Script on Limbs
/// </Summary>
public class Limb : MonoBehaviour {
public float armor;
public Player player;
void Start () {
// Get the player
player = transform.parent.GetComponent<Player>();
}
/// <Summary>
/// Call this Directly when using Raycast.
/// Otherwise let the OnCollision event call it
/// </Summary>
public void Hit (int damage = 0, float slow = 0, float slowTime = 0, Vector3 moveForce = null) {
if (damage > 0){
// Do damage reduction
damage = damage < armor ? 0 : damage - armor;
armor = damage < armor ? armor - damage : 0;
// Deal the damage
player.DamagePlayer(damage);
}
if (slow > 0 && slowTime > 0)
player.SlowPlayer (slow, slowTime)
if (moveBody != null)
player.ApplyForce (moveForce);
}
}
void Fire() {
if(CurrentAmmo > 0)
{
MuzzleFlash.Emit();
CurrentAmmo--;
audio.Play();
audio.clip = ShootSound;
Instantiate(Light, LightPosition.position, LightPosition.rotation);
RaycastHit hit;
if (Physics.Raycast(EnemyCam.transform.position, EnemyCam.transform.forward, out hit, Range))
{
Debug.Log(hit.transform.name);
Limb target = hit.transform.GetComponent<Limb>();
if(target != null)
{
target.hit(damage:Damage, slow: Slow, slowTime: SlowTime, moveForce: -hit.normal * Force);
}
Instantiate(HitEffect, hit.point, Quaternion.LookRotation(hit.normal));
}
}
}
Your answer
Follow this Question
Related Questions
damage system 0 Answers
Enemy deals damage to player on contact 2 Answers
Enemy fire rate? help! 2 Answers
Deal damage on collision 2 Answers
My Enemy Damage Script not working 1 Answer