Atanas
Atanas

Reputation: 83

Unity communication between scripts

I'm making a Unity3D game. I want to implement a connection between the script Timer.cs and Collide.cs, by which they exchange the variable obji. And before you mark this question as a duplicate I want to mention that have already read this tutorial. As a result of the solution provided I get the error

A namespace cannot directly contain members such as fields or methods

Can you provide a solution for exchanging information between scripts that have no element in common. I want Timer.cs to get the variable obji from Collide.cs

Timer.cs

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

public class Timer : MonoBehaviour
{
    public ScoresManager ScoresManager;
    Text instruction;
    // Start is called before the first frame update
    void Start()
    {
        instruction = GetComponent<Text>();
        InvokeRepeating("time", 0, 1);

    }
    void time() {


        if (timeLeft <= 0){
        /*   if(move.obji() <= 0){
                instruction.text = "You win!";
            }else{
                instruction.text = "You lost!";
            }*/


} else {
            timeLeft = timeLeft - 1;
            instruction.text = (timeLeft).ToString();
        }
    }
    // Update is called once per frame
    int timeLeft = 30;

    void Update()
    {
    }
}

Collide.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
    public class Collide : MonoBehaviour
{
    public Text txt;
    public int obji = -1; //this is an example, I always try to initialize my variables.
    void Start()
    { //or Awake
        obji = GameObject.FindGameObjectsWithTag("Enemy").Length;
    }
    void OnCollisionEnter(Collision collision)
    {

        if (collision.collider.gameObject.tag == "Enemy")
        {

            transform.localScale -= new Vector3(0.03F, 0.03F, 0.03F);


            Destroy(collision.collider.gameObject);
            obji = obji - 1;
            Debug.Log(obji);

            if ((obji) > 0)
            {
                txt.text = (obji).ToString();
            }
            else {
                txt.text = "You win!";
            }
        }
    }
}

Editor view 1

Editor view 2

Upvotes: 0

Views: 1420

Answers (2)

Dimitar
Dimitar

Reputation: 4801

The error you've once received:

A namespace cannot directly contain members such as fields or methods,

tells you that in a namespace cannot be placed any methods or fields (i.e. variables) directly. A namespace can only contain

  • classes,
  • interfaces,
  • enums,
  • delegates,
  • structs
  • namespaces.

Generally speaking, a namespace is used to provide certain scope and organize entities.


There are many ways you can get access to another class's member fields. The cleanest and simplest way is through a so-called Getter method (also through get properties). You should avoid using and referencing public fields. For example, in your Collide class

// You don't have to always initialize your fields: they have default values. 
// Initialize only when you need to. 
private int obji;

...

public int GetObji() {
    return obji;
}

Now, to call that method you need a proper reference to it. For that you can simply add that as a parameter in your Timer class:

public Collide CollideRef;
...
// Get the field
CollideRef.GetObji();

And then just drag and drop the GameObject, having the Collide component onto it.

Upvotes: 0

Lews Therin
Lews Therin

Reputation: 3777

Communication between scripts like this (sharing properties of one class with another class) is a very common task in Unity. The script that needs the value of a property of another class should get a reference to that other class.

In your example, since Timer needs to access the obji property from the Collide class, you need to add a reference to the Collide class to the Timer class:

public class Timer : MonoBehaviour
{
    public Collide _collide;

    // The rest of the script...
}

Then, in the Inspector in Unity, you need to drag a GameObject that has the Collide script attached to the _collide property of the GameObject with the Timer script attached.

Finally, you can access the obji property through your newly created reference:

if (_collide.obji > 0)

See this tutorial from Unity which covers this topic in depth.

Upvotes: 3

Related Questions