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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

(C#) How to find a script you don't know the name of and call one of it's public functions

Discussion in 'Scripting' started by slingy11, Oct 20, 2015.

  1. slingy11

    slingy11

    Joined:
    Jun 8, 2013
    Posts:
    8
    I have a bit of a problem: I have a script for the player, and in it, I have a GameObject variable pointing the the weapon you're carrying. Every weapon has two scripts, one called XRayScript, and the other is dependent on the weapon (there are multiple possible scripts.) Every of the weapon scripts (Not the XRayScript) has a public void function called FireWeapon() . I'm trying to find the script of the weapon and call the function when you press a button from the player script, but there are multiple possible weapon scripts, so I don't know how to find it and call the function. Any ideas?
     
    FifHyde likes this.
  2. RiokuTheSlayer

    RiokuTheSlayer

    Joined:
    Aug 22, 2013
    Posts:
    356
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    This is what an interface, or abstract class, is for.

    You define the shape of the type, and then the class says it will implement that shape, and you can reference it as the interface or abstract class.

    Code (csharp):
    1.  
    2. public interface IWeapon
    3. {
    4.     void FireWeapon();
    5. }
    6.  
    7. public class XRayScript : MonoBehaviour, IWeapon
    8. {
    9.  
    10.     public void FireWeapon()
    11.     {
    12.         //fire!
    13.     }
    14.  
    15. }
    16.  
    17.  
    18. //... elsewhere
    19. var go = *someGameObjectWithPossibleWeaponScript*;
    20. var weapon = go.GetComponent<IWeapon>();
    21. weapon.FireWeapon();
    22.  
    As an abstract class (both options are valid... usually abstract classes are used when some implementation needs to be inherited as well, or to force some inheritance chain).

    Code (csharp):
    1.  
    2. public abstract class Weapon : MonoBehaviour
    3. {
    4.     pulic abstract void FireWeapon();
    5. }
    6.  
    7. public class XRayScript : Weapon
    8. {
    9.  
    10.     public override void FireWeapon()
    11.     {
    12.         //fire!
    13.     }
    14.  
    15. }
    16.  
    17.  
    18. //... elsewhere
    19. var go = *someGameObjectWithPossibleWeaponScript*;
    20. var weapon = go.GetComponent<Weapon>();
    21. weapon.FireWeapon();
    22.  




    There is also 'SendMessage' which doesn't require this structuring.
    http://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html

    Only thing is that it reflects out the method and is 'technically' slower. But that's not my reason against.

    I'm not a fan because:
    1) it promotes unstructured code.
    2) it has the potential to call methods on several unrelated scripts if the name collides with a function on an unrelated script. This results in having to create arbitrarily unique names... which can be annoying as your project grows and you have more and more messages to send about.
    3) debugging is a pain as you don't have any direct call to the method being called. The compiler can't catch if you mispelled it 'FireWEapon' or 'FirWeapon' or anything when you pass in the string. Nor can you easily jump to all references when using advanced IDE tools in Visual STudio or MonoDevelop.

    and many many more little quibbles
     
    Last edited: Oct 20, 2015
  4. slingy11

    slingy11

    Joined:
    Jun 8, 2013
    Posts:
    8
    Hey thanks a bunch to both of you. I tried both methods and the worked perfectly, but I decided to go with the abstract class, because SendMessage will try to send it to the XRayScript, and I'll take the little performance increase.
     
    FifHyde likes this.
  5. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,739
    interface might be your best bet, since you can only inherit from one class, but your class can implement as many interfaces as is needed.
     
    FifHyde likes this.