C# 如何检查游戏是否在主菜单后启动?
在默认情况下运行游戏时,主菜单场景首先在索引0处加载。 因此,当加载游戏或制作新游戏时,任何加载的场景索引都不是0,表示游戏已启动或加载 我想将此脚本用作管理器脚本,以检测新游戏何时开始或游戏是否加载了主菜单以外的任何内容,以便我可以激活其他脚本中的内容或开始其他脚本中的内容 第一个问题是游戏对象脚本附加到的空游戏对象是否应该在DontDestroyOnLoad上 我如何从其他脚本中使用它C# 如何检查游戏是否在主菜单后启动?,c#,unity3d,C#,Unity3d,在默认情况下运行游戏时,主菜单场景首先在索引0处加载。 因此,当加载游戏或制作新游戏时,任何加载的场景索引都不是0,表示游戏已启动或加载 我想将此脚本用作管理器脚本,以检测新游戏何时开始或游戏是否加载了主菜单以外的任何内容,以便我可以激活其他脚本中的内容或开始其他脚本中的内容 第一个问题是游戏对象脚本附加到的空游戏对象是否应该在DontDestroyOnLoad上 我如何从其他脚本中使用它 using System.Collections; using System.Collections.Ge
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class NewGame : MonoBehaviour
{
public static bool GameStarted = false;
private Scene currentScene;
// Start is called before the first frame update
void Start()
{
currentScene = SceneManager.GetActiveScene();
}
// Update is called once per frame
void Update()
{
if(currentScene.buildIndex != 0 && GameStarted == false)
{
GameStarted = true;
}
}
}
我想使用的脚本示例如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScaleRotate : MonoBehaviour
{
public GameObject objectToScale;
public Vector3 minScale;
public Vector3 maxScale;
public float duration;
public float rotationAngle = 180.0f;
public DimLights dimLights;
private bool scaling = true;
private bool isInProcess = false;
private void Start()
{
StartCoroutine(dimLights.DimLightsOverTime(2, duration));
StartCoroutine(ScaleOverSeconds(maxScale, new Vector3(0,rotationAngle,0), duration));
}
public IEnumerator ScaleOverSeconds(Vector3 scaleTo, Vector3 rotateTo, float seconds)
{
isInProcess = true;
float elapsedTime = 0;
Vector3 startingScale = objectToScale.transform.localScale;
Vector3 startingRotation = objectToScale.transform.localEulerAngles;
//If you want, you can change axis of rotation or angle or everything you want. But what I do - I rotate by Y-axis for 180 degrees
while (elapsedTime < seconds)
{
objectToScale.transform.localScale = Vector3.Lerp(startingScale, scaleTo, (elapsedTime / seconds));
objectToScale.transform.localEulerAngles = Vector3.Lerp(startingRotation, rotateTo, (elapsedTime / seconds));
elapsedTime += Time.deltaTime;
//You can use yield return null instead of yield return new WaitForEndOfFrame() - this will do the same, but it's easier to write
yield return null;
}
objectToScale.transform.localScale = scaleTo;
objectToScale.transform.localEulerAngles = rotateTo;
isInProcess = false;
}
private void Update()
{
if(NewGame.GameStarted == true)
{
}
if (Input.GetKeyDown(KeyCode.S))
{
//Check if object is not changing it's scale right now
if (!isInProcess)
{
//Use if(scaling) instead of if(scaling == true) - this means the same, but it's more readable
if (scaling)
{
Vector3 rotateTo = objectToScale.transform.localEulerAngles + new Vector3(0, rotationAngle, 0);
StartCoroutine(dimLights.DimLightsOverTime(0, duration));
StartCoroutine(ScaleOverSeconds(minScale, rotateTo, duration));
//Remove scaling = false (we will paste it later)
}
//Add there else operator
else
{
//If you want to change rotation to counterclockwise, change '+' to '-'
Vector3 rotateTo = objectToScale.transform.localEulerAngles + new Vector3(0, rotationAngle, 0);
StartCoroutine(dimLights.DimLightsOverTime(2, duration));
StartCoroutine(ScaleOverSeconds(maxScale, rotateTo, duration));
}
//Change scaling value. If you want, you can move this line into ScaleOverSeconds coroutine
scaling = !scaling;
}
}
}
}
但我仍然不确定如何使用新游戏,以及这是否是检查新游戏开始的逻辑方法?使用
DontDestroyOnLoad
Start
public class NewGame : MonoBehaviour
{
// Here you store the actual instance
private static NewGame _instance;
// Public read-only access property
public static NewGame Instance
{
get
{
// if already set simply return directly
if(_instance) return _instance;
// Otherwise try to find it in the scene
_instance = FindObjectOfType<NewGame>();
if(_instance) return _instance;
// Otherwise create it now
_instance = new GameObject(nameof(NewGame)).AddComponent<NewGame>();
return _instance;
}
}
private void Awake()
{
if(_instance && _instance != this)
{
// There already exist another instance
Destroy (this.gameObject);
return;
}
// Otherwise this is the active instance and should not be destroyed
_instance = this;
DontDestroyOnLoad(this.gameObject);
// Todo solution for 2
}
...
}
因此,您可以在任何其他脚本中简单地访问
if(NewGame.GameStarted)
{
// => buildIndex != 0
}
我尝试了第二种解决方案,但在get=>行中出现错误,需要无效的表达式项{and;,需要get或set访问器
public class NewGame : MonoBehaviour
{
// Here you store the actual instance
private static NewGame _instance;
// Public read-only access property
public static NewGame Instance
{
get
{
// if already set simply return directly
if(_instance) return _instance;
// Otherwise try to find it in the scene
_instance = FindObjectOfType<NewGame>();
if(_instance) return _instance;
// Otherwise create it now
_instance = new GameObject(nameof(NewGame)).AddComponent<NewGame>();
return _instance;
}
}
private bool _gameStarted;
public static bool GameStarted => Instance._gameStarted;
private void Awake()
{
if(_instance && _instance != this)
{
// There already exist another instance
Destroy (this.gameObject);
return;
}
// Otherwise this is the active instance and should not be destroyed
_instance = this;
DontDestroyOnLoad(this.gameObject);
SceneManager.sceneLoaded += OnSceneLoaded;
// update it once now
_gameStarted = SceneManager.GetActiveScene().buildIndex != 0;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_gameStarted = scene.buildIndex != 0;
}
}
if(NewGame.GameStarted)
{
// => buildIndex != 0
}