Set variable on Instantiated object from a collider which isn't connected - possible?

Hey guys, so I’ve got a conundrum for you, which might be (I’m hoping!) an easy fix.

If you can imagine, a series of see-saw like mechanisms which are sitting on the ground, secured by hinge joints. On the end closer to the camera, is an empty GameObject with a rigidbody and a box collider, which responds to a mouse click by applying force downward, thereby causing the other end of the see-saw to raise up into the air.

At the opposite end of the see-saw, is another GameObject with a trigger collider, and OnExit applies a velocity to a collider attached to another rigidbody (a rock; more on this below).

From camera right, rolls in a rock (the other rigidbody from above), which is currently being moved by MovePosition and has a Z movement constraint set on it so that it doesn’t roll away from the boards. Now, what I’m trying to do is click the closer-to-camera GameObject sitting atop the see-saw when the rock is rolling over the other end, and have it launch forward and stop all movement once it hits the ground. I’ve gotten this mechanic to sort of work, but there is a major caveat:

I need to send a message through the clicked GameObject to tell the ExitTrigger it’s ok to launch the rock (rather than ignore it, which is the default behavior). I also need to tell the Rock to stop it’s MovePosition loop and also free it’s movement constraints, so it can be fully affected by the velocity applied from both the see-saw as well as the ExitTrigger.

I’ve tried SendMessage, as well as using GetComponent to set a variable in the script, but it seems to be setting them globally, which affects subsequently spawned rocks in the same way.

Is there an easy way to Instantiate multiple objects, and set variables on just one of those objects from a collider that isn’t connected to the object in any meaningful, hierarchical, way? I hope that makes sense… I’ve been wracking my brain with this since lunch. I am not a professional coder, so if there’s an easy and obvious way to do this programmaticly (through classes, etc) that I’m not aware of, please be gentile :slight_smile:

ok, for this, you need to provide us with 2 scripts, the one that controls the game object. We are most interested in the one that controls clicking and giving the order to drop a rock, the second is the rock controller. I believe we need the whole script on that one. If the rock it’s self has a script, we need that one too.

A sample web scene would do great if you have one. I am thinking that it is an issue with hierarchy and using SendMessageUpwards or something like that.

Hey! Sorry for taking so long to get back. I very much appreciate the response (and the time investment!)

I’ve simplified the scene to exemplify my problem specifically, and I’ve also uploaded a web player as requested:

http://web.me.com/sophoro/

To recap: I’m trying to pass variables to scripts on instantiated objects that aren’t directly attached (i.e. telling an recently spawned rock object that it can stop it’s motion on the X by way of an FixedUpdate function on an unrelated object.) I hope that makes sense. :slight_smile:

I’ve commented out most of the messaging code I’ve been working with; it’s current iteration, anyway.

The scene hierarchy consists of:

  • SeeSaw

  • ClickTrigger

  • ExitTrigger

  • Fulcrum

  • Rock

  • Ground Plane

  • RockSpawnRight

There is a “master” script attached to the main camera:

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
	
	public static GameManager SP;
	
	private GameObject rockHolder;
	private GameObject rockSpawnPoint;
	private GameObject boardObject;
	private float secsSpawn;
	public Board boardHasFired;
	public Rock rockHasMotion;
	
	void Awake () {
		SP = this;
	}
	
	// Use this for initialization
	void Start () {
		
		rockHolder = GameObject.Find("Rock");
		rockSpawnPoint = GameObject.Find("RockSpawnRight");
		boardObject = GameObject.Find("SeeSaw");
		
		//boardHasFired = boardObject.GetComponent<Board>();
		//rockHasMotion = rockHolder.GetComponent<Rock>();


		secsSpawn = Random.Range(1,5);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	
	void FixedUpdate () {
		
		if (secsSpawn <= 0) {
			GameObject rock = Instantiate(rockHolder, rockSpawnPoint.transform.position, rockSpawnPoint.transform.rotation) as GameObject;
			Destroy(rock, 15.0f);
			secsSpawn = Random.Range(1, 5);
			Debug.Log(secsSpawn);
		} else {
			secsSpawn -= Time.deltaTime;
		}
	}
		
}

The ClickTrigger is an empty GameObject which sits atop the closer (to the camera) end of the SeeSaw. It has a rigidbody, a box collider and a script attached:

using UnityEngine;
using System.Collections;

public class ClickTrigger : MonoBehaviour {
	
	public float forceStrength = 20.0f;
	private bool applyForce = false;
	
	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		
	}
	
	void OnMouseOver() {
		
		if (Input.GetMouseButtonDown(0)) {
			applyForce = true;	
		} else {
			applyForce = false;	
		}
		
	}
	
	void OnMouseExit() {
		applyForce = false;	
	}
	
	void FixedUpdate() {
		if (applyForce) {
			
			rigidbody.AddForce(new Vector3(0,-1,0) * forceStrength, ForceMode.Impulse);
			
			//GameManager.SP.boardHasFired.hasFired = true;
		}
	}
	
}

The ExitTrigger is another empty GameObject, sitting on the opposite end of the SeeSaw. It contains a box collider set as a trigger, and has this script attached:

using UnityEngine;
using System.Collections;

public class ExitTrigger : MonoBehaviour {
		
	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnTriggerExit(Collider collider) {
	
//		if ((collider.tag == "Rock")  (GameManager.SP.boardHasFired.hasFired == true)) {
		if (collider.tag == "Rock") {
			collider.rigidbody.constraints = RigidbodyConstraints.None;
			//GameManager.SP.rockHasMotion.motion = false;
			//GameManager.SP.boardHasFired.hasFired = false;
			collider.rigidbody.velocity = new Vector3(Random.Range(-10,10), collider.rigidbody.velocity.y * 1.0f, -20.0f);
		}
		
	}
	
}

The RockSpawn object is an empty GameObject, and just acts as a translate to point for Instantiated Rocks.

This is the script attached to Rock objects:

using UnityEngine;
using System.Collections;

public class Rock : MonoBehaviour {

	public Vector3 speed = new Vector3(5,5,0);
	public bool motion = true;
	public bool rockLaunched = false;
	
	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void FixedUpdate () {
	
		if (motion == true) {
			rigidbody.MovePosition(rigidbody.position + speed * Time.deltaTime);
		} 
		
	}
	
}

And finally, there is another trigger collider sitting above the ground plane, with this script attached:

using UnityEngine;
using System.Collections;

public class HaltMotion : MonoBehaviour {
		
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnTriggerEnter(Collider collider) {
	
		collider.rigidbody.velocity = new Vector3(0, 0, 0);
		collider.rigidbody.useGravity = false;
		
		collider.gameObject.GetComponent<Rock>().motion = false;
						
	}
	
}

Thanks again in advance for any advice, comments, complaints, flogging, etc.!

Any ideas? Am I approaching this all wrong, should I be approaching this in a different way, maybe?