- Home /
How do I make a general script that uses an unknown object?
I'm not completely sure if this is possible, but I'm making a puzzle game, and want a general script that I can assign an object to a public variable, then put that script on some toggled object, like a door that will be opened when a lever is pressed. ex: Put the script on a door, attach a lever to the script in the object, then put the same script on a different door, and attach a different lever to the script in that object. Will that work, or is there a different method that will have the same result?
Answer by KittenSnipes · Feb 02, 2018 at 02:31 AM
This is a script that can contain as many doors and switches as you want. Each element of the list can hold one door and multiple switches. So hopefully it works for you all having troubles. Cheers:
Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorActivator : MonoBehaviour {
//Call the class holding the door and switches
public List<ActivateDoor> activators;
// Use this for initialization
void Start () {
//Setting up our status holders
for (int i = 0; i < activators.Count; i++)
{
activators[i].activatedSwitches = new Dictionary<string, bool>();
}
}
// Update is called once per frame
void Update () {
//Loop through the activators
for (int i = 0; i < activators.Count; i++)
{
//If our switches are all activated
if (activators[i].activatedSwitches.Count == activators[i].switches.Count)
//Loop through the activated switches in the current activator element
for (int j = 0; j < activators[i].activatedSwitches.Count; j++)
{
//Then loop through all the switches
for (int k = 0; k < activators[i].switches.Count; k++)
{
//We double check to see if our switches are true
if (activators[i].activatedSwitches[activators[i].switches[k].name] == true)
{
//And if they are then activate our door.
activators[i].door.SetActive(true);
}
}
}
}
}
private void OnTriggerEnter(Collider other)
{
//Go through each activator created in the editor
for (int i = 0; i < activators.Count; i++)
{
//Go through each switch in each element of the activators
for (int j = 0; j < activators[i].switches.Count; j++)
{
//If the other object that we interacted with is one of our switches
//and our list does not already have it then set it
//as activated. Meaning add it to the activatedSwitches list.
if (other.gameObject == activators[i].switches[j]
&& !(activators[i].activatedSwitches.ContainsKey(activators[i].switches[j].name)))
{
//We add the activated switch to the activator containing it and set it to true.
activators[i].activatedSwitches.Add(activators[i].switches[j].name, true);
}
}
}
}
}
[System.Serializable]
public class ActivateDoor
{
//The de-activated door object
[Header("Make sure the doors are de-activated")]
public GameObject door;
//The switches or switch to activate the door
[Header("Add Switches To This")]
public List<GameObject> switches;
//Statuses of the switches (On/Off)
[Header("These will show you which switches have been activated.")]
public Dictionary<string, bool> activatedSwitches;
}
2D Version On @Sir_Aulen Request:
Script2D:
@Sir_Aulen
using System.Collections.Generic;
using UnityEngine;
public class New : MonoBehaviour {
//Call class of door and switches
public List<ActivateDoor> activators;
public int locked;
void Start () {
//Set up status holders
for (int i = 0; i < activators.Count; i++)
{
activators[i].activatedSwitches = new Dictionary<string, bool>();
}
}
void Update () {
//Loop through the activators
for (int i = 0; i < activators.Count; i++)
{
//If our switches are all activated
if (activators[i].activatedSwitches.Count == activators[i].switches.Count)
//Loop through the activated switches in the current activator element
for (int j = 0; j < activators[i].activatedSwitches.Count; j++)
{
//Then loop through all the switches
for (int k = 0; k < activators[i].switches.Count; k++)
{
//We double check to see if our switches are true
if (activators[i].activatedSwitches[activators[i].switches[k].name] == true)
{
//And if they are then activate our door.
//Instead of having this here you can switch it to do something else for your
//door
if (locked > 1)
{
activators[i].door.GetComponent<Animator>().SetInteger("Toggled", 1);
}
//activators[i].door.SetActive(true);
//Turn off that collider
activators[i].door.GetComponent<Collider2D>().enabled = false;
}
}
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
//Go through each activator created in the editor
for (int i = 0; i < activators.Count; i++)
{
//Go through each switch in each element of the activators
for (int j = 0; j < activators[i].switches.Count; j++)
{
//If the other object that we interacted with is one of our switches
//and our list does not already have it then set it
//as activated. Meaning add it to the activatedSwitches list.
if (other.gameObject == activators[i].switches[j]
&& !(activators[i].activatedSwitches.ContainsKey(activators[i].switches[j].name)))
{
//We add the activated switch to the activator containing it and set it to true.
activators[i].activatedSwitches.Add(activators[i].switches[j].name, true);
}
}
}
}
private void OnTriggerExit2D(Collider2D other)
{
//Go through each activator created in the editor
for (int i = 0; i < activators.Count; i++)
{
//Go through each switch in each element of the activators
for (int j = 0; j < activators[i].switches.Count; j++)
{
//If the other object that we interacted with is one of our switches
//and our list does not already have it then set it
//as activated. Meaning add it to the activatedSwitches list.
if (other.gameObject == activators[i].switches[j]
&& !(activators[i].activatedSwitches.ContainsKey(activators[i].switches[j].name)))
{
//We add the activated switch to the activator containing it and set it to true.
activators[i].activatedSwitches.Add(activators[i].switches[j].name, false);
if (locked > 1)
{
activators[i].door.GetComponent<Animator>().SetInteger("Toggled", 0);
activators[i].door.GetComponent<Collide2D>().enabled = true;
}
}
}
}
}
}
[System.Serializable]
public class ActivateDoor
{
//You can add any gameObject including 2d ones
[Header("Make sure the doors are de-activated")]
public GameObject door;
//This can hold any amount of gameObjects even 2D ones
[Header("Add Switches To This")]
public List<GameObject> switches;
//Statuses of the switches (On/Off)
[Header("These will show you which switches have been activated.")]
public Dictionary<string, bool> activatedSwitches;
}
Yes, I know that, that parts working :). You know how you can modify public variables inside the unity engine, and have multiple scripts running with slightly different numbers? And then also attach different objects to variables that way? I'm trying to write a script that lets me have different levers toggle different objects, just with one script. I've tried a couple things, but they didn't work because it wasnt a specific object
Oh well how about ins$$anonymous$$d you can create a list to hold gameobjects of a certain tag. Less intensive that way. Then you can use a for loop to loop through all of them and do what you need. The random part you can use:
Random.Range($$anonymous$$inimum Number, $$anonymous$$aximum Number);
It matters what variable you want to randomly assign to them
I'm not randomly assigning variables, its a puzzle game, so i have different levers affecting different objects, so I'm not sure if it would work to have different tags. I also need to check a variable held by the lever, if that affects anything
Here is a working script. Have fun with it and I hope it helps. Cheers!
Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorActivator : $$anonymous$$onoBehaviour {
public List<ActivateDoor> activators;
// Use this for initialization
void Start () {
for (int i = 0; i < activators.Count; i++)
{
activators[i].activatedSwitches = new Dictionary<string, bool>();
}
}
// Update is called once per frame
void Update () {
for (int i = 0; i < activators.Count; i++)
{
if (activators[i].activatedSwitches.Count == activators[i].switches.Count)
for (int j = 0; j < activators[i].activatedSwitches.Count; j++)
{
for (int k = 0; k < activators[i].switches.Count; k++)
{
if (activators[i].activatedSwitches[activators[i].switches[k].name] == true)
{
activators[i].door.SetActive(true);
}
}
}
}
}
private void OnTriggerEnter(Collider other)
{
for (int i = 0; i < activators.Count; i++)
{
for (int j = 0; j < activators[i].switches.Count; j++)
{
if (other.gameObject == activators[i].switches[j]
&& !(activators[i].activatedSwitches.Contains$$anonymous$$ey(activators[i].switches[j].name)))
{
activators[i].activatedSwitches.Add(activators[i].switches[j].name, true);
}
}
}
}
}
[System.Serializable]
public class ActivateDoor
{
[Header("$$anonymous$$ake sure the doors are de-activated")]
public GameObject door;
[Header("Add Switches To This")]
public List<GameObject> switches;
[Header("These will show you which switches have been activated.")]
public Dictionary<string, bool> activatedSwitches;
}
Would this script go under the player character? What I think i understand the code does, is check if you collide with a switch, and then add that to an active group? I'm not really sure how to use this, I'm somewhat new to unity/c++ code
$$anonymous$$y answer above is fixed so it has comments of what everything does. Yes you would want to add it to your character.
Sorry, I should have made some things clear about my game; 1) (I dont think this matters) But im in 2D, and 2) I have it so that if you walk towards an unlocked door, it does an open animation, then closes when you get far enough away, and 3) The switches are switches, not 1-time buttons, so i can turn them on and off. I was hoping to have the doors locked if the switch is off, and act like a normal door when the switch is on.
Also, for future reference, rather than manually changing the transform to 0, you can just click the cog in the corner and go to "reset"