属性没有传递给其他类

时间:2017-07-21 04:25:24

标签: c# unity3d properties

第一次真正尝试实现属性,似乎我错过了一些我不知道的基本内容。我试图将bool值从一次脚本传递到另一个脚本并使用Update()不断提升。

GameManager.cs我正在检查玩家是否空闲,当玩家空闲时,它会将属性UserActive设置为false。在PreCountdownTimer.cs我只是在测试_userActive是否正在更新,但事实并非如此。为什么GameManager()中的属性值未传递给PreCountdownTimer()

GameManager.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance = null;

    public Object introScene;

    private bool _userActive;
    public bool UserActive { get; set; }
    private bool _onIntroScreen;
    public bool OnIntroScreen { get; set; }

    public GameObject preCountdownTimerPrefab;
    private GameObject _preCountdownTimerInstance;
    private float _preCountdownLength;
    public float PreCountdownLength { get; protected set; }
    private float _preCountdownInterval;
    public float PreCountdownInterval { get; protected set; }

    private float _checkMousePositionTimingInterval = 0.1f;
    private Vector3 _currentMousePosition;
    private Vector3 _prevMousePosition;
    private Scene _currentScene;

    void Awake()
    {
        if (Instance == null)
            Instance = this;
        else if (Instance != null)
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);
    }

    void OnEnable()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        _currentScene = scene;
    }

    void Start()
    {
        PreCountdownLength = 5.0f;
        PreCountdownInterval = 1.0f;

        _onIntroScreen = true;
        _userActive = false;

        _prevMousePosition = Input.mousePosition;

        InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval); 
    }

    void Update()
    {
        _currentMousePosition = Input.mousePosition;

        // CHECK FOR PLAYER IDLE
        if (_currentScene.name != introScene.name)
        {
            _onIntroScreen = false;

            if (_currentMousePosition != _prevMousePosition)
            {
                _userActive = true;
            }
            else
            {
                _userActive = false;
            }       
        }
        else if (_currentScene.name == introScene.name)
        {
            _onIntroScreen = true;
        }

        // IF IDLE START PRE-COUNT TIMER ELSE DESTROY
        if (!_userActive && !_onIntroScreen)
        {
            if (_preCountdownTimerInstance == null)
                _preCountdownTimerInstance = Instantiate(preCountdownTimerPrefab);
        }
        else if (_userActive)
        {
            if (_preCountdownTimerInstance != null)
                Destroy(_preCountdownTimerInstance);
        }
    }

    void LastMousePosition()
    {
        _prevMousePosition = Input.mousePosition;
    }
}

PreCountdownTimer.cs

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

public class PreCountdownTimer : MonoBehaviour {

    private IEnumerator preCounter;

    private float _preCountdownInterval;
    private bool _preCountdownActive;
    private bool _userActive;
    private bool _onIntroScreen;
    private float _timerLength;

    void Start()
    {
        _timerLength = GameManager.Instance.PreCountdownLength;
    }

   void Update()
    {
        _userActive = GameManager.Instance.UserActive;
        _onIntroScreen = GameManager.Instance.OnIntroScreen;

        Debug.Log("User Activity: " + _userActive);
    }
}

2 个答案:

答案 0 :(得分:2)

GameManager中,您有一个字段和一个属性:

private bool _userActive;              // field
public bool UserActive { get; set; }   // property

那些没有联系。设置_userActive后,它对UserActive无效。在PreCountdownTimer中,您检查GameManager.Instance.UserActive。修复方法是连接字段和属性:

private bool _userActive;
public bool UserActive 
{ 
    get
    {
        return _userActive;
    } 
    set
    {
        _userActive = value;
    } 
}

或者根本删除字段_userActive并设置属性(我更喜欢这种方式,因为您目前不需要该字段):

void Start()
{
    PreCountdownLength = 5.0f;
    PreCountdownInterval = 1.0f;

    _onIntroScreen = true;
    UserActive = false;

    _prevMousePosition = Input.mousePosition;

    InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval); 
}

void Update()
{
    _currentMousePosition = Input.mousePosition;

    // CHECK FOR PLAYER IDLE
    if (_currentScene.name != introScene.name)
    {
        _onIntroScreen = false;

        if (_currentMousePosition != _prevMousePosition)
        {
            UserActive = true;
        }
        else
        {
            UserActive = false;
        }       
    }
    else if (_currentScene.name == introScene.name)
    {
        _onIntroScreen = true;
    }

    // IF IDLE START PRE-COUNT TIMER ELSE DESTROY
    if (!UserActive && !_onIntroScreen)
    {
        if (_preCountdownTimerInstance == null)
            _preCountdownTimerInstance = Instantiate(preCountdownTimerPrefab);
    }
    else if (UserActive)
    {
        if (_preCountdownTimerInstance != null)
            Destroy(_preCountdownTimerInstance);
    }
}

GameManager中的其他属性也存在同样的问题。另外,我建议使用属性(也在GameManager)而不是字段。通过这种方式,您可以更好地控制正在发生的事情。只有在绝对必要时才直接使用字段。

答案 1 :(得分:1)

在GameManager中你定义了

private bool _userActive;
public bool UserActive { get; set; }

第一个是私有字段,而第二个是公共属性,它们具有相似的名称,但您没有将它们链接在一起,因此它们都是独立的。

您有两种选择,

1)删除私有_userActive并仅使用公共属性 2)使公共财产使用私人领域,如下面的

private bool _userActive;
public bool UserActive 
{ 
    get
    {
       return _userActive;
    }; 
    set
    {
       this._userActive = value;
    };
}

如果您需要进行一些验证,重新格式化或触发其他操作以及检索或设置值,则第二个选项最有用。