Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Assigning script to variable without knowing script name

Discussion in 'Scripting' started by Flunkee, Apr 30, 2016.

  1. Flunkee

    Flunkee

    Joined:
    Mar 6, 2015
    Posts:
    17
    I'm creating a game where I have multiple enemy types, each with their own unique script (All enemy scripts inherit from a common script called "Enemy.cs" though (Enemy.cs inherits from Humanoid.cs, not sure if need to know but it might)).
    So when a bullet with an OnTriggerEnter method comes into contact with one of these enemies, and I want to access it's variables/methods, I can't simply say
    Code (CSharp):
    1. EnemyScript enemy = other.GetComponent<EnemyScript> ();
    Because I have no idea which script it will be! Can someone help me out here? Thanks.
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    A way of solvin this is that you can create an "Object" variable (public) and then assign the script to it, and then with myScript.GetType() you can get the "name" of the script
     
  3. Flunkee

    Flunkee

    Joined:
    Mar 6, 2015
    Posts:
    17
    I understand what this is supposed to do but I'm still a bit confused on it.
    Mind giving an example?
     
  4. aer0ace

    aer0ace

    Joined:
    May 11, 2012
    Posts:
    1,513
    For this situation, I typically have an integer id attached to the base for type. This way, subclasses can then assign the proper type id, and you can look at the enemy script this way.

    Similarly, you can just try casting to the specific type on GetComponent, and if it returns null, then the object doesn't have that type of script on it.
     
  5. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    at the variables:
    public Object script;
    you attach the script in the inspector

    in your code:
    yourGameObject.GetComponent<script.GetType>();

    .GetType() returns the "name" of the script (it's "type" to be specific) and because getComponent needs a "type" to be defined, it should work
     
  6. Flunkee

    Flunkee

    Joined:
    Mar 6, 2015
    Posts:
    17
    I have multiple enemy types and I will not know which one the bullet hits.
     
  7. Flunkee

    Flunkee

    Joined:
    Mar 6, 2015
    Posts:
    17
    Mind going into more detail?
     
  8. subikowyy123

    subikowyy123

    Joined:
    Aug 19, 2019
    Posts:
    1
    Nie.
    wiem, że trochę się spóźniłem ... ale daj mi wroga.cs metody OnTriggerEnter:)

    private void OnTriggerEnter (Collider other)
    {
    if (other.tag == "Pocisk")
    {
    // umieść tutaj co chcesz
    }
    }
     
  9. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    Interfaces can help you solve this. For example, let's pretend we want to set health variable to a bunch of unknown scripts. Declare an interface:

    Code (CSharp):
    1. public interface IHealth {
    2.   public float CurrentHealth { get; set; }
    3. }
    Implement it

    Code (CSharp):
    1. public class EnemyBug : IHealth {
    2.     public float currentHealth {get; set;}
    3. }
    and use like this
    Code (CSharp):
    1. var health = other.GetComponent<IHealth>();
    2. if(health != null) // other have some health points
    3. {
    4.    health.currentHealth = 100;
    5. }
     
  10. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,340
    Usually you'd inverse that - your EnemyScript would have a (potentially abstract) HitByBullet method that handled getting hit. Or you'd do what @palex-nx is suggesting, which is better design.

    Still, if you want to dispatch manually in the OnTriggerEnter, you can just check the type and decide based on that. This is pretty clean in newer versions of Unity with an up-to-date C# version, by using the new pattern-matching switch statement

    Code (csharp):
    1. EnemyScript enemy = other.GetComponent<EnemyScript> ();
    2.  
    3. switch (enemy) {
    4.     case null: // aka other didn't have an EnemyScript component.
    5.         break;
    6.     case Goblin goblin:
    7.         HandleHittingGoblin(goblin);
    8.         break;
    9.     case Dragon dragon:
    10.         HandleHittingDragon(dragon);
    11.         break;
    12.     default:
    13.         Debug.Log($"Hit unknown enemy type {enemy.GetType()}");
    14.         break;
    15. }
     
  11. AndersMalmgren

    AndersMalmgren

    Joined:
    Aug 31, 2014
    Posts:
    5,358
    This goes against alot of patterns. SOLID for one. You have a hittable object being hit by a hitter object.