简体   繁体   中英

access global game data in Unity (C#)

i'am completely new to Unity and C#. I try to use my OOP knowledge to build something that holding the data and "business logic" of my game.

Game outline: Some cubes falling down, can be moved while falling and finally dropping on an pane.

The cubes are prefab objects and must be tracked to count the score, detect un/wanted behaviour, etc.

In the scene is:

  • 1 empty GameObject = CubeSpanPoint + CubeSpawn Script
  • 1 empty GameObject = GameMain + GameMain script (holding game settings and business logic)
  • 1 prefab Cube + MoveScript + FallingScript

GameMain.cs

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

[System.Serializable]
public class GameMain : MonoBehaviour
{
    private float CubeSpawnSpeed = 3.0f;  //seconds
    private int score = 0;

    // construtor
    public GameMain()
    {
    }

    // getter: is falling allowed for the cube
    public bool getFalling(){
        return true;
    }

    // getter cube spawn speed
    public float getCubeSpawnSpeed(){
        return this.CubeSpawnSpeed;
    }
}

The FallingScript must get the data from MainGame (getters), FallingSpeed and the falling permission.

CubeFalling.cs

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

public class BoxFalling : MonoBehaviour
{
    public GameMain gameMain;

    void Start(){
        // an attempt to get the instance this way, but fail
        // GameMain main = GameObject.Find("GameMain").GetComponent<GameMain>();
    }

    void Update()
    {
        // Is still falling allowed?
        if (gameMain.getFalling()){
            transform.Translate(Vector3.down);
        }
    }
}

But this produces the error NullReferenceException: Object reference not set to an instance of an object BoxFalling.Update ()

It is also not possible to use the inspector by pulling the GameMain GameObject onto gameMain slot in the CubeFalling Script to the same named public variable.

What i've been expecting is that i've to pull the GameMain scipt to the GameMain GameObject, what is equal to an instantiation with new GameMain . And to reuse this instance, that i've to pull the GameObject to the GameMain Variable in the falling script. But this don't work.

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

[System.Serializable]
public class GameMain : MonoBehaviour
{   private static GameMain _gameMain;
    public static GameMain Instance {get {return _gameMain;}}
    void Awake()
    {
        _gameMain = this;
    }

    // getter: is falling allowed for the cube
    public bool getFalling(){
        return true;
    }
}

BoxFalling.cs

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

public class BoxFalling : MonoBehaviour
{
    void Update()
    {
        // Is still falling allowed?
        // now you can got it
        if (GameMain.Instance.getFalling()){
            transform.Translate(Vector3.down);
        }
    }
}

You could use a Singleton to access GameMain . This would be handy when in future you are instantiating more cubes at runtime.

But you also should be able to retrieve the GameMain using

gameMain = GameObject.Find("GameMain").getComponent<GameMain>();

Perhaps you misspelled something? Deactivated objects will not be found.

(Edit: This approach searches through all GameObjects in the hierarchy. At least cache the result. See more at Unity's documentation )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM