我有一个脚本冲突,检查是否存在网络连接和游戏版本(是否为最新版本);但它会跳过这些条件并直接加载游戏。
我如何使脚本遵循此模式?:
您会发现有一些加载函数会重复执行;我不确定要申请哪些。
public Text AlertText;
public GameObject alert;
public string URL = "";
public string CurrentVersion;
string latestVersion;
public GameObject newVersionAvailable;
private void Start()
{
StartCoroutine(LoadTxtData(URL));
}
void Awake()
{
if (Application.internetReachability == NetworkReachability.NotReachable)
{
alert.SetActive(true);
AlertText.text = "Sorry, you have to enable your conection to play this game";
if (Input.GetKeyDown(KeyCode.Escape))
Application.Quit();
}
else
{
alert.SetActive(false);
CheckVersion();
}
}
public void CheckVersion()
{
if(CurrentVersion != latestVersion)
{
newVersionAvailable.SetActive(true);
}
else
{
newVersionAvailable.SetActive(false);
}
}
private IEnumerator LoadTxtData(string url)
{
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
latestVersion = www.ToString();
CheckVersion();
}
public void OpenURL(string url)
{
Application.OpenURL(url);
}
private Image progressBar;
private void Start()
{
Invoke("LoadAsyncOperation", 3f);
StartCoroutine(LoadAsyncOperation());
}
public IEnumerator LoadAsyncOperation()
{
AsyncOperation gameLevel = SceneManager.LoadSceneAsync(1);
while (gameLevel.progress < 1)
{
progressBar.fillAmount = gameLevel.progress;
yield return new WaitForEndOfFrame();
}
}
public GameObject loadingScreenObj;
public Slider slider;
AsyncOperation async;
public void StartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
public void LoadScreen(int LVL)
{
//StartCoroutine(loadingScreen());
}
IEnumerator LoadingScreen(int lvl)
{
loadingScreenObj.SetActive(true);
async = SceneManager.LoadSceneAsync(lvl);
async.allowSceneActivation = false;
while (async.isDone == false)
{
slider.value = async.progress;
if (async.progress == 0.9f)
{
slider.value = 1f;
async.allowSceneActivation = true;
}
yield return null;
}
}
void Start()
{
Invoke("loadMenuLevel", 3f);
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
void loadMenuLevel()
{
SceneManager.LoadScene("gameplay");
}
void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
loadMenuLevel();
}
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
}
答案 0 :(得分:1)
之所以发生这种情况,是因为您在Invoke("loadMenuLevel", 3f);
脚本的Start()
方法中调用了SplashScrean.cs
方法。
Start()
附加到对象后很快调用 MonoBehaviour
。表面上,您已将其附加到场景中的GameObject
。所有这些都被立即击中。
您还可以通过在同一脚本的Update()
方法中单击鼠标左键来调用它:
if (Input.GetKey(KeyCode.Mouse0))
{
loadMenuLevel();
}
我将在每个任务完成时向设置为bools
的每个加载脚本中添加true
。然后,在SplashScrean.cs
中,如果以上三个条件均已完成,则更改以上条件以自动加载级别。或者,保持按键状态并添加bools
。
if (Application.internetReachability != NetworkReachability.NotReachable
&& loadScriptComplete && isCurrentVersion && Input.GetKey(KeyCode.Mouse0))
{
loadMenuLevel();
}
现在,如果您还需要加载MonoBehaviours
来等待执行其加载逻辑,那么可以考虑向其添加Update()
逻辑来检查您在CheckNetwork.cs
中设置的标志。 / p>
//For example. Instead of this
private void Start()
{
Invoke("LoadAsyncOperation", 3f);
StartCoroutine(LoadAsyncOperation());
}
//Do this
private void Update()
{
//Note that we only need to check if it is a CurrentVersion, as if that is true, then we definitely have internet access.
if(CheckNetwork.IsCurrentVersion) {
Invoke("LoadAsyncOperation", 3f);
StartCoroutine(LoadAsyncOperation());
}
}
编辑/其他说明,我注意到:
CheckNetwork.cs
在CheckVersion();
子句中引用else
。这似乎毫无意义。 LoadTxtData()
无法在该时间范围内设置CheckVersion()
所依赖的逻辑。如果您愿意的话,这是一种比赛条件。另外,您还是要处理LoadTxtData()
中的支票,所以我就在那里进行。
答案 1 :(得分:1)
在这里我不能给您完整的可复制代码(主要是因为我还不完全了解您的所有脚本之间的连接方式),但是我发现您已经在使用Coroutines。 / p>
如前所述,我会使用一名中央经理来处理所有这些事情。
我在这里只给您一个通用的伪代码,希望您从这里找到自己的路
public class LoadManager
{
public CheckNetwork check;
public Loading loading;
public Loading2 loading2;
public SplashScrean splashScreen;
// suprise: a not well documented fact
// you can simply make the Start method an IEnumerator (Coroutine)
// so you can directly wait for anything you want
private void IEnumerator Start()
{
// Next suprise: You can simply yield other IEnumerators
// that makes them execute and at the same time waits until they are finished
// so all methods that you want to wait for from here
// should be IEnumerators
// as said this is only an example
// you could directly within that single
// Coroutine do your complete download and check routine together
yield return check.CheckPermissions();
if(!check.isReachable)
{
yield break;
}
// same for chekcing the version
yield return check.CheckVersion();
if(!check.isUpToDate)
{
// do something for update
yield break;
}
// is up to date so start and wait for loading
yield return loading.LoadAsyncOperation();
// and so on
}
}
还有一些内置的等待方式,例如WaitUntil,WaitForSeconds等。