I want to have an object in a scene but I don’t want to load it, or rid of it in the scene. Bassically I have a code that brings over an object to a second scene, and that works fine. But as soon as I get back in the previous scene, it reloads the thing. How can I solve this?
Maybe tag the object, and when new level is loaded see if there’s another object with the same tag. Then just figure out which one is original, and delete others. Maybe something like this:
// may not compile, writing out of my mind
// tag the object with "Player"
public class Player: MonoBehaviour {
bool trueOne = false;
void Awake() {
GameObject[] players = FindGameObjectsWithTag("Player");
// if there are more than 1 players, then we know that we have more than we need
// so find the original one
if (players.Length > 1) {
foreach (GameObject player in players) {
if (player.GetComponent<Player>().trueOne == false) {
Destroy(player);
}
}
} else {
trueOne = true; // only first one is true one
}
}
}
I guess you could combine this with OnLevelWasLoaded(), to actually mark good objects from those that need to be deleted.
I get the following errors:
Assets/Irc/scripts/Irc.cs(64,36): error CS0309: The type Irc' must be convertible to
UnityEngine.Component’ in order to use it as parameter T' in the generic type or method
UnityEngine.GameObject.GetComponent()'(Irc is instead of player)
Assets/Irc/scripts/Irc.cs(65,33): error CS0103: The name `Destroy’ does not exist in the current context
I have no idea how to fix that, since i am very new to unity
Please help:(
Here’s the whole script. Put it into EnsureSingleInstance.cs script, and add to object you want to have only one instance. Then assign unique id to it. There’s probably a better way to do some things, but that’s a quick hack I came up with.
using UnityEngine;
using System;
using System.Collections.Generic;
public class EnsureSingleInstance: MonoBehaviour {
public string uniqueId = "change me";
bool originalOne = false;
void Awake() {
// Find all objects with this script
UnityEngine.Object[] objects = GameObject.FindObjectsOfType(typeof(EnsureSingleInstance));
int count = 0;
// Find all objects tagged with our uniqueId
List<EnsureSingleInstance> clones = new List<EnsureSingleInstance>();
foreach (UnityEngine.Object o in objects) {
EnsureSingleInstance instance = o as EnsureSingleInstance;
if (instance.uniqueId == uniqueId) {
clones.Add(instance);
++count;
}
}
// If there's only one copy, then we are original one, otherwise we have clones
// and need to clean up
if (count > 1) {
foreach (EnsureSingleInstance clone in clones) {
if (clone.originalOne != true) {
Debug.Log("Destroying: " + clone.gameObject);
Destroy(clone.gameObject);
}
}
} else {
originalOne = true;
}
}
}
I usually handle this with a singleton like approach such as…
public class MyUniqueObject : MonoBehavior
{
static MyUniqueObject _instance = null;
public static MyUniqueObject Instance {
get {
if (_instance == null){
_instance = SpawnNewMyUniqueObject();
}
return _instance;
}
}
void Awake () {
DontDestroyOnLoad(this);
}
static MyUniqueObject SpawnNewMyUniqueObject(){
MyUniqueObject = (Resources.Load("PathTo/MyUniqueObject Prefab") as GameObject).GetComponent<MyUniqueObject>();
}
}
Basically the idea is that no scene actually has the object at load. However, as soon as you reference the object (via MyUniqueObject.Instance) it:
- Checks to see if you have already spawned this object (and _instance is no longer null), if not - spawns a new one
- Returns the singular _instance of the object.
Note: Quick-scripted from memory, obviously could contain errors/be incomplete - but it should give you the general idea.
Thanks alot, this one did the trick!