1

I got a script like this to create a raycast from maincamera and hit the enemy.

void FixedUpdate(){
    if (fire) { 
        fire = false;
        RaycastHit hit;
        if (Physics.Raycast (fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
            if (Enemy.distance < 80) {
                if (hit.collider.tag == "body") {
                    Debug.Log ("Bullet in the body.");
                    Enemy.bodyshot = true; //Changing other script variable.
                } else if (hit.collider.tag == "head") {
                    Debug.Log ("Bullet in the head.");
                    Enemy.headshot = true; //Changing other script variable.
                }
            }
        }
    }
}

Enemy Script in Update;

if (headshot) { //headshot variable is static to reach from other script.
            anim.SetTrigger ("isDying");
            speed = 0;
            death = true;
}

if (bodyshot) { //bodyshot variable is static to reach from other script.
    anim.SetTrigger ("isSore");
}

So, when I shoot an enemy, all enemies are dying at the same time. Because these scripts are attached to all enemies. I need to change bodyshot and headshot variables without using static. What can I do to separate them ?

Tolga Dogan
  • 45
  • 1
  • 5
  • the problem is that your variables are static so they are not variables of the respective instances. make use of `GameObject.GetComponent()` – yes Aug 18 '17 at 19:10

2 Answers2

2

When it comes to raycast, you only need the raycast script attached to an empty GameObject. It does not have to be attached to each individual Object that you want to perform the raycast on.

The only time you have to attach script to a GameObject you want to detect clicks on is when using the Unity EventSystem to detect clicks on the objects.

So, remove this script from other GameObjects and just attach it to one GameObject.

Note:

If you want to access or do something to the GameObject that the ray just hit, the GameObject is stored in the hit variable.

RaycastHit hit;...
Destroy(hit.collider.gameObject);

You can also access scripts attached to the Object hit:

hit.collider.gameObject.GetComponent<YourComponent>().doSomething();
Programmer
  • 121,791
  • 22
  • 236
  • 328
  • the problem is that he sets Enemy.headshot/bodyshot = true. they are static variables which he checks against in the Update function. thats why all instances of Enemy die. – yes Aug 18 '17 at 19:13
  • @yes I saw that. but the problem is more than that. That's why I told OP that the object hit is stored in the `hit` variable and that he can get the component from each **individual** object that is hit with `hit.collider.gameObject.GetComponent()` then do something with it. Another problem is that this script is attached to every object. I asked OP to remove it from every object and attach it to an empty object. I meany by sugin `hit.collider.gameObject.GetComponent()`, OP should know that the variables should not be `static`. – Programmer Aug 18 '17 at 19:29
  • i only wanted to empathize the static thing so OP maybe reads up about what i actually means rather then the usual unity explanation of "its something you can easily call from everywhere". sry im sure you know it, i always like to read your solutions and explanations. – yes Aug 19 '17 at 16:57
0

Instead of checking to see what the tag of the collider is, you can first check to make sure the collider is one of the colliders attached to your object, and then check the tag for body location. For example:

public Collider[] coll;
void Start() {
    coll = GetComponents<Collider>();
}

void FixedUpdate(){
    if (fire) { 
        fire = false;
        RaycastHit hit;
        if (Physics.Raycast (fpsCam.transform.position, fpsCam.transform.forward, out hit, range)){
            if (Enemy.distance < 80) {
                if (hit.collider == coll[0] || hit.collider == coll[1]) {
                    if (hit.collider.tag == "head"){

or to simplify you can make coll[0] the head and [1] the body and ignore checking for a tag.

edit: As Programmer mentioned, this is not an efficient way to do this since you will be casting a ray for every object that has this script and you really only want to be casting a single ray.

ryeMoss
  • 4,303
  • 1
  • 15
  • 34