Is it possible to pick reference variables from one component, in another (different) component via the inspector?

I’ve been searching on this, and as with most questions I post, there’s probably an easy answer here that I’m just not finding or formatting my search to find.


Here’s the setup:

  • Component Script A includes:

  • public float myFloat

  • public int myInt

  • Component Script B has:

  • public {variable}

The idea being that, in the inspector I can attach Component Script B to an object, and through the inspector pick the GameObject that has Component Script A, and choose “myFloat” as the variable to reference inside of Component Script B.

Is this even possible?


Here’s what I’m trying to do:

I’d like to make a simple script that can be attached to UI text objects to auto-update their displayed text values to match that of the referenced variable value (like the above example) - but I don’t want to have to write a lot of small scripts to find and make these references at run time (which I already know how to do).

So - with that intention, perhaps there’s a different way to accomplish this?

Per the usual, everyone here is awesome and I appreciate any input/help/guidance that could be provided - thanks!

There is another solution you can use!
@Glurth method is ok, but you are coupling your classes in that way.

The way to accomplish that without boilerplate code is… Scriptable Objects!

ScriptableObjects are like monobehaviours, without being GameObjects haha!

You can create an instance of a class inside the assets folder,

and use that instance in your classes as a draggable value in the inspector,

then you will be using the same instance of the shared variable.

Both classes are using the SAME instance that contains the variable.

In fact you can create events for variable changes!

You just need to create a ScriptableObject called “SharedFloat” (for example)
it should have a float variable types to share!

using System;
using UnityEngine;

[CreateAssetMenu]
public class SharedFloat : ScriptableObject
{
	//You need to asign an initial and current values, because
	//scriptable objects doesnt reset their state on application quit
	[SerializeField] float initialValue, currentValue;

	//The public property to access to operate with the current value
	public float Value
	{
		get => currentValue;
		set
		{
			//if new value is different to the old one then set that value to the currentValue
			//and execute all functions subscribed to the OnValueChanged event
			if (value != currentValue)
			{
				currentValue = value;
				OnValueChanged();
			}
		}
	}

	//the event that is called on when current value is changed
	public event Action OnValueChanged;


	//here is where the current value copy initial value on start
	private void OnEnable() => currentValue = initialValue;
}

[147532-sf.png|147532]


Then in the Player and HealthUI Scripts
you can do this!

//The Script attached to the player
public class PlayerTest : MonoBehaviour
{
	public SharedFloat Health;

	//when player gets damage
	public void GetDamage(float damage) => Health.Value -= damage;
}


//The Script attached to the UI
public class HPBarTest : MonoBehaviour
{
	public SharedFloat Health;

	//Subscribe to OnValueChanged at the begining
	private void Awake() => Health.OnValueChanged += UpdateHPUI;

	void UpdateHPUI()
	{
		//Do everything what you want here
	}
}

Boom!
You have now Reactive Shared Variables!

Uncompiled example (may contain errors, example only):

public class ScriptA:Monobehavior
{
   public float Anum;
}
public Class ScriptB:Monobehavior
{
   public ScriptA  Aref;  //this public varaiable, allows you to drag an object with a ScriptA component, onto this field, in the inspetcor.
   public float copyOfANum;
   void Start()
   {
      if(Aref!=null)
         copyOfANum= Aref.Anum;  //after confirming the user HAS indeed provided a reference to a ScriptA component, we can look "into" it, with the "." (dot), to get the number we want.
   }
}

There is another solution you can use!
@Glurth method is ok, but you are coupling your classes in that way.

The way to accomplish that without boilerplate code is… Scriptable Objects!

ScriptableObjects are like monobehaviours, without being monobehaviours haha!

You can create an instance of a class inside the assets folder,

and use that instance in your classes as a draggable value in the inspector,

then you will be using the same instance of the shared variable.

Both classes are using the SAME instance that contains the variable.

In fact you can create events for variable changes!

You just need to create a ScriptableObject called “SharedFloat” (for example)
it should have a float variable types to share!

using System;
using UnityEngine;

[CreateAssetMenu]
public class SharedFloat : ScriptableObject
{
	//You need to asign an initial and current values, because
	//scriptable objects doesnt reset their state on application quit
	[SerializeField] float initialValue, currentValue;

	//The public property to access to operate with the current value
	public float Value
	{
		get => currentValue;
		set
		{
			//if new value is different to the old one then set that value to the currentValue
			//and execute all functions subscribed to the OnValueChanged event
			if (value != currentValue)
			{
				currentValue = value;
				OnValueChanged();
			}
		}
	}

	//the event that is called on when current value is changed
	public event Action OnValueChanged;


	//here is where the current value copy initial value on start
	private void OnEnable() => currentValue = initialValue;
}


Then in the Player and HealthUI Scripts
you can do this!

//The Script attached to the player
public class PlayerTest : MonoBehaviour
{
	public SharedFloat Health;

	//when player gets damage
	public void GetDamage(float damage) => Health.Value -= damage;
}


//The Script attached to the UI
public class HPBarTest : MonoBehaviour
{
	public SharedFloat Health;

	//Subscribe to OnValueChanged at the begining
	private void Awake() => Health.OnValueChanged += UpdateHPUI;

	void UpdateHPUI()
	{
		//Do everything what you want here
	}
}

Boom!
You have now Reactive Shared Variables!