Let's say that I have three simple box-like objects and I want to make different compositions by adding to the first object, already present in the scene, another one and then the other in whatever order i want by pressing a specific key on the keyboard (let's say W key for the Object 2 and S key for the Object 3).
For example:
After that I would like to delete the last present object every time I want by pressing Q key.
For example, I press W,W,S,W,S (Obj2, Obj2, Obj3, Obj2, Obj3).
After, I press Q three times (obtaining the composition Obj2, Obj2 because i destroyed the last three with Q).
And after that I press W one time (obtaining Obj2, Obj2, Obj2).
The modular part is made by a script put in an Empty GameObject(which is inside the Objects 1, 2 and 3.
public class Placement : MonoBehaviour
{
public GameObject shape1, shape2, shape3;
public Counter count;
void Start()
{
count = FindObjectOfType<Counter>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
count.Array[count.i] = Instantiate(shape3, transform.position, transform.rotation);
this.enabled = false;
}
if (Input.GetKeyDown(KeyCode.S))
{
count.Array[count.i] = Instantiate(shape2, transform.position, transform.rotation);
this.enabled = false;
}
if (Input.GetKeyDown(KeyCode.Alpha6))
{
Destroy(count.Array[count.i]);
count.i = count.i - 1;
}
}
Then I used a counter and a GameObject array to "save" each clone put in the scene in another generic script always present in the scene.
public class Counter : MonoBehaviour
{
public int i = 0;
public GameObject[] Array = new GameObject[50];
public void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
i = i 1;
}
if (Input.GetKeyDown(KeyCode.S))
{
i = i 1;
}
}
}
The problems are:
- The first script is "reloaded" each time because it's inside every instantiated object I put in the scene, so I have to use an external single script where I save every counter and/or GameObject reference I need;
- If I remove this.enabled = false; from every Instantiate process the script partially works but it creates too many clones of the same object(because it's using every Empty GameObject in the scene as reference to where to put the clones and not just the last one present);
- By creating too many clones(even if I press W/S one single time), if I try to destroy the last one, it will destroy many others and if I try to put others after the destroying process, it will clone the object in every position available and not the last one.
I'm starting to lose my mind in a dumb process.... :')
CodePudding user response:
Use one empty game object as
ObjectSpawnManager
to manage your object spawn/despawn behaviour, put the first script to this object, so that you don't need put the same script on multiple instances.Remove the
Update
part ofCounter
script, add publicUpdateCounter
method, and call it fromObjectSpawnManager
script when the corresponding key down.
CodePudding user response:
Since you have stated a few problems and no specific questions, I am going to propose to you an approach that should work and implement what you ask for. If you want clarification on a specific question, feel free to ask.
As you have stated yourself, it makes more sense to have a single script manage the whole process of placing objects. Attach this script, let's call it SpawnManagerScript
to an empty GameObject
e.g. SpawnManager
in the scene.
I would also suggest you to use a List
instead of an array if you are not sure how many objects will be there at some point in time. If you do want to limit the number of objects to 50 (looking at your code), an array is totally fine.
Assuming you were able to figure out the correct positioning of the objects upon spawning already, I won't go into detail regarding that.
If I understood you correctly, what's left to do now is the following:
Spawning
GameObject
: Differentiate the user input (e.g.S
&W
) in yourSpawnManagerScript
. For each type of object you could have apublic
field in yourSpawnManagerScript
class which references e.g. a Prefab or templateGameObject
in the scene. You can use the template object for cloning on user input. Add this clone to theList
or array of objects and position it correctly.Deleting
GameObject
: Again, detect your desired input key for deletion in the script. Grab the last element in theList
or the last added element in the array from the respective container. Destroy it or set it to inactive. Remove the entry from the container.