C# Access Function From Another Script

I want to display a UI text message that appears while a certain function is being called. I have an enemy state system in my game and the UI text reflects whichever state the enemy is currently in. At the moment, this is working, but with my attack state there are two different functions inside that are called depending on how close the player is to the enemy when they attack. The two methods are Shoot (for long distance attacks) and Lunge (for close range attacks). At the moment for the attack state the text display says “Enemy is attacking” as expected but I want it to be more specific as to which method is being called, so it will say either “Enemy is shooting” or “Enemy is attacking at close range” depending on these methods. I feel I’m close to getting it to work, via searching online for answers, but it keeps throwing errors at me. At the moment it’s saying: Assets/Scripts/StatePatternEnemy.cs(112,26): error CS0019: Operator ==' cannot be applied to operands of type IEnemyState’ and `void. Is there something I’ve forgotten to add or am I doing it all wrong? I’ll post the relevant scripts here for you to check out. I appreciate any help.
The code in question is happening in StatePatternEnemy.cs and in the Update() method.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class StatePatternEnemy : MonoBehaviour {

    //Sets speed for enemy turning while searching for the player
    public float searchingTurnSpeed = 120f;
    //The amount of time the enemy spends looking for the player
    public float searchingDuration = 4f;
    //The range in which the enemy can detect or see the player
    public float sightRange = 20f;
    //This sets up waypoints for the enemy to follow
    public Transform[] wayPoints;
    public Transform eyes;
    public Vector3 offset = new Vector3 (0f,0.5f,0f);
    //Indicates what state the enemy is in
    public MeshRenderer meshRendererFlag;
    //Stores reference to bullet prefab
    public GameObject bulletPrefab;
    //Stores reference to text from message box UI component
    public Text messageBoxText;
    //Set location for bullet spawn location
    public Transform bulletSpawn;
    //UPDATE: 31/03/17: Enemy model cannot currently be animated due to errors from imported model
    //Get reference for Animator to control animations
    //Animator anim;
    //Reference to the audio source.
    public AudioSource enemyAudio;
    //The sound to play when the enemy dies.
    public AudioClip deathClip;
    //The sound to play when the enemy is wounded.
    public AudioClip damagedClip;
    //Gets a reference to each of the three enemies
    public GameObject enemyType1;
    public GameObject enemyType2;
    public GameObject enemyType3;
    public GameObject enemyCharacter;


    //These variables are hidden from the Inspector as they don't need to be edited
    //Locates the enemy's current chase target (the player)
    [HideInInspector] public Transform chaseTarget;
    //Variable for enemy's current state
    [HideInInspector] public IEnemyState currentState;
    //Variable for the chase state
    [HideInInspector] public ChaseState chaseState;
    //Variable for the alert state
    [HideInInspector] public AlertState alertState;
    //Variable for the patrol state
    [HideInInspector] public PatrolState patrolState;
    //Variable for the dead state
    [HideInInspector] public DeadState deadState;
    //Variable for the attack state
    [HideInInspector] public AttackState attackState;
    //Variable for enemy health
    [HideInInspector] public EnemyHealth enemyHealth;
    //Reference to NavMeshAgent component that allows AI to move around scene automatically
    [HideInInspector] public NavMeshAgent navMeshAgent;

    private void Awake()
    {
        chaseState = new ChaseState (this);
        alertState = new AlertState (this);
        patrolState = new PatrolState (this);
        deadState = new DeadState (this);
        attackState = new AttackState (this);
        //Gets the NavMeshAgent component before the game starts to run
        navMeshAgent = GetComponent<NavMeshAgent> ();
        enemyAudio = GetComponent<AudioSource> ();
        //Get Shoot and Lunge functions from AttackState class so the text can be changed depending on which of these are active
        enemyCharacter.GetComponent<AttackState>().Lunge();
        enemyCharacter.GetComponent<AttackState>().Shoot();
    }

    void Start()
    {
        //When the game starts to run, the default state for the enemy will be patrol
        currentState = patrolState;
        //Get message box text component when scene runs
        //messageBoxText = GetComponent<Text> ();
        //Get Animator component
        //anim = GetComponent<Animator> ();
    }

    public string GetCurrentState()
    {
        return currentState.GetType ().ToString ();
    }

    void Update()
    {
        //Update the current state of the enemy
        currentState.UpdateState ();
        //Updates message box text depending on enemy state
        //UPDATE 31/03/17. This if statement is what I tried to do to get the text to update but it didn't work. I was trying to get the current state.
        if (currentState == patrolState)
            messageBoxText.text = "Enemy is patrolling";
         else if (currentState == chaseState)
            messageBoxText.text = "Enemy is chasing";
         else if (currentState == alertState)
            messageBoxText.text = "Enemy is searching";
         else if (currentState == attackState)
            messageBoxText.text = "Enemy is attacking";
         else if (currentState == deadState)
            messageBoxText.text = "Enemy is dead";
        else if (currentState == AttackState.Instance.Shoot())
            messageBoxText.text = "Enemy is shooting";
        else if (currentState == AttackState.Instance.Lunge())
            messageBoxText.text = "Enemy is attacking at close range";
         else
            messageBoxText.text = "Unknown state";

    }

    void OnCollisionEnter(Collision col)
    {
        //If a bullet collides with an enemy and their health is more than 0...
        if (col.gameObject.tag == "Bullet" && enemyHealth.currentHealth > 0)
        {
            //Play the audio clip of the enemy being hurt
            enemyAudio.clip = damagedClip;
            enemyAudio.Play ();
        }
    }

    private void OnTriggerEnter (Collider other)
    {
        currentState.OnTriggerEnter (other);
    }
}
using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class AttackState : IEnemyState {

    //Reference to StatePatternEnemy script
    private readonly StatePatternEnemy enemy;

    //Whether player is within the trigger collider
    bool playerInRange;

    public static AttackState Instance;
  
    public AttackState(StatePatternEnemy statePatternEnemy)
    {
        enemy = statePatternEnemy;
    }

    void Awake()
    {
        Instance = this;
    }
  
    //Regularly updates Look and Search functions
    public void UpdateState()
    {
        Shoot ();
        Lunge ();
    }
  
    public void OnTriggerEnter (Collider other)
    {
        //If the entering collider is the player...
        if (other.CompareTag ("Player"))
        {
            //...the player is in range.
            playerInRange = true;
            Lunge();
            enemy.navMeshAgent.Stop();
        }
      
    }

    public void OnTriggerExit (Collider other)
    {
        //If the exiting collider is the player...
        if (other.CompareTag ("Player"))
        {
            //...the player is no longer in range.
            playerInRange = false;
        }
    }
  
    //Logic for patrol state when it transitions from alert state
    public void ToPatrolState()
    {
        Debug.Log ("Cannot transition from attack state to patrol state");
    }
  
    //Logic for alert state. This just generates a warning if it attempts to go into alert state when it's already in this state
    public void ToAttackState()
    {
        Debug.Log ("Can't transition to same state");
    }
  
    //Logic for chase state
    public void ToChaseState()
    {
        //Sets enemy into chase state from alert state
        enemy.currentState = enemy.chaseState;
        //Sets search timer to 0 as this isn't needed
        //searchTimer = 0f;
    }
  
    public void ToDeadState()
    {
        //Sets enemy into dead state from alert state
        enemy.currentState = enemy.deadState;
    }

    public void ToAlertState()
    {
        //Sets enemy into alert state when triggered
        enemy.currentState = enemy.alertState;
    }

    void Update()
    {
        //enemy.messageBoxText.text = "Enemy is attacking the player";
    }
  
    //This function sets up the logic so that if the player is detected by the enemy, the enemy will chase the player
    public void Shoot()
    {
        Debug.Log ("Enemy attacking at long distance range");
        //Set enemy state alerter to blue to show the enemy is attacking
        enemy.meshRendererFlag.material.color = Color.blue;
        //The raycast is used to detect the player
        RaycastHit hit;
        //If the enemy GameObject detects the player when they are within range and can see the player...
        if (Physics.Raycast (enemy.eyes.transform.position, enemy.eyes.transform.forward,
                             out hit, enemy.sightRange) && playerInRange) {
            //...the enemy will start to shoot at the player depending on what the raycast hit
            //enemy.chaseTarget = hit.transform;
            /*if (bullet != null)*/
            //{
            //Create bullet from bullet prefab
            var bullet = GameObject.Instantiate (enemy.bulletPrefab, enemy.bulletSpawn.position, enemy.bulletSpawn.rotation) as GameObject;
            //Add velocity to the bullet
            bullet.GetComponent<Rigidbody> ().velocity = bullet.transform.forward * 6;
            //Destroy the bullet after 2 seconds
            //enemy.Destroy (bullet, 2.0f);
            //}
            enemy.navMeshAgent.Stop ();
            //Debug.Log ("Attack");

        } else if (playerInRange == false) {
            ToAlertState();
        }

      
    }
  
    //This function is triggered when the enemy is in the chase state and is very close to the player.
    public void Lunge()
    {
        Debug.Log ("Enemy attacking at close range");
        //Set enemy state alerter to blue to show the enemy is attacking
        enemy.meshRendererFlag.material.color = Color.white;
        //Stops enemy's movement
        enemy.navMeshAgent.Stop ();
        Debug.Log ("Lunge");
        //If the player is no longer in range, the enemy will switch to the alert state
        if (playerInRange == false)
        {
            ToAlertState();
        }
  


    }
  
}
using UnityEngine;
using System.Collections;

public interface IEnemyState
{

    void UpdateState();

    void OnTriggerEnter (Collider other);

    void ToPatrolState();

    void ToAlertState();

    void ToChaseState();

    void ToDeadState();

    void ToAttackState();
}

The error pretty much says it all.

You’re trying to compare an ‘IEnemyState’ with ‘void’.

Your ‘currentState’ variable in the ‘StatePatternEnemy’ class is of type ‘IEnemyState’, whereas the methods ‘Shoot’ and ‘Lunge’ are declared as

public void Shoot(){...}
public void Lunge(){...}

They return nothing (void) and thus cannot be on either side of the ‘==’ operator. If it was another type, it would still need to either match the type on the other side or be convertable (either explicitly or implicitly).

This makes a lot of sense, thank you. Okay, I’ll do some research into this and see what I can come up with. If I can’t get it to work, it doesn’t matter too much.

The implementation you’ve done is questionable anyway.

You compare the states by reference (at least that’s the default of ‘==’).
If you wanted to implement a state-machine that uses state-objects rather than simple enum or integer states, you’d probably want to customize the equality comparison by overriding the Equals method (and perhaps the == operator as well) or completely eliminate that. Depends on your usage.

To simply fix the error, your methods would need to return an IEnemyState, but once again, if not implemented correctly, you’ll run into problems and I’d probably try to approach this a little different.

It’s also worth noting that you should not make everything public. Encapsulate the fields and instead provide accessors (get/set properties or methods) if you need the outer world to have influence on those fields. Exposing fields that should be tweakable and assignable in the inspector can use the [SerializeField] attribute.

This is pretty simple, you want to use a MVC approach to your programming so for example I have my character as a model, my keyboard movement as a controller, and my character movement as the view.

so you can call private myClass classa
classa.function(“hi”); to that effect.

remember that myClass needs to have a function with a string for it to display “hi”.

If myClass has a string variable you could even do
classa.stringVar = “sup yo”;
Debug.Log(classa.stringVar);