【发布时间】:2021-06-21 20:26:04
【问题描述】:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneFader : MonoBehaviour
{
public CanvasGroup canvasGroup;
public bool fadeAutomatically;
public float fadeTime;
// Stores the currently running routine to be able to stop/cancel it
private Coroutine _currentRoutine;
// Stores the current direction
private bool _currentDirection;
// Used for the automatic switch to determine the next direction
private bool _nextDirection;
private void Start()
{
SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}
public enum FadeDirection
{
In,
Out
}
public IEnumerator FadeAndLoadScene(bool fadeDirection, string sceneToLoad)
{
yield return Fade(canvasGroup, fadeDirection, false);
SceneManager.LoadSceneAsync(sceneToLoad);
}
private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
{
if (MenuController.LoadSceneForSavedGame == true)
{
var saveLoad = GameObject.Find("Save System").GetComponent<SaveLoad>();
saveLoad.Load();
}
}
private void StartFade(bool isIn, bool autoSwitch)
{
// Another routine running already?
if (_currentRoutine != null)
{
// Different direction?
if (_currentDirection != isIn)
{
// Interrupt the current routine
StopCoroutine(_currentRoutine);
// And start a new one
_currentRoutine = StartCoroutine(Fade(canvasGroup, isIn, autoSwitch));
}
}
else
{
// Otherwise directly start the first routine
_currentRoutine = StartCoroutine(Fade(canvasGroup, isIn, autoSwitch));
}
}
private void Update()
{
if (!fadeAutomatically)
{
if (Input.GetKeyDown(KeyCode.O))
{
StartFade(false, fadeAutomatically);
}
if (Input.GetKeyDown(KeyCode.I))
{
StartFade(true, fadeAutomatically);
}
}
else // fadeAutomatically
{
StartFade(_nextDirection, fadeAutomatically);
}
}
public IEnumerator Fade(CanvasGroup canvasGroup, bool isIn, bool autoSwitch)
{
// Store the current fading direction
_currentDirection = isIn;
// Determine start and end value depending on the fading direction
var startValue = isIn ? 0 : 1;
var targetValue = isIn ? 1 : 0;
// Get the so far elapsed time according to the current alpha
// It is the fadeTime multiplied by the already added or removed alpha
var elapsedTime = fadeTime * (isIn ? canvasGroup.alpha : (1 - canvasGroup.alpha));
while (elapsedTime <= fadeTime)
{
// Use Maths.Lerp to linear interpolate between the start and end value
canvasGroup.alpha = Mathf.Lerp(startValue, targetValue, elapsedTime / fadeTime);
// For "skipping" one single frame you can simply return null
yield return null;
elapsedTime += Time.deltaTime;
}
// To be sure to end with clean values
canvasGroup.alpha = targetValue;
// Should we automatically switch the direction?
if (autoSwitch) _nextDirection = !isIn;
// Reset the current routine (see below)
// Not sure if this is really necessary, I believe it will reset anyway
// as soon as the routine has finished .. but just to be sure
_currentRoutine = null;
}
}
我添加了这个枚举并使用它:第 24 到 32 行
public enum FadeDirection
{
In,
Out
}
public IEnumerator FadeAndLoadScene(bool fadeDirection, string sceneToLoad)
{
yield return Fade(canvasGroup, fadeDirection, false);
然后在像这样的其他脚本中使用它:
StartCoroutine(sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, _newGameButtonLevel));
但我收到错误:
SceneFader.FadeDirection.In
无法从 SceneFader.FadeDirection 转换为 bool
我也想使用淡入淡出脚本来加载场景。尝试使用枚举对其进行扩展,但出现此错误。
主要目标是能够在加载场景时淡入/淡出,如果只是需要淡入某些场景,还可以在游戏中淡入。
【问题讨论】:
-
不清楚您期望
FadeDirection.In被解释为什么。既然您使用的是文字值(不是变量),为什么不直接传递您真正想要的bool值呢?如果您确实有一个变量,您可以将它与一个枚举值进行比较以返回一个bool值,但似乎不需要在此处进行这种简单的转换。跨度> -
如果您要拥有一个枚举,那么您的公共函数应该将枚举作为参数,而不是布尔值。如果需要,您可以在内部函数中将其转换为布尔值。
-
你在这里使用枚举有什么原因吗?似乎您有两种状态,一种是淡入颜色,另一种是淡出,那么为什么不直接设置一个布尔值
isFadingIn并在淡入时将其设置为 true,然后在淡出时设置为 false?为什么你需要在这里使用枚举?