calling functions in many objects w/ FindGameObjectsWithTag

i’m trying to make a script that will smoothly change the color of many environment objects based on the character’s state. at first i had implemented this idea as an update loop running in every environment object, but i realized that could get very expensive and messy. now instead i’m trying to call the right function in every object from one script as needed instead of making the update loop run through a whole mass of redundant if statements for every object.

here’s the script attatched to the character, which monitors the character’s state and should theoretically call the function on the environment object scripts:

using UnityEngine;
using System.Collections;

public class XashState : MonoBehaviour {

	private NormalCharacterMotor character;
	GameObject[] environmentFunkyObjects;
	FunkyColor funkyScript;
	
	// Use this for initialization
	void Start () {
		character = GameObject.FindWithTag("Player").GetComponent(typeof(NormalCharacterMotor)) as NormalCharacterMotor;
		environmentFunkyObjects = GameObject.FindGameObjectsWithTag("EnvironmentFunkyObject");
		foreach (GameObject environmentFunkyObject in environmentFunkyObjects) {
			funkyScript = environmentFunkyObject.GetComponent(typeof(FunkyColor)) as FunkyColor;
		}
	}
	
	void FunkyColorUpdater() {
		
		if (character.grounded) {
			foreach (GameObject environmentFunkyObject in environmentFunkyObjects) {
				funkyScript.GroundedLerp();
			}
		}
		else if (character.jumpCount == 3) {
			foreach (GameObject environmentFunkyObject in environmentFunkyObjects) {
				funkyScript.TripleJumpLerp();
			}
		}
		else {
			foreach (GameObject environmentFunkyObject in environmentFunkyObjects) {
				funkyScript.AirLerp();
			}
		}
	}
	
	// Update is called once per frame
	void Update () {
		FunkyColorUpdater();
	}
}

here’s the script attached to the environment objects:

using UnityEngine;
using System.Collections;

public class FunkyColor : MonoBehaviour {

	public Color groundedColor;
	public Color airColor;
	public Color tripleJumpColor;
	public float groundLerpTime = 0.5f;
	public float airLerpTime = 0.5f;
	public float tripleLerpTime = 0.5f;
	
	bool isThisWorking = false;
	
	private NormalCharacterMotor character;
	
	// Use this for initialization
	void Start () {
		character = GameObject.FindWithTag("Player").GetComponent(typeof(NormalCharacterMotor)) as NormalCharacterMotor;
	}
	
	public void GroundedLerp() {
		renderer.material.color = Color.Lerp(renderer.material.color, airColor, Time.deltaTime * groundLerpTime);
	}
	
	public void TripleJumpLerp() {
		renderer.material.color = Color.Lerp(renderer.material.color, tripleJumpColor, Time.deltaTime * tripleLerpTime);
		isThisWorking = true;
	}
	
	public void AirLerp() {
		renderer.material.color = Color.Lerp(renderer.material.color, airColor, Time.deltaTime * airLerpTime);
	}

it only seems to work on one script in the scene, though. how can i get it to call the function on all tagged objects?

you need to use the functions that look for objects not those that only look for a single object and then iterate through the resulting array. That part does not happen automatically

well, the script is successfully creating an array of all tagged game objects, but it’s only getting one instance of the script. i can kind of understand why, and i would guess the solution would be to generate another array of the script instances on the objects in Start and then iterate through that instead. but i’m not sure how i would go about doing that in Start, and as I understand it using GetComponent within the foreach statements in FunkyColorUpdater would be pretty costly so that’s out of the question. or am i not understanding what you mean… :sweat_smile:

You need an array of FunkyColor objects instead of just a single one. Rather than use a “foreach” loop, a “for” loop would probably work better here:-

FunkyColor[] funkyScripts;

void Start() {
    ...
    funkyScripts = new FunkyColor[environmentFunkyObjects.Length];

    for (int i = 0; i < funkyScripts.Length; i++) {
        funkyScripts[i] = (FunkyColor) environmentFunkyObjects[i].GetComponent("FunkyColor");
    }
    ...
}

awesome, thanks andeeee. with this i can have 60 instances of the script running at once and usually stay around 130fps in the editor (well unless all those objects are on screen being rendered of course, but that’s another matter!) whereas the way i was doing it before i had noticeable slowdown with that amount.