- Home /
Player not taking damage with hit collidor
I'm very new to unity, and currently i'm trying to get my player to take damage from shots fired (Raycasts) from an enemy NPC. What currently works is that the player can damage the enemy NPC's when fired, but it doesn't work the opposite way, and i can't seem to figure out why.
Gun Class:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (AudioSource))]
public class Gun : MonoBehaviour {
public enum GunType {Semi,Burst,Auto};
public GunType gunType;
public float rpm;
public LayerMask collisionMask;
public float damage = 1;
// Components
public Transform spawn;
//public Transform shellEjectionPoint;
//public Rigidbody shell;
private LineRenderer tracer;
// System:
private float secondsBetweenShots;
private float nextPossibleShootTime;
void Start() {
secondsBetweenShots = 60/rpm;
if (GetComponent<LineRenderer>()) {
tracer = GetComponent<LineRenderer>();
}
}
public void Shoot() {
if (CanShoot()) {
Ray ray = new Ray(spawn.position,spawn.forward);
RaycastHit hit;
float shotDistance = 20;
if (Physics.Raycast(ray,out hit, shotDistance)) {
shotDistance = hit.distance;
// just testing here, dont mind this!
if(hit.transform.tag == "Player") {
Debug.Log ("Player Hit");
}
if(hit.collider.GetComponent<Entity>()) {
Debug.Log("Taking Damage");
hit.collider.GetComponent<Entity>().takeDamage(damage);
}
}
nextPossibleShootTime = Time.time + secondsBetweenShots;
audio.Play();
if (tracer) {
StartCoroutine("RenderTracer", ray.direction * shotDistance);
}
//Rigidbody newShell = Instantiate(shell,shellEjectionPoint.position,Quaternion.identity) as Rigidbody;
//newShell.AddForce(shellEjectionPoint.forward * Random.Range(150f,200f) + spawn.forward * Random.Range(-10f,10f));
}
}
public void ShootContinuous() {
if (gunType == GunType.Auto) {
Shoot ();
}
}
private bool CanShoot() {
bool canShoot = true;
if (Time.time < nextPossibleShootTime) {
canShoot = false;
}
return canShoot;
}
IEnumerator RenderTracer(Vector3 hitPoint) {
tracer.enabled = true;
tracer.SetPosition(0,spawn.position);
tracer.SetPosition(1,spawn.position + hitPoint);
yield return null;
tracer.enabled = false;
}
}
Entity class, which Player.cs and Enemy.cs extend:
using UnityEngine;
using System.Collections;
public class Entity : MonoBehaviour {
// this class will model our enemies
// enemy health
public float health;
public virtual void takeDamage(float dmg) {
// subtract dmg points from health
health -= dmg;
// log it
Debug.Log (health);
if(health <= 0) {
// kill enemy
die();
}
}
public virtual void die() {
// log that enenmy is dead
//Debug.Log ("Dead");
// destry the game object
Destroy (gameObject);
}
}
And the Enemy.cs class;
using UnityEngine;
using System.Collections;
public class Enemy : Entity {
// add player expereicne points
public float expOnDeath;
// get reference to player
private Player player;
void Start() {
// find the game object with player tag
player = GameObject.FindGameObjectWithTag ("Player").GetComponent<Player>();
}
// override base die method, but with added functionality
public override void die() {
// add exp points
player.AddExpereince (expOnDeath);
base.die ();
}
}
And the player.cs class
using UnityEngine;
using System.Collections;
public class Player : Entity {
private int level;
// current exp level
private float currentExpLevel;
// exp required to level up next
private float expToLevel;
public GameGUI gui;
void Start() {
gui = GameObject.FindGameObjectWithTag ("GUI").GetComponent<GameGUI> ();
// by default the players level will be set to 1
LevelUp ();
}
public override void die() {
base.die ();
}
public void AddExpereince(float exp) {
currentExpLevel += exp;
if(currentExpLevel >= expToLevel) {
currentExpLevel -= expToLevel;
LevelUp();
}
gui.setPlayerExp (level);
//Debug.Log ("EXP: "+currentExpLevel+" Level: "+level);
}
private void LevelUp() {
// increase exp level
level++;
expToLevel = level * 50 + Mathf.Pow (level * 2,2);
AddExpereince (0);
}
}
Answer by LRG · Dec 19, 2014 at 01:05 PM
This may not your issue, but it is probably worth checking.
You are raycasting and retrieving a single collision. Then, checking whether that one collision was against an Entity and applying damage in that case.
If you happen to be raycasting from within a gun, or from within the NPC, it is likely that the one collision being reported (which is the first one) is not the Entity (but the Gun, for instance), and thus it is essentially being ignored.
You might want to verify whether that is the case, and if it is, some possible solutions would be:
To filter some layers so that you don't get other collisions.
To start the raycast from further away.
To raycast for multiple collisions and iterate over all of them.
For the last approach, which is probably the easiest and safest, you can use http://docs.unity3d.com/ScriptReference/Physics.RaycastAll.html
Your answer
Follow this Question
Related Questions
turn on off particle system 1 Answer
Error ambiguous reference with Json 1 Answer
A node in a childnode? 1 Answer
how to create car wheel impression on ground in unity3d? 1 Answer