My goal is to have two objects interact with eachother: a black box prefab on a conveyor belt, and another open black box off the belt. I am trying to set “blackActive” to true in the prefab when clicking on it, and that part works. Where things get muddled is when I try to send this information to my boxStateHandler script, where “scriptToAccess = boxBlackObject.GetComponent ();” finds the state of “blackActive”. Once the box handler sees that the script is active, I would like to be able to click on the box off the conveyor belt, which in turn would destroy the box on the conveyor belt, I believe there is an issue with my boxStateHandler’s destroy section. Any help would be greatly appreciated, here are the scripts:
boxBlackActive.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class boxBlackActive : MonoBehaviour {
//variable for if the box has been clicked on
public bool blackActive = false;
public int boxesActive = 0;
//when clicked, the box is set to blackActive true
void OnMouseDown(){
blackActive = true;
}
}
boxStateHandler.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class boxStateHandler : MonoBehaviour {
//gameobject for outside script
public GameObject boxBlackObject;
//variables to access outside script
private boxBlackActive scriptToAccess;
private bool booleanBlackBoxActive;
//booleans for each state that the storage box will go through during play, starts on open
public bool boxBlackOpen = true;
public bool boxBlackClosed = false;
public bool boxBlackSealed = false;
public bool boxBlackMistake = false;
public bool boxBlackSuccess = false;
//continually brings up the status of blackActive
void Update () {
scriptToAccess = boxBlackObject.GetComponent<boxBlackActive> ();
booleanBlackBoxActive = scriptToAccess.blackActive;
}
//if blackActive in the other script is true, onMouseDown over the open black box, destroy the blackBox prefab that was selected
void OnMouseDown(){
if (booleanBlackBoxActive = true) {
Destroy (boxBlackObject.gameObject);
Debug.Log ("destroy object");
//sets box active back to false so that other boxes may be used
booleanBlackBoxActive = false;
}
}
}
Edit: Ok since I can’t add it as a comment I’ll put it here.
So here’s a bit of a different approach. The main problem with your situation is that you are spawning boxes of different colors (randomly I assume) so you need to dynamically get the right reference for each of this boxes so you can destroy them from your boxStateHandler scripts.
What I suggest you to do is create an enum for your different color of boxes, so you don’t have to create a different script just to handle a box of a different color. And instead of finding references, let the boxes destroy themselves by sending them a message via an event. When they get the message they will check, “Am I ready to be destroyed?” if they are then they will be auto destroyed.
Here’s the code to do that:
I’ll change the name to boxActive.cs instead of boxBlackActive.cs since we will use it for boxes of every color.
boxActive.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum BoxColor
{
Black,
Red
//Add the colors you need here
}
public class boxBlackActive : MonoBehaviour {
//variable for if the box has been clicked on
public bool active = false;
//You would set this variable at the moment when you spawn this box
public BoxColor boxColor;
//when clicked, the box is set to blackActive true
void OnMouseDown(){
active = true;
}
//Here in on enable and disable what you are basically doing is tell this box
//to listen to the message that boxStateHandler may send
void OnEnable()
{
boxStateHandler.OnDestroyMessage += OnDestroyMessage;
}
void OnDisable()
{
boxStateHandler.OnDestroyMessage -= OnDestroyMessage;
}
void OnDestroyMessage(BoxColor color)
{
//Should I listen to this destroy message?
//I should if it is for boxes of my color only
if(color == this.boxColor)
{
//If I was clicked before then I can be destroyed
if(active)
{
Destroy(this.gameObject);
}
}
}
}
boxStateHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class boxStateHandler : MonoBehaviour {
//Set this variable in the editor
public BoxColor handlerColor;
//This is the event or message that you will be sending
public delegate void DestroyMessage(BoxColor color);
public static event DestroyMessage OnDestroyMessage;
//On click, send a destroy message
void OnMouseDown(){
if(OnDestroyMessage != null)
OnDestroyMessage();
}
}
So with this solution you don’t have to worry about boxStateHandler finding the references to the boxes, boxStateHandler will shout a message and the boxes will listen to it and react accordingly.
Notes:
There are many ways to refactor what I did here but I did it this way because I think is clearer and easier to understand.
This code will also help you when handling multiple colors so you won’t need to create extra scripts for each color.
This code will have a “secondary effect” if you click multiple boxes of the same color and then click the corresponding cardboard box it will destroy them all at once.
@MacDx So I used “if (booleanBlackBoxActive) {” and the black box on the conveyor still does not get destroyed when the box off of the conveyor is clicked, blackActive does not seem to change from false value when the box on the conveyor is clicked.