创建场景状态接口类 与 场景状态基类
public interface IBaseSceneState {
void EnterScene();
void ExitScene();
}public class BaseSceneState : IBaseSceneState
{
protected UIFacade mUIFacade;
public BaseSceneState(UIFacade uIFacade)
{
mUIFacade = uIFacade;
}
public virtual void EnterScene()
{
mUIFacade.InitPanel();
}
public virtual void ExitScene()
{
mUIFacade.ClearPanel();
}
}在Canvas和GameManager上挂载脚本
public class CanvasDontDesOnLoad : MonoBehaviour {
void Start ()
{
DontDestroyOnLoad(this.gameObject);
}
}游戏总管理类: GameManager --游戏总管理,负责管理所有的管理者
UI管理者类:UIManager - 负责管理UI的管理者
UI中介者类: UIFacade -- UI中介,上层与管理者们做交互,下层与UI面板进行交互(使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互)
场景切换流程:
1. 调用ChangeScene方法 -- 在UIFacade中将当前场景赋值给上一个场景,将传入的场景赋值给当前场景
2. 在显示遮罩的2秒后调用上一个场景的Exit()方法:先清理当前场景字典中 Panel身上的IBasePanel的引用(直接Clear()) ,再清理Panel游戏物体,将其放入工厂后clear()字典
3. 再调用当前场景的Enter()方法 : 将当前场景所需的Panel游戏物体添加进存储Panel游戏物体的字典中,再实例化当前字典中的Panel面板并获取Panel面板上的Panel脚本,调用Panel脚本的Init()初始化方法并将Panel脚本添加进Panel脚本的字典中;
4. 最后用2秒逐渐隐藏遮罩,显示场景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 游戏总管理,负责管理所有的管理者
/// </summary>
public class GameManager : MonoBehaviour
{
private static GameManager _instance;
public static GameManager instance
{
get
{
return _instance;
}
}
public FactoryManager factoryManager;
public UIManager uIManager;
private void Awake()
{
_instance = this;
factoryManager = new FactoryManager();
uIManager = new UIManager();
//第一次需要手动控制场景的加载
uIManager.mUIFacade.currentSceneState.EnterScene();
}
//获取Sprite资源
public Sprite GetSprite(string resourcesName)
{
return factoryManager.spriteFactory.GetSingleResources(resourcesName);
}
//获取AudioClip资源
public AudioClip GetAudioClip(string resourcesName)
{
return factoryManager.audioClipFactory.GetSingleResources(resourcesName);
}
// 得到游戏物体资源
public GameObject GetGameObjectResources(FactoryType factoryType,string resourcesName)
{
return factoryManager.factoryDict[factoryType].GetItem(resourcesName);
}
//将游戏物体入栈
public void PushGameObjectToFactory(FactoryType factoryType,string itemName,GameObject itemGO)
{
factoryManager.factoryDict[factoryType].PushItem(itemName, itemGO);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
/// <summary>
/// UI中介,上层与管理者们做交互,下层与UI面板进行交互
/// </summary>
public class UIFacade {
private GameManager mGameManager;
public Dictionary<string, IBasePanel> currentScenePanelDict = new Dictionary<string, IBasePanel>();
public IBaseSceneState currentSceneState;
public IBaseSceneState lastSceneState;
private GameObject mask; //开始画面的遮罩
private Image maskImage; //遮罩图片
public Transform canvasTrans;
public UIManager mUIManager;
public UIFacade(UIManager uIManager)
{
mGameManager = GameManager.instance;
mUIManager = uIManager;
InitMask();
}
//初始化遮罩
public void InitMask()
{
canvasTrans = GameObject.Find("Canvas").transform;
//mask = GameManager.instance.GetGameObjectResources(FactoryType.UIFactory,"Img_Mask");
mask = CreateUIAndSetPos("Img_Mask");
maskImage = mask.GetComponent<Image>();
}
//实例化UI
public GameObject CreateUIAndSetPos(string uiName)
{
GameObject itemGO = GameManager.instance.GetGameObjectResources(FactoryType.UIFactory, uiName);
itemGO.transform.SetParent(canvasTrans);
itemGO.transform.localScale = Vector3.one;
itemGO.transform.localPosition = Vector3.zero;
return itemGO;
}
//改变当前场景的状态
public void ChangeSceneState(IBaseSceneState baseSceneState)
{
lastSceneState = currentSceneState;
ShowMask();
currentSceneState = baseSceneState;
}
//显示遮罩
public void ShowMask()
{
mask.transform.SetSiblingIndex(10);
Tween t = DOTween.To(() => maskImage.color, toColor => maskImage.color = toColor, new Color(0, 0, 0, 1), 2f);
t.OnComplete(ExitSceneComplete);
}
//离开当前场景
public void ExitSceneComplete()
{
lastSceneState.ExitScene();
currentSceneState.EnterScene();
HideMask();
}
public void HideMask()
{
mask.transform.SetSiblingIndex(10);
DOTween.To(() => maskImage.color, toColor => maskImage.color = toColor, new Color(0, 0, 0, 0), 2f);
}
/// <summary>
/// 添加UIPanel到UIManager字典
/// </summary>
public void AddPanelToUIManagerDict(string uiPanelName)
{
mUIManager.currentScenePanelDict.Add(uiPanelName,mGameManager.GetGameObjectResources(FactoryType.UIPanelFactory,uiPanelName));
}
/// <summary>
/// 实例化当前所有面板并添加到当前字典并调用Panel的Init()方法
/// </summary>
public void InitPanel()
{
foreach (var item in mUIManager.currentScenePanelDict)
{
item.Value.transform.SetParent(canvasTrans);
item.Value.transform.localPosition = Vector3.zero;
item.Value.transform.localScale = Vector3.one;
IBasePanel basePanel = item.Value.GetComponent<IBasePanel>();
if (basePanel == null)
{
Debug.LogWarning("获取面板上的IBasePanel脚本失败");
}
basePanel.InitPanel();
currentScenePanelDict.Add(item.Key,basePanel);
}
}
public void ClearPanel()
{
currentScenePanelDict.Clear();
mUIManager.ClearDict();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 负责管理UI的管理者
/// </summary>
public class UIManager {
public Dictionary<string, GameObject> currentScenePanelDict;
public UIFacade mUIFacade;
public UIManager()
{
mUIFacade = new UIFacade(this);
currentScenePanelDict = new Dictionary<string, GameObject>();
mUIFacade.currentSceneState = new StartLoadSceneState(mUIFacade);
}
//清空字典,清除的是GameObject
public void ClearDict()
{
foreach (var item in currentScenePanelDict)
{
PushUIPanelToFactory(item.Value.name.Substring(0,item.Value.name.Length-7),item.Value);
}
currentScenePanelDict.Clear();
}
//将UIPanel放回工厂
public void PushUIPanelToFactory (string itemName,GameObject item)
{
GameManager.instance.PushGameObjectToFactory(FactoryType.UIPanelFactory, itemName,item);
}
}
游戏开始场景:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class StartLoadSceneState : BaseSceneState
{
public StartLoadSceneState(UIFacade uIFacade):base(uIFacade)
{
}
public override void EnterScene()
{
mUIFacade.AddPanelToUIManagerDict(StringManager.StartLoadPanel);
base.EnterScene();
}
public override void ExitScene()
{
base.ExitScene();
SceneManager.LoadScene(1);
}
}
游戏主场景
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainSceneState : BaseSceneState
{
public MainSceneState(UIFacade uIFacade) : base(uIFacade)
{
}
public override void EnterScene()
{
mUIFacade.AddPanelToUIManagerDict(StringManager.HelpPanel);
mUIFacade.AddPanelToUIManagerDict(StringManager.SetPanel);
mUIFacade.AddPanelToUIManagerDict(StringManager.MainPanel);
mUIFacade.AddPanelToUIManagerDict(StringManager.GameLoadPanel);
base.EnterScene();
}
public override void ExitScene()
{
base.ExitScene();
SceneManager.LoadScene(2);
}
}
其他测试场景:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NormalGameOptionSceneState : BaseSceneState
{
public NormalGameOptionSceneState(UIFacade uIFacade) : base(uIFacade)
{
}
public override void EnterScene()
{
mUIFacade.AddPanelToUIManagerDict(StringManager.GameNormalOptionPanel);
mUIFacade.AddPanelToUIManagerDict(StringManager.GameNormalBigLevelPanel);
base.EnterScene();
}
public override void ExitScene()
{
base.ExitScene();
}
}
游戏面板类
面板接口和面板基类
public interface IBasePanel {
void InitPanel();
void EnterPanel();
void ExitPanel();
void UpdatePanel();
}using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasePanel : MonoBehaviour, IBasePanel
{
protected UIFacade mUIFacade;
protected virtual void Awake()
{
mUIFacade = GameManager.instance.uIManager.mUIFacade;
}
public virtual void EnterPanel()
{
}
public virtual void ExitPanel()
{
}
public virtual void InitPanel()
{
}
public virtual void UpdatePanel()
{
}
}
开始场景面板
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class StartLoadPanel : BasePanel
{
protected override void Awake()
{
base.Awake();
Invoke("LoadNextScene", 2);
}
private void LoadNextScene()
{
mUIFacade.ChangeSceneState(new MainSceneState(mUIFacade));
}
}
主场景游戏面板
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class MainPanel : BasePanel
{
private Tween[] mainPanelTween = new Tween[2];//0.右,1.左
private Tween ExitTween;//离开主页时运行的动画
protected override void Awake()
{
base.Awake();
mainPanelTween[0] = transform.DOLocalMoveX(1920, 0.5f);
mainPanelTween[0].SetAutoKill(false);
mainPanelTween[0].Pause();
mainPanelTween[1] = transform.DOLocalMoveX(-1920, 0.5f);
mainPanelTween[1].SetAutoKill(false);
mainPanelTween[1].Pause();
}
public override void EnterPanel()
{
if (ExitTween != null)
{
ExitTween.PlayBackwards();
}
}
public override void ExitPanel()
{
ExitTween.PlayBackwards();
}
public void MainPanelMoveToLeft()
{
ExitTween = mainPanelTween[0];
ExitTween.Play();
mUIFacade.currentScenePanelDict[StringManager.SetPanel].EnterPanel();
}
public void MainPanelMoveToRight()
{
ExitTween = mainPanelTween[1];
ExitTween.Play();
mUIFacade.currentScenePanelDict[StringManager.HelpPanel].EnterPanel();
}
public void ChangeToNoramlScene()
{
mUIFacade.currentScenePanelDict[StringManager.GameLoadPanel].EnterPanel();
mUIFacade.ChangeSceneState(new NormalGameOptionSceneState(mUIFacade));
}
}
帮助和设置面板
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class HelpPanel : BasePanel
{
private Tween helpPanelTween;
protected override void Awake()
{
base.Awake();
helpPanelTween = transform.DOLocalMoveX(0, 0.5f);
helpPanelTween.SetAutoKill(false);
helpPanelTween.Pause();
transform.SetSiblingIndex(5);
}
public override void InitPanel()
{
transform.localPosition = new Vector3(1920, 0, 0);
}
public override void EnterPanel()
{
helpPanelTween.PlayForward(); //移动到中心
}
public override void ExitPanel()
{
if (mUIFacade.currentSceneState.GetType() == typeof(NormalGameOptionSceneState))
{
helpPanelTween.PlayBackwards();
}
else
{
helpPanelTween.PlayBackwards();
mUIFacade.currentScenePanelDict[StringManager.MainPanel].EnterPanel();
}
}
public void ReutnToMainPanel()
{
helpPanelTween.PlayBackwards();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class SetPanel : BasePanel
{
private Tween setPanelTween;
protected override void Awake()
{
base.Awake();
setPanelTween = transform.DOLocalMoveX(0, 0.5f);
setPanelTween.SetAutoKill(false);
setPanelTween.Pause();
transform.SetSiblingIndex(2);
}
public override void InitPanel()
{
transform.localPosition = new Vector3(-1920, 0, 0);
}
public override void EnterPanel()
{
setPanelTween.PlayForward();
}
public override void ExitPanel()
{
setPanelTween.PlayBackwards();
mUIFacade.currentScenePanelDict[StringManager.MainPanel].EnterPanel();
}
}
版权声明:本文为weixin_44003309原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。