Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[Solved] Detaching shot from shooter

Discussion in 'Scripting' started by JonNPoulsen, Jun 23, 2016.

  1. JonNPoulsen

    JonNPoulsen

    Joined:
    Jun 22, 2016
    Posts:
    13
    I'm making a platform game and have encountered a curious issue. I've created a health slider and an enemy dummy prefab which causes the player to lose one third of its HP when the dummy and the player collides. This part works fine. But I also created shots for the player to fire and made it such that if the shots collide with the dummy, the dummy is deactivated. Unfortunately, the shot is connected to the player through a spawn transform that is a child of the player object. This (I think) causes Unity to regard the shot as a part of the player so when the shot collides with the dummy, the player loses all its HP!

    Can you tell me how to detach the shot from the player but still have it spawn from a point relative to the player's position? Or alternatively come up with a clever if-expression that will distinguish shot from player?

    This is the relevant part of the player controller:
    Code (CSharp):
    1. void Update()
    2.   {
    3.   if (Input.GetKey("1") && Time.time > nextFire && ammunition > 0)
    4.   {
    5.   nextFire = Time.time + fireRate;
    6.   Destroy(Instantiate(phony, phonySpawn.position, phonySpawn.rotation), 3);
    7.   ammunition = ammunition - 1;
    8.   }
    9.   {
    10.   if (Input.GetKeyDown(KeyCode.Space) && Time.time > nextJump)
    11.   {
    12.   nextJump = Time.time + jumpRate;
    13.   rb.AddForce(new Vector3(0, jump, 0));
    14.   }
    15.   }
    16.   }
    This is the script that causes the player to take damage on collision with the dummy. It is attached to the dummy prefab:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. public class CollisionDamage : MonoBehaviour
    5. {
    6.  
    7.     public Slider healthBarSlider;  //reference for slider
    8.     public Text gameOverText;   //reference for text
    9.     public GameObject player;
    10.     public GameObject shot;
    11.  
    12.     void Start()
    13.     {
    14.         gameOverText.enabled = false; //disable GameOver text on start
    15.     }
    16.  
    17.     //Check if player collides with enemy
    18.     void OnTriggerEnter(Collider player)
    19.     {
    20.         if (healthBarSlider.value > 0.667)
    21.         {
    22.             healthBarSlider.value = 0.667f;  //reduce health
    23.         }
    24.         else if (healthBarSlider.value > 0.333f)
    25.         {
    26.             healthBarSlider.value = 0.333f;
    27.         }
    28.         else if (healthBarSlider.value > 0)
    29.         {
    30.             healthBarSlider.value = 0;
    31.             gameOverText.enabled = true; //enable GameOver text
    32.             Destroy(player);
    33.         }
    34.     }
    35. }
    Also, I tried attaching the tag "Shot" to the shots and modify the code like this:

    Code (CSharp):
    1.  void OnTriggerEnter(Collider player)
    2.   {
    3.   if (player.CompareTag("Shot") == true)
    4.   { healthBarSlider.value = healthBarSlider.value; }
    5.   else if (healthBarSlider.value > 0.667 && player.CompareTag("Shot")==false)
    6.   {
    7.   healthBarSlider.value = 0.667f;  //reduce health
    8.   }
    9.   else if (healthBarSlider.value > 0.333f && player.CompareTag("Shot") == false)
    10.   {
    11.   healthBarSlider.value = 0.333f;
    12.   }
    13.   else if (healthBarSlider.value > 0 && player.CompareTag("Shot") == false)
    14.   {
    15.   healthBarSlider.value = 0;
    16.   gameOverText.enabled = true; //enable GameOver text
    17.   Destroy(player);
    18.   }
    19.   }
    20. }
    This worked to a limited extent but the player still loses two thirds of its health when it shoots the dummy.
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    Code (csharp):
    1.  
    2. if (Input.GetKey("1") && Time.time > nextFire && ammunition > 0)
    3.   {
    4.   nextFire = Time.time + fireRate;
    5.   Destroy(Instantiate(phony, phonySpawn.position, phonySpawn.rotation), 3);
    6.   ammunition = ammunition - 1;
    7.   }
    8.  
    there is nothing in that code which would add the instantiated gameobject to the player as a child... so unless you are doing it somewhere else I think you're off track.

    To set an instance to be a child you have to call "transform.SetParent" or set the "transform.parent" attribute to be the instance... i.e.

    Code (csharp):
    1.  
    2. GameObject bullet = Instantiate(bulletPrefab, Vector3.zero, Quaternion.identity);
    3. bullet.transform.parent = transform; // set the bullet to be a child of the transform this script is attached to
    4.  
     
    JonNPoulsen likes this.
  3. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    Code (csharp):
    1.  
    2.  void OnTriggerEnter(Collider player)
    3.     {
    4.         if (healthBarSlider.value > 0.667)
    5.         {
    6.             healthBarSlider.value = 0.667f;  //reduce health
    7.         }
    8.         else if (healthBarSlider.value > 0.333f)
    9.         {
    10.             healthBarSlider.value = 0.333f;
    11.         }
    12.         else if (healthBarSlider.value > 0)
    13.         {
    14.             healthBarSlider.value = 0;
    15.             gameOverText.enabled = true; //enable GameOver text
    16.             Destroy(player);
    17.         }
    18.     }
    19.  
    no, calling the collider parameter being passed into the function "player" doesn't mean anything other than the variable is called player. The physics engine is just passing in the collider that is involved in the collision, you can call it anything you like "other" "it" "something", the variable name is functionally irrelevant

    Code (csharp):
    1.  
    2. void OnTriggerEnter(Collider other)
    3. {
    4. if(other.tag = "Player") // or some such check
    5. {
    6. // do stuff because it's a thing tagged "player"
    7. }
    8. }
    9.  
     
    JonNPoulsen likes this.
  4. JonNPoulsen

    JonNPoulsen

    Joined:
    Jun 22, 2016
    Posts:
    13
    You're right. I changed the collider to "other" and included the condition other.gameObject == player and that solved the problem. Thanks!