Accesing components on multiple objects in c#?

Hi there.

What I’m trying to do is to have triggers in the scene that will allow the player to rotate the camera around him, only when he is inside one of those objects colliders.

I have multiple object that all have the same script attached (in this instance named RotateArea.cs).

And I want to access all those objects from another objects script component (CameraRotator.cs).

Is there a way in Unity to access all of those at the same time? I’m currently using FindGameObjectWithTag, as it gets an error as soon as I use FindGameObjectsWithTag. Appearently I can’t use .GetComponent after a FindGameObjectsWithTag.

What to do?

CameraRotator

using UnityEngine;
using System.Collections;

public class CameraRotator : MonoBehaviour 
{
	public float rotateTime = 1.0f;
	
	private bool _isTweening = false;
	private CrunchPlatformColliders _cruncher;
	private DisablePlayer _disablePlayer;
	RotateArea rotateFunction;
	
	void Start () 
	{
		_cruncher = GetComponentInChildren<CrunchPlatformColliders>();
		GameObject player = GameObject.FindGameObjectWithTag("Player");
		_disablePlayer = player.GetComponentInChildren<DisablePlayer>();
		rotateFunction = GameObject.FindGameObjectWithTag("rotateZone").GetComponent<RotateArea>();
	}
	
	

	void Update(){
		if(rotateFunction.isInRotateZone)
		{
			if (Input.GetKeyDown(KeyCode.Z))
			{
				rotateTween(90);
			}
			
			if (Input.GetKeyDown(KeyCode.X))
			{
				rotateTween(-90);
			}
		}
	}

	private void rotateTween(float amount) 
	{
		if (_isTweening == false) 
		{
			_isTweening = true;
//			_cruncher.setPlayerPos();
			_disablePlayer.disable();
			Vector3 rot = new Vector3(0,amount, 0);
			iTween.RotateAdd(gameObject, iTween.Hash(iT.RotateAdd.time, rotateTime, iT.RotateAdd.amount, rot, iT.RotateAdd.easetype, iTween.EaseType.easeInOutSine, iT.RotateAdd.oncomplete, "onColorTweenComplete"));
		}
	}
	
	private void onColorTweenComplete()
	{
		_isTweening = false;
		_disablePlayer.enable();
		_cruncher = GetComponentInChildren<CrunchPlatformColliders>();
		//_cruncher.crunchCollidersToPlayer();
	}
}

RotateArea

using UnityEngine;
using System.Collections;

public class RotateArea : MonoBehaviour {

public bool isInRotateZone = false;
public GUIText referencetotext;


	// Use this for initialization
	void OnTriggerEnter ()
	{
		isInRotateZone = true;
		referencetotext.text ="Press Z or X to change lane";
	}
	

	void OnTriggerExit()
	{
		isInRotateZone = false;
		referencetotext.text ="";
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

Any help is appreciated

Let me write about your problem in general first. The way you are approaching this problem is down toward the bottom of the list of my choices. So if you can define the zone as a distance from a point, my first choice would be to have both RotateArea and CameraRotator use distance from a point to do its calculations.

Second choice would be to put OnTriggerEnter() and OnTriggerExit() on the player. This could could check for the kind of object (tag), and then set a flag. Your camera script could then read the information from the player.

My third choice would be to use Events and Delegates and have the RotateAreas communicate to the CameraRotator script. Here is a link for more info on Events and Delegates:

[How do Delegates and Events work? - Unity Answers][1]

So here is a specific answer to your question:

At the top of the file:

RotateArea[] ras;

In Start():

GameObject[] gos = GameObject.FindGameObjectsWithTag("rotateZone");
ras = new RotateArea[gos.Length];
for(int i = 0; i < gos.Length; i++) {
    ras _= gos*.GetComponent<RotateArea>();*_

}
At the end of Start() you will have an array of references to all of your RotateAreas. So in the body of your script you can add this function:
bool CanRotate() {
foreach (RotateArea ra in ras) {
if (ra.isInRotateZone)
return true;
}
return false;
}

Just call this function when you want to determine if you should be able to rotate or not.
_*[1]: http://answers.unity3d.com/questions/600416/how-do-delegates-and-events-work.html*_

this is C#. sadly I don’t really know UnityScript so you may need someone to translate this to js :wink:

In your RotateArea script you can declare a static variable such as

public static List<RotateArea> areas = new List<RotateArea>();

then in RotateArea.Awake() you will get this:

if(!RotateArea.areas.Contains(this));
    RotateArea.areas.Add(this);

then in any other script you can access RotateArea.areas and know about all the currently existing rotate areas

to do this cleanly you will need to have an OnDestroy function in RotateArea that handles the deletion of the object:

void OnDestroy(){ RotateArea.areas.Remove(this); }

I like this method because it is contained within the RotateArea script and allows more generic access of these objects without ever resorting to Find functions.

Also Events can be a problem because when you use event listeners it becomes very difficult to debug, you can’t really see what objects are listening to what events of what other objects and this way your code becomes fairly unclear.