4

I'm working on random coin generator. I have included the code below:

timer -= Time.deltaTime;

if (timer <= 0)
{

    Vector3 position = new Vector3(Random.Range(11f, 14f), Random.Range(-0.7f, 4.5f), 0);
    Instantiate(coins, position, transform.rotation);
    timer = delayTimer;
}

and I add a collision to pick the coin and make a score text:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Collisions : MonoBehaviour {
    public  Text scoreText;
    private float score;
    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {

        scoreText.text = "Score : " + score;



    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "Player")
        {
            Destroy(gameObject);
            scoreText.text = "Score : " + score;
            score++;

        }
    }

}

so now when I need to add the Text to the prefab I can't and if I assign the text in somehow to the prefab it doesn't count any score

enter image description here

6
  • 2
    My guess: You kill your own game object and the execution of the script with the line Destroy(gameObject);, which is why it doesn't get to the scoreText.text = .. line anymore. Can you add a Debug.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 to null, so there is actually nothing to write to. You have to create a new Text object somewhere and add it to a canvas. Or is the scoreText supposed to be a static element in the scene? Commented Dec 10, 2016 at 20:00
  • when play the game i found this error NullReferenceException: Object reference not set to an instance of an object Collisions.Update () (at Assets/scripts/Collisions.cs:15) Commented Dec 10, 2016 at 20:25
  • Good, now you know that scoreText is always null inside the Collisions script. Now where is that scoreText supposed to come from? My guess is that it is a global object in the scene. Then you should find that GameObject in the scene with var go = GameObject.Find("someName"); and then get the Text component of that with var scoreText = go.GetComponent<Text>();. And then you can edit the .text of that found scoreText object. Commented Dec 10, 2016 at 20:30
  • the script call RandomCoin "the Generator " is on empty gameOpject and i made a public gameOpject in the script to assign the coin and i delete the coin after make it prefab ; in the coin prefab i add the Collisions Scripts and inside the script i made a public Text in the script to assign the text Score Ui . now the problem that i need to assign the text from prefab witch for some reason i can't .. now when i played the scene i have this error NullReferenceException: Object reference not set to an instance of an object Collisions.Update () (at Assets/scripts/Collisions.cs:15) Commented Dec 10, 2016 at 20:33
  • i don't need to assign a gameObject i just need to assign the text using the code instead of public text witch it deleted when transfer the coin to prefab Commented Dec 10, 2016 at 20:39

1 Answer 1

4

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++;

Sign up to request clarification or add additional context in comments.

10 Comments

just like that GuiController.SetMyText(Nothing Here !!)
that was the lazy version of GuiController.SetMyText("Score : " + score)
i add it but the same .. :( i get a score : 0 but it doesn't change
are you sure the line you call the static method is being executed?
and you have a gameobject in the scene with GuiController script attached, and its 'my text' field is set to a Text object in the scene?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.