Pulling a variable from another object

So I tried asking this in the Unity Answers section, and it got answered but the solution didn’t work, and the topic was closed so I couldn’t really ask about it.

I have two of the same objects, the object “Monster”.
They each, being the same object, have the same script “MonsterAI”.
All I am trying to do is get it to read “X attacked Y.” in the console, with X being the monster attacking and Y being its target.
Here is my code, I am using C#:

using UnityEngine;
using System.Collections;

public class MonsterAI : MonoBehaviour
{
	public string name = "NoName";
	public float hp = 100f;
	public float attack = 10f;
	public float speed = 10f;
	public float team = 1f;
	
	float action_bar = 100f;
	public GameObject[] target;
	
	void Start()
	{
	
	}
	

	void Update()
	{
		//ticking down their action bar
		if (action_bar > 0f)
		{
			action_bar -= speed * Time.deltaTime;
		}
		else
		{
			target = GameObject.FindGameObjectsWithTag("Monster");
			Attack (target[0]);
			Debug.Log (name + " has ended their turn.");
			action_bar = 100f;
		}
	}
	
	//functions
	void Attack(GameObject target)
	{
		string target_name = target.GetComponent("MonsterAI").name;
		Debug.Log (name + " attacks " + target_name + ".");
	}
}

Everything in the attack function was what was given to me in the answers section (Answer Link) albeit with a view changes to the names of variables.
It is returning the name “Monster” which is the name of the object, not the string stored in the variable “name”.
Thank you for your time.

Try Changing the variable target to a different name in the attack function…

    //functions

    void Attack(GameObject localTarget)

    {

        string target_name = localTarget.GetComponent("MonsterAI").name;

        Debug.Log (name + " attacks " + target_name + ".");

    }

you have used the variable name target twice…

Tried that just to be sure and it didn’t change anything, but it shouldn’t have. The variable “target” is used in both the Update() and Attack() functions, but is contained within the scope of each function. I am new to Unity so if I am wrong, please correct me.

It’s probably not a good idea to use “name” because it’s used by gameobject, etc. Try _name or something. Also, the script reference recommends the type without the parenthesis GetComponent(MonsterAI)._name. You can use the parenthesis, but it’s supposedly not as fast.

Don’t use strings in GetComponent. Also, in C# you need to cast to the correct type (or use the generic version) since otherwise you get Component.

–Eric

When I just used (MonsterAI) in stead of (“MonsterAI”) I got a compiler error. Also I am afraid I don’t understand what you mean when you say “cast the correct type”. Any chance you could throw me out a quick example code of what you mean?

Edit: I changed the variable to “mname” and removed the string from GetComponent, so now the code is:

	void Attack(GameObject target)
	{
		string target_name = target.GetComponent(MonsterAI).mname;
		Debug.Log (mname + " attacks " + target_name + ".");
	}

The errors I am getting are:
Assets/Scripts/MonsterAI.cs(40,58): error CS0119: Expression denotes a type', where a variable’, value' or method group’ was expected

Assets/Scripts/MonsterAI.cs(40,45): error CS1502: The best overloaded method match for `UnityEngine.GameObject.GetComponent(System.Type)’ has some invalid arguments

Assets/Scripts/MonsterAI.cs(40,45): error CS1503: Argument #1' cannot convert object’ expression to type `System.Type’

GetComponent(typeof(MonsterAI)) as MonsterAI
GetComponent()

You mean quotation marks…parentheses are these: ( ). Not being as fast is only one of the problems though; you should pretty much never use quotes.

–Eric

So how should I write this then?

string target_name = target.GetComponent(typeof(MonsterAI), MonsterAI).mname;

I am still confused. Once again, very new to this. My first project in fact.

Try this

        void Attack(GameObject target)
        {
            
             // - NO - string target_name = target.GetComponent(MonsterAI).mname;
            //Assuming that MonsterAI has a variable called mname
            string target_name = target.GetComponent<MonsterAI>().mname;
            Debug.Log (mname + " attacks " + target_name + ".");
        }

If you’re trying to get the ‘name’ of the object as you have it in the scene, try transform.name

So using GetComponent().mname worked. Why is it that it wouldn’t work with parenthesis? Is there a way to do it using parenthesis?

Parenthesis are for javascript, but the script reference didn’t even recommend it for that. I think it’s kind of deprecated. Someone gave you javascript code by mistake or something.

As Eric5h5 pointed out above, I believe something like this would also work?

(not tested)

            void Attack(GameObject target)
            {
               
                 // - NO - string target_name = target.GetComponent(MonsterAI).mname;
                //Assuming that MonsterAI has a variable called mname
MonsterAI mai = target.GetComponent(typeof(MonsterAI)) as MonsterAI;

                //string target_name = target.GetComponent<MonsterAI>().mname;
string target_name = mai.mname;
                Debug.Log (mname + " attacks " + target_name + ".");
            }

The current docs seem to be broken on this subject, but the unity3 docs have it:

GetComponent. () : T

Weird. Guess it is just strange to me that you would use these “<>” in stead of these “()”. Does it signify something? I know they wouldn’t just make it use a different syntax for no reason. Is there anything else that uses that same syntax?

I think it might be a good idea to do some general C# tutorials, so you can learn about generics, casting, etc. A lot of stuff in Unity will be less confusing if you have that knowledge first.

–Eric

May be a good idea. I am a year two student so we are just starting to get into more of this stuff. Thanks everyone!