Access a method from another script AND different GameObject

Hey everyone.

I use the getComponent<>() method to access other scripts successfully in this project but it doesn’t seem to work if the scripts are not attached to the same object. I’m getting a NullReferenceException every time it gets down to

nextPos = getXml.getPositionData (onSet.ToString (), myName);

What am I doing wrong here? my other script GetXML is attached to a separate gameobject. Many thanks.

using UnityEngine;
using System.Collections;

public class QuickMove : MonoBehaviour 
{
	public Vector3 currentPos;
	public Vector3 nextPos;
	public GetXML getXml;
	private int onSet = 1;
	private string myName;

	// Use this for initialization
	void Awake ()
	{
		getXml = GetComponent<GetXML> ();

	}
	void Start () 
	{
		currentPos = transform.position;
		myName = transform.name;
	}
	
	// Update is called once per frame
	void Update () 
	{

		if (Input.GetKeyDown ("2") && (onSet <= 29)) 
		{
			currentPos = transform.position;
			onSet++;
		
			nextPos = getXml.getPositionData (onSet.ToString (), myName);
			transform.position = Vector3.Lerp (currentPos, nextPos, Time.deltaTime * 3.0f);
		}
	}
}

If I am reading your question above correctly, you want your QuickMove script to access the GetXML script that is located on an object other than the one the QuickMove script is located on.

The getComponent() method returns the component of Type on the same game object as the calling script. That is why your posted code is not working correctly.

What you need is a reference to the game object that holds the GetXML component. You may want to set this with a public variable, have Awake() find it based on a tag, or maybe you’re using a singleton pattern. Whatever works for your project. Once you have a reference to this game object, you can use GetComponent from that reference.

// If you store a GameObject.
getXml = someGameObject.GetComponent<GetXML>(); 

// Or if you store a Transform.
getXml = someTransform.gameObject.GetComponent<GetXML>();

If you use GetComponent(), it tries to get this script on current GameObject. You can simply assigh GameObject with attached GetXML.cs to the inspector’s field, because you have field

public GetXML getXml;

which is visible in inspector for QuickMove script.

In this case you no need to use getXml = GetComponent ();, you can use getXml without null exceptions

Luckily I solved my problem before it got posted :slight_smile: Attaching in the inspector wasn’t working for me however, perhaps because these are prefabs instantiated by the GetXML script.

Anyways I just needed to find the parent object of GetXML.

using UnityEngine;
using System.Collections;

public class QuickMove : MonoBehaviour 
{
	public Vector3 currentPos;
	public Vector3 nextPos;
	public GetXML getXml;
	public float speed = 100;
	private int onSet = 1;
	private string myName;
	
	void Awake ()
	{
		// Find the GetXML script attached to "DataObject"
		getXml = GameObject.Find ("DataObject").GetComponent<GetXML>();
	}

	void Start () 
	{
		currentPos = transform.position;
		nextPos = transform.position;
		myName = transform.name;
	}
	

	void Update () 
	{
		PositionChanging ();
	}

	void PositionChanging()
	{
		// Lerp to nextPos when nextPos changes.
		if (Input.GetKeyDown ("2") && (onSet < 30)) 
		{
			onSet++;
			nextPos = getXml.getPositionData (onSet.ToString (), myName);
		}
		if (Input.GetKeyDown ("1") && (onSet > 1)) 
		{
			onSet--;
			nextPos = getXml.getPositionData (onSet.ToString (), myName);
		}

		// Fast in slow out.  Needs a gate on the finish to get to nextPosition still.
		transform.position = Vector3.Lerp (transform.position, nextPos, speed * Time.deltaTime * 10.0f);
	}
}

I also fixed the lerp to update every frame instead of only when keyboard input was true.