You need a script or a prefab to know about a certain object in the scene. right?
Whenever you find yourself in this situation you must revise your approach. Keep in mind:
You can't assign a reference of an object from a scene to a prefab. That's basically impossible. prefabs aren't supposed to know about the scene.
You can assign a reference of an object from a scene to another object from the same scene.
You can assign a reference of an object from (or within) a prefab to any object (either to another prefab or same prefab or within a prefab or to an object in the scene)
In other words:
you can drag and drop anything anywhere except for from scene to prefab
Alternative?
There are many.
Why not try singleton pattern? It's easy to learn and easy to use. It's impeccable with objects which only have one instance. Like a GameController or GuiController or a UserProfileController etc.
Having a singleton GuiController:
public class GuiController : MonoBehaviour
{
//singleton setup
static GuiController instance;
void Awake() { instance = this; }
//now it's ready for static calls
public UnityEngine.UI.Text MyText;
//static method which you can call from anywhere
public static void SetMyText(string txt) { instance.MyText.text = txt; }
}
Have an object in the scene (better be the canvas). attach this script to it. Set the reference of My Text in it. In your collisions script just call GuiController.SetMyText("Score : " + score)
Edit
There is actually a slight mistake with your Collision script.
the field score which is defined in Collisions resets to 0 in the new object every time a game object with this script is being instantiated. This happens because score is not defined as a static member of Collisions and any new object naturally has its own members i.e. a new score. In fact, it shouldn't be in Collisions it is better to have a GameController script handling these kinds of data.
Again with the singleton pattern:
public class GameController : MonoBehaviour
{
static GameController instance;
void Awake() { instance = this; }
float score;
public static float Score { get { return instance.score; } set { instance.score = value; } }
}
Attach the script to a game object and instead of score++ you can write GameController.Score++;
Destroy(gameObject);, which is why it doesn't get to thescoreText.text = ..line anymore. Can you add aDebug.Log("Score changed to " + score);line after chaning the score and watching the debug log output to confirm this? And second:public Text scoreText;initializes the variable tonull, so there is actually nothing to write to. You have to create a newTextobject somewhere and add it to a canvas. Or is thescoreTextsupposed to be a static element in the scene?scoreTextis always null inside theCollisionsscript. Now where is thatscoreTextsupposed to come from? My guess is that it is a global object in the scene. Then you should find thatGameObjectin the scene withvar go = GameObject.Find("someName");and then get theTextcomponent of that withvar scoreText = go.GetComponent<Text>();. And then you can edit the.textof that foundscoreTextobject.