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

Tallying hits on an instantiated target with collisions

Discussion in 'Scripting' started by voh_unity400, Mar 30, 2021.

  1. voh_unity400

    voh_unity400

    Joined:
    Mar 22, 2021
    Posts:
    2
    I'm trying to count the number of targets destroyed. Both the targets and projectiles are generated through "Instantiate()". I'm trying to see if there's a way to take the OnCollission or OnTrigger events from the targets and affect variables on the script that called "Instantiate" on them.
    In other words, I want the script that created those targets, which is also governing the game's rules, to be able to count the number of targets that were and weren't destroyed.
    The targets are made with a prefab with a Box Collider with Trigger On.
    When a Target is hit by a projectile (or hits the floor) I'd want it to first add to the tally of targets hit (or targets missed) and then destroy itself.
    Below is the code I'm using to update the state of the game and the OnTriggerEnter what I'd like it to do.
    Code (CSharp):
    1.  void Update()
    2.     {
    3.         float target_gen_timer = Mathf.Repeat(Time.time, target_launch_period);
    4.         if (target_gen_timer < 0.1*target_launch_period)
    5.         {
    6.             if (make_target)
    7.             {
    8.                 make_target = false;
    9.                 // Position Randomizer
    10.                 Vector3 target_pos = random_position_radial();
    11.                 // Test position
    12.                 target_pos = new Vector3(0,20,50);
    13.                 // Create new instance of target
    14.                 target_instance = Instantiate(target_prefab, target_pos, Quaternion.identity) as GameObject;
    15.                 // Set Target's Rigidbody properties
    16.                 Rigidbody target_rb = target_instance.GetComponent<Rigidbody>();
    17.                 target_rb.drag = drag;
    18.             }
    19.         }
    20.         else
    21.         {
    22.             make_target = true;
    23.         }
    24.     }
    25.  
    26.     private void OnTriggerEnter(Collider other)
    27.     {
    28.         Debug.Log("Collision with "+other.gameObject.name);
    29.         if (other.gameObject.name == "Plane")
    30.         {
    31.             missed_targets++;
    32.         }
    33.         else if (other.gameObject.name == "Bullet(Clone)")
    34.         {
    35.             hit_targets++;
    36.             int next_level = hit_targets/10;
    37.             if (next_level > level)
    38.             {
    39.                 level = next_level;
    40.                 Update_drag();
    41.                 Update_period();
    42.                 level_counter.text = "Level "+level;
    43.             }
    44.             Destroy(other.gameObject);
    45.         }
    46.         scoreboard.text = "Targets Hit: " + hit_targets + "\nTargets Missed: " + missed_targets;
    47.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Totally doable. Here's how I would do it:

    I would put a little stub script on the instantiated object that lets you connect callbacks to change values in the script that contained the Instantiate() call, something like:

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class OnTriggerNotifier : MonoBehaviour
    4. {
    5.     public System.Action<GameObject> WhatToCall;
    6.  
    7.     private void OnTriggerEnter(Collider other)
    8.     {
    9.         WhatToCall?.Invoke(gameObject);
    10.     }
    11. }
    When you Instantiate() the thing,

    Code (csharp):
    1. // replace this line with however you get your new thingy
    2. GameObject NewThingy = GameObject.CreatePrimitive(PrimitiveType.Cube);
    3.  
    4. NewThingy.GetComponent<Collider>().isTrigger = true;
    5.  
    6. OnTriggerNotifier notifier = NewThingy.AddComponent<OnTriggerNotifier>();
    7.  
    8. // now give it a function to call when trigger happens:
    9. notifier.WhatToCall += (go) => {
    10.  Debug.Log( "GameObject '" + go.name + "' was triggered.");
    11. };
    I chose to make it pass back the GameObject of the thing it hit. You don't need that, or you could pass back other things.

    Obviously you can "forward" anything that happens to this GameObject using this pattern, such as OnCollision stuff or whatever. It's super-open-ended and flexible.
     
  3. voh_unity400

    voh_unity400

    Joined:
    Mar 22, 2021
    Posts:
    2
    Thank you very much. This has been of great help!
     
    Kurt-Dekker likes this.