- Home /
How can I use a master script to send values to multiples objects
Hi I'm working on a strategy game that involves the use of AI entities called customers. The customers come into the restaurant and perform a multitude of randomly generated tasks before leaving. As it currently stands I can only get a single customer to act correctly. The problem is that the master script will assign a value from the MasterWaypoints array in the Customer script based on what the player chooses to upgrade. The values being assigned to the Customer script are only being sent to a single customer when they should be sent to all of the customers. Notice how the ActiveWaypoints array isn't being updated on the cloned "Customer" object.
Here are the important parts of the Master script
var waypointScript : NavigateWaypoints;
var customerObj : GameObject;
function Update() {
waypointScript = gameObject.Find("Customer").GetComponent(NavigateWaypoints);
customerObj = gameObject.FindWithTag("Player");
if (globalMoney <= -100) {
Application.LoadLevel(4);
}
}
function OnGUI(){
//Button Set 2
if (b_SubsetButtons[1] == true) {
//Table W/ Two Chairs
if(b_HideButtonSet[0] == true){
if (GUI.Button(buttonSet2Rect1, b_ButtonText[b_ButtonTextHolder]) && b_ButtonTextHolder == 0) {
waypointScript.inactiveWaypoints[12] != waypointScript.masterWaypoints[12];
waypointScript.activeWaypoints[12] = waypointScript.masterWaypoints[12];
waypointScript.inactiveWaypoints[13] != waypointScript.masterWaypoints[13];
waypointScript.activeWaypoints[13] = waypointScript.masterWaypoints[13];
globalMoney -= 40;
r_UpgradeObjects[0].SetActive(true);
b_ButtonTextHolder = 10;
b_HideButtonSet[0] = false;
}
}
//Cash Register
if(b_HideButtonSet[1] == true){
if (GUI.Button(buttonSet2Rect1, b_ButtonText[b_ButtonTextHolder]) && b_ButtonTextHolder == 10){
[highlight]Instantiate(customerObj);[/highlight]
waypointScript.inactiveWaypoints[3] != waypointScript.masterWaypoints[3];
waypointScript.activeWaypoints[3] = waypointScript.masterWaypoints[3];
if(waypointScript.currentWaypoint <= 2){
waypointScript.currentWaypoint = 3;
}
globalMoney -= 80;
b_ButtonTextHolder = 5;
r_UpgradeObjects[10].SetActive(true);
b_HideButtonSet[1] = false;
}
}
}
Ok now here are the important parts of the Customer script
var waypoint : Transform;
var currentWaypoint : int;
var agent : NavMeshAgent;
var script1 : SlideOutMenu;
var activeWaypoints : Transform[];
var inactiveWaypoints : Transform[];
var masterWaypoints : Transform[];
var startMoving = false;
var selectedMenuItem : int;
var subtractedBurgers : int;
var subtractedGlucks : int;
var subtractedBopsters : int;
function Awake(){
agent = gameObject.GetComponent.<NavMeshAgent>();
agent.speed = Random.Range(2.5, 5);
script1 = gameObject.Find("GUIElements").GetComponent(SlideOutMenu);
}
function Start(){
inactiveWaypoints[1] = masterWaypoints[1];
inactiveWaypoints[2] = masterWaypoints[2];
inactiveWaypoints[3] = masterWaypoints[3];
inactiveWaypoints[4] = masterWaypoints[4];
activeWaypoints[5] = masterWaypoints[5];
inactiveWaypoints[6] = masterWaypoints[6];
inactiveWaypoints[7] = masterWaypoints[7];
inactiveWaypoints[8] = masterWaypoints[8];
inactiveWaypoints[9] = masterWaypoints[9];
inactiveWaypoints[10] = masterWaypoints[10];
inactiveWaypoints[11] = masterWaypoints[11];
inactiveWaypoints[12] = masterWaypoints[12];
inactiveWaypoints[13] = masterWaypoints[13];
}
function Update () {
TurnOnEntity();
if(startMoving == true){
waypoint = activeWaypoints[currentWaypoint];
agent.SetDestination(waypoint.position);
}
}
function TurnOnEntity(){
if (activeWaypoints[1] == masterWaypoints[1]){
startMoving = true;
}
if (activeWaypoints[2] == masterWaypoints[2]){
startMoving = true;
}
if (activeWaypoints[3] == masterWaypoints[3]){
startMoving = true;
}
}
[1]: /storage/temp/25885-properly+functioning+customer.png
Answer by RyanZimmerman87 · Apr 29, 2014 at 05:17 AM
I'll try to take a closer look at this later tonight, gotta run to store so I just breezed through the code.
But I see one "problem" that you are using GameObject.Find() every Update() frame, this is really not a good idea for performance. You should set up all your object references in Start() or Awake() or call a single function to get the new object whenever a new customer comes.
I think it might be easier to get the customers to access the master script when they Start() that is unless their data needs to be handled in a specific order when the scene starts and there are multiple customers.
It's only working on the first customer I think because you are using GameObject.Find("Customer") for the clones you would need GameObject.Find("Customer(Clone)")
But even with the correct name it would only find one Clone and it seems like you are trying to set the data for multiple customers?
You may need to provide some more info for this.
But I think if I was determined to have the master script control all the customers instead of the customers drawing data from the master script on Start(), I would probably set up a Game Object array on the master script. I would set up a tag for the customers and also an int number variable on the customer script.
So it would be something like this:
GameObject[] customerObjectArray;
customerObjectArray = GameObject.FindGameObjectsWithTag("Customer Tag");
foreach(GameObject currentCustomerObject in customerObjectArray)
{
//get the customerID; (int)
int currentCustomerID = currentCustomerObject.GetComponent<CustomerScript>().customerID;
//x represents the logic possibilities you use to determine
//which data to send to their script
if (currentCustomerID == "x")
{
//set their logic correctly based on which customer they are
}
}
Obviously there is a lot more logic involved to make everything work correctly but that's about the best example I can do to hopefully get you started or to give you ideas if you want one master script to control all the customers.
But once again I must stress you should eliminate the customer GameObject.Find from Update()
Depending on how many customers you have you could use a Game Object array or just a series of game object variables.
For the customers that are already in the scene on Awake() you could use something like this example with the foreach()
The foreach() function would only be called in Start() or Awake() to set up the initial customers.
Then for each additional customer that joins the scene you could call a separate function (just once not every Update).
I still think it would be easier for each customer to retrieve their data from the master script in some kind of function called from within Start()
Basically what you're doing could be handled in many different ways, the most important thing is that you understand the logic so everything works bug free. So I would just take it slow and step by step work through the problem and make sure everything makes sense as you design this system.
Thank you so much for the help! I removed the GameObject.Find from Update() like you said, but it wasn't there originally. I placed it there temporarily because I was wondering why the master script wasn't detecting any clones. However it's likely that I would have forgotten about it if you didn't re$$anonymous$$d me. There is a lot of information in your answer so it will take me little while to set everything up correctly. Also I like the solution you provided for the master script to control the customers but since you said I could also have the customers access the master script on start or awake, I think that would be the better option. We'll have to see after I'm done working. Thank you again.