Interesting Script Problem
This is the fourth time I'm asking for help with these scripts because it still doesn't work, with all the changes I've made so far. Anyway, I'm making a third person shooter. I have a bullet prefab which is shot by my enemies and my character. I'm using two scripts to do it. One is for the Bullet:
using UnityEngine;
using System.Collections;
public class MoveBullet : MonoBehaviour {
public int damage = 5;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter(Collider Enemy){
if(Enemy.gameObject.CompareTag("enemy"))
{
Enemy.gameObject.SendMessage("OnDamage", damage);
}
}
}
And the other for the Damage on the characters:
using UnityEngine;
using System.Collections;
public class Damage : MonoBehaviour {
public int damage = 5;
public int health = 100;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnDamage(){
health= health - damage;
if (health <= 0) {
Destroy(gameObject);
}
}
}
The script is largely working. When I get shot, I receive damage. When I shoot, my enemies receive damage. When health reaches 0, I die. The problem is, every time I shoot a bullet, my health drops by 5 as if I was shot. I could avoid all enemy bullets and I would still die from the damage received when I shot my own bullets. This basically makes the script unusable. Please tell me how to fix it because I'm an idiot and I have no idea (despite my best tries). Thanks!
Answer by LucasMars · Feb 19, 2016 at 10:14 PM
When the object is being created, is the bullet inside of the player? If so, then that is the problem. Since if it is colliding when being created, then it'll hurt your player.
@Lucas$$anonymous$$ars Yes, the bullet spawns inside the player. So, this is the problem then. Thank you! But how can I go around it because I need for the bullet to spawn inside the player?
You could disable the script for damage until the bullet exits the player. Or, another option, is to use two different types of bullets. One for enemies that hurt the player, and one for the player that hurts the enemies.
@Lucas$$anonymous$$ars Could you please show me how to disable the script until the bullet exits the player? Is there a line of code or something I could use? I would be eternally grateful for it!
I think it would work something like this:
using UnityEngine;
using System.Collections;
public class Damage : $$anonymous$$onoBehaviour {
//damage per bullet
public int damage = 5;
//player health
public int health = 100;
//time since bullet was created
public float time_bullet;
void OnDamage(){
time_bullet = Time.deltaTime;
if(Bullet.Intersects(**Your Player Object*) && time_bullet<Time.deltaTime+0.25f){//is overlapping and has been outside the player for a second
health= health - damage;
if (health <= 0) {
Destroy(gameObject);
}
}
}
}
If the bullet is inside the player and the time since the bullet was created is less than a quarter of a second (as you still want the player to interact with bullets if it isn't spawning inside the player), then don't run the script. Otherwise, you can go ahead and hurt the player.
To check whether any of your enemies are intersecting, you could have it so it checks each enemy individually, and only reset the value at the start of the frame.
using UnityEngine;
using System.Collections;
public class Damage : $$anonymous$$onoBehaviour {
//damage per bullet
public int damage = 5;
//player health
public int health = 100;
//time since bullet was created
public float time_bullet;
void OnDamage(){
time_bullet = Time.deltaTime;
//get array with all enemies
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemies");
bool intersects_bool = false;
foreach(GameObject Enemy in enemies){
if(Bullet.Intersects(Enemy)){
intersects_bool = true;
}
}
if(time_bullet<Time.deltaTime+0.25f && intersects_bool==true){//is overlapping and has been outside the player for a second
health= health - damage;
if (health <= 0) {
Destroy(gameObject);
}
}
}
}
What this does, is it checks each enemy to see whether it is overlapping. You don't change the bool to false in the middle, so that it can tell whether it is overlapping any enemy.
@Lucas$$anonymous$$ars Thank you, you wonderful man!
@Lucas$$anonymous$$ars I'm trying to use the code and it seems to be alright, but I'm getting the error "Assets/Scripts/Damage.cs(22,28): error CS0103: The name
Bullet' does not exist in the current context"`
Any idea how to fix this error?
Well, like 22 is if(Bullet.Intersects(Enemy)){
Now, I forgot to declare bullet as a variable. Add a line at the top of your code which is: private GameObject Bullet;
And then bring back your start function and declare this.gameobject (I assume the script above is on a bullet).
void Start(){
Bullet = this.gameObject;
}
If the script is not attached to the bullet, you are going to need to add code to your bullet creation script to change the variable Bullet (in this script) to the newest bullet created (by the other script).
You have two options with that then. You could either: A) $$anonymous$$ove the intersecting code to the bullets themselves B) Get the bullet gameobject at runtime.
I would recommend A. Have it so that each bullet has a script on which has the code with intersects. Then do a for loop that finds all bullets, and runs that function (which returns either true or false). Then run the code with the declining health, but only if one of the functions returned true.
Your answer
Follow this Question
Related Questions
Damage calculation with various weapons 1 Answer
An object reference is required to access non-static member 2 Answers
My Character dosen´t move 0 Answers