Accessing script from another object

Hello,

I have script attached to Player and another script attached to multiple Enemies
Anyway, I’m not sure how to access variables from Enemy script so Player can take damage, get experience and etc.

Writing public Enemy myEnemy; doesn’t work in Player script and I really don’t know how to fix it. :frowning:

EnemyScript

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour{
	
	public int Health;
	public int Damage;
    public int Experience;
}

Player Script:

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

//------------------------------------------------------------------------------------
public class Player{

	//Player attributes.
	private int Health;
	private int Mana;
	private int ReqExp;
	private int CurrExp;
	private int Level;
	private int Damage;

	//Set values of player attributes.
	public void SetValues(int HP, int MP, int R_EXP, int C_EXP, int LVL, int DMG){
		Health = HP;
		Mana = MP;
		ReqExp = R_EXP;
		CurrExp = C_EXP;
		Level = LVL;
		Damage = DMG;
	}

	//Player take damage from enemy and lose DMG of health points.
	public void GetDamage(int DMG){
		if (Health > 0) {
			Health -= DMG;
		}  

        if(Health <= 0;){
			GameObject.Destroy (GameObject.FindGameObjectWithTag ("Player"));
			Debug.Log ("You're dead!");
		}
	}

	public int GetHealth(){
		return Health;
	}
}
//------------------------------------------------------------------------------------

public class PlayerScript : MonoBehaviour {

	public Player myPlayer;
	public Enemy myEnemy;  // <-- I'm doing it wrong, yes?

	public float distance; //Distance between player and enemy.
	public Text myHealthText; //Health text.

	void Start(){
		//(Health, Mana, ReqExp, CurrExp, Lvl, Damage).
		myPlayer.SetValues (100, 100, 130, 0, 1, 10);
	}

	void Update () {
		distance = Vector3.Distance(gameObject.transform.position, 
        GameObject.FindGameObjectWithTag("Enemy").transform.position);

        if (distance <= 3) {
			myPlayer.GetDamage (myEnemyScript.Damage); //Get damaged by enemy.
			StartCoroutine (WaitAfterHit ()); //Wait few seconds after hit.
		}
		myHealthText.text = "Health " + myPlayer.GetHealth().ToString(); //Show player health.
	}
		
	IEnumerator WaitAfterHit(){
		yield return new WaitForSeconds (5);
	}
}
  }

You’ve got it right so far in that you’re referencing the Enemy script, but you will also need to associate that script with the correct enemy game object with that script attached. Here are some changes to the code that should allow you to access methods in the script that is attached to your enemy

	public Player myPlayer;
	public GameObject myEnemy;  // Create a public reference to the enemy game object.
	public float distance;
	public Text myHealthText;

	private Enemy _enemyScript; // Reference to the script attached to "myEnemy" object.

	void Start()
	{
		myPlayer.SetValues (100, 100, 130, 0, 1, 10);

		// Find the Enemy script attached to "myEnemy"
		_enemyScript = myEnemy.GetComponent<Enemy>();
	}

I would have continued with more modifications but I’m not sure where your variable “myEnemyScript” on line 62 is defined, so I don’t want to confuse you. But if you proceed by trying to access the methods in the Enemy script through “_enemyScript” as I defined it, then things should work the way you want them to.

It’s also worth mentioning that using GameObject.FindGameObjectWIthTag() in the update routine is a very, very bad idea as this becomes quite computationally expensive searching through all game objects in the scene every single frame. A more optimized approach would be to replace it with myEnemy.transform.position since I declared the public game object myEnemy in the modifications above. This way, you won’t search through all the game objects in your scene every frame just to check the distance between the player and the enemy. In the early stages of your project it might not be a big deal, but this will certainly become a problem as you add more objects to the scene and have more scripts running and such.