第一次真正尝试实现属性,似乎我错过了一些我不知道的基本内容。我试图将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);
}
}
答案 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;
};
}
如果您需要进行一些验证,重新格式化或触发其他操作以及检索或设置值,则第二个选项最有用。