当前位置:网站首页>Unity practical framework (I) scenario management framework
Unity practical framework (I) scenario management framework
2022-07-20 10:12:00 【p_ hat-trick】
List of articles
Unity Practical framework ( One ) Scenario management framework
as everyone knows ,Unity The engine itself provides SceneManager modular , But it only contains basic functions , For example, simple scene switching 、 Create scenes, etc , We want to make our scenario management framework applicable to more complex situations , Obviously, a more powerful interface is needed . below , The author will provide a flexible and easy-to-use SceneManager Feasible ideas .
Frame ideas
IScene/ISceneManager
First , In order to practice the idea of interface oriented programming , We need to understand what we want to achieve , And show it in the form of interface . Definition Iscene And ISceneManager Abstract scene objects and scene management component objects .
After defining these two interfaces , In the later practical implementation , The new types can be implemented separately IScene The interface is called a loadable scenario , Or implementation ISceneManager Make the type have the tools to complete the scene switching function with some logic ( Such as switching UI Of the scene UISceneManager Or switch the battle scene BattleSceneManager).
IScene
A typical scenario can be defined as a set of state machines , ad locum , Define the following states for the scene :
You can see , Here, the scene is divided into three lines , Five states , It's a little bit easier . These five states can basically meet the needs of scene management . Corresponding to each state above , It's a function , This function performs the operations that should be completed when switching states . Of course , because load State is responsible for loading scene resources , We naturally define its return value as IEnumerator To apply synergy .
IEnumerator Load(object savedState);
Besides , Define two properties in the interface , One for name(string) To identify the scene , For another ISceneManager Interface , This member should be the current SceneManager Reference to singleton , Used to complete Scene And SceneManager Interaction between .
IScene The complete definition of is as follows :
public interface IScene
{
string Name { get; }
ISceneManager SceneManager { get; set; }
IEnumerator Load(object savedState);
void Begin();
void Resume();
void Pause();
void Finish();
}
ISceneManager
ad locum , We are SceneManager Use stack structure to store scenes . Of course, this is not the only solution to writing a scenario management framework , But using stack naturally has its advantages . Go to the next page / Returning to the previous page is the mode that often appears in scene switching , Using stack structure can well adapt to this situation .
Since stack is used , that ISceneManager Naturally, it should be defined Push and Pop Two kinds of state , Of course , In order to deal with scene switching more flexibly , add to replace state , This state is equivalent to pop and push The combination of , But the intermediate state is omitted .
meanwhile , For the intermediate state of scene switching , We define it with a single class :
public class Transition
This “ Intermediate state ” Class will greatly extend our SceneManager The usability of , It contains the previous scene 、 The latter scenario , And the dynamic effect of scene switching , This class is not actually implemented , Want to achieve effects like gradual in and gradual out , Subclasses of this class should be written .
public enum TransitionType
{
Push,
Pop,
Replace
}
public class Transition
{
public TransitionType TransitionType { get; set; } // Conversion type
public IScene NextScene { get; set; } // Next scene
public Type NextSceneType { get; set; } // The type of the next scene
public object SavedState { get; set; } // Saved scene data
public event Action TransitionEnded; // Callback events
public event Action TransitionFadeOuted; // Callback events
internal void RaiseTransitionEnded()
{
TransitionEnded?.Invoke();
}
internal void RaiseTransitionFadeOuted()
{
TransitionFadeOuted?.Invoke();
}
}
Last , stay ISceneManager Interface , Contains the currently running scenario 、 Currently designated Transition, The method of switching scenes and callback events .
public interface ISceneManager
{
IScene CurrentScene { get; }
Transition CurrentTransition { get; }
event Action<Transition> TransitionStarted;
event Action<Transition> TransitionEnded;
void SetTransition(Transition transition);// It can be understood as native SceneManager Of loadscene function .
}
UISceneManager
Now? , Let's finish it IsceneManager A practical implementation of . Different kinds of scenarios may require different applications SceneManager( implement ISceneManager Interface ), Here we use UI For example .
First , yes UI Some components required by the interface :
private UIRoot uiRoot; //NGUI relevant , If you use UGUI Or other GUI Control does not need it
private UICamera uiCamera; // shooting UI Interface camera
private LayerMask eventReceiverMask = -1; // Hierarchical mask
then , You need a stack to store all the currently loaded scenes
private List<IUIOverlay> stackedOverlayList = new List<IUIOverlay>();
private List<KeyValuePair<IScene, object>> stackedScenes = new List<KeyValuePair<IScene, object>>();
among , above IUIOverlay The interface defines the current UI Others on the interface UI, Or picture in picture ,IUIOverlay Itself is not discussed in this article . The purpose of listing here is , Readers can know if they want to use SceneManager Achieve picture in picture 、 Pop up window and other effects , You can pop up 、 The control script of picture in picture implements this interface , To facilitate the SceneManager Unified management in .
Of course , Our focus is on SetTransition Function implementation .
public void SetTransition(Transition transition)
{
if (CurrentTransition != null)
{
return;
}
var t = transition as UITransition; //UITransition yes Transition Subclasses of
if (t.Animation == TransitionAnimation.None)
{
CoroutineManager.Instance.StartCoroutine(UIRoot, SetTransitionAsync(transition));
}
else if (t.Animation == TransitionAnimation.Fade)
{
CoroutineManager.Instance.StartCoroutine(UIRoot, SetFadeTransitionAsync(transition));
}
else
{
CoroutineManager.Instance.StartCoroutine(UIRoot, SetSlideTransitionAsync(transition));
}
}
Different scene conversion effects (None No effect ,Fade In and out ,Slide Slide out , It is assumed that there are only three ways ) Different conversion functions are required , Therefore, it is transferred to different functions to call . Note that scenario conversion, which is obviously expensive, should be applied with a coroutine . there CoroutineManager Nor is it a native collaboration manager , In other articles , The author will introduce an elegant CoroutineManager How to design .
What should be done during scene conversion ? First , When you need to judge the current conversion mode Push still Pop, This judgment is from stackedScene Take out the scene or press in the scene .
Pop
about pop, All you have to do is pop up the current scene , And take one from the scene stored in the stack and load .
if (transition.TransitionType == TransitionType.Pop)
{
if (stackedScenes.Count > 0)
{
var kv = stackedScenes[stackedScenes.Count - 1];
transition.NextScene = kv.Key;
transition.SavedState = kv.Value;
stackedScenes.RemoveAt(stackedScenes.Count - 1);
}
}
CurrentTransition = transition;
// The scene class and its data class together constitute transition
var nextScene = transition.NextScene;
var savedState = transition.SavedState;
// Don't forget it. Iscene Status defined in ! After taking out the scene in the stack , Before destroying the current scene , First call pause
currentScene?.Pause();
Push
about push, To push the current scene and the scene data to be saved onto the stack .
if (transition.TransitionType == TransitionType.Push && currentScene != null)
{
stackedScenes.Add(new KeyValuePair<IScene, object>(currentScene, nullSavedState));
}
currentScene?.Pause();
When pushed into the stack , With the scene, an empty data is pressed , This data will be filled after the scene is established . Because in general , We need to save the last state of the scene before it is destroyed , therefore , The most reasonable way should be in IScene.Finish() Function to store data in ( Remember the above IScene State machine ), The form of data will not be discussed in this article . obviously , For each scene , The types of data that need to be saved are very different , So for each inherited from IScene Scene class , Write a data Classes are reasonable . such as , For the game hall scene LobbyScene :IScene, Write a LobbySceneData To store its data . This class is IScene When loading the scene ,load Parameters obtained by function !
IEnumerator Load(object savedState);
After importing the new scene , You can call the current scene finish Function to destroy it , And load the current scene . Write functions that meet the requirements to complete the animation of scene conversion , For example, mask is used to realize gradual in and gradual out 、 perhaps canvas Upper "loading" word , Don't go over here .
// Unified scene conversion animation ?
currentScene?.Finish();
// Unified scene conversion animation ?
currentScene = nextScene;
StartCoroutine(currentScene.Load(currentScene.data));
//...
currentScene?.Begin();
//..
currentScene?.Resume();
//..
Sum up , We have implemented the simplest scenario manager ! With LobbyScene For example , The relationship between this set of scenario management is as follows
Update time :2022.7.16
边栏推荐
- Leshan normal programming competition 2020-c: maximum product [thinking]
- 黑马程序员多线程实现方式三
- Leshan normal programming competition 2020-h: least common multiple [find the number of factors]
- 栈模拟队列
- firewall-cmd
- FPGA - detailed explanation of SPI bus (concept)
- 南京大学计算方法(数值分析)期末复习笔记
- 学习笔记:猫眼top100电影信息爬取
- Leetcode:20. 有效的括号【三种思路+不同语言实现】
- 网络安全学习(十二)OSI与TCP
猜你喜欢
经纬度及其与坐标系的转换
离散数据(数组)的过零位置搜索
Deep parsing ThreadLocal
使用umount命令解挂载失败解决办法
FPGA skimming P4: use 8-3 priority encoder to realize 16-4 priority encoder, use 3-8 decoder to realize full subtracter, realize 3-8 decoder, use 3-8 decoder to realize logic function, and use data se
FPGA decoder + decoder (including code)
Qt解决大量重复数据的操作
FPGA skimming p2: multifunctional data processor, calculate the difference between two numbers, use generate For statement simplifies the code, uses sub modules to realize the size comparison of three
网络安全学习(十四)IP协议
黑马程序员线程安全问题
随机推荐
第二次实验 静态路由的扩展配置
2022-7-8 Group 8 Gu Yujia's Outward Bound Training
Network Security Learning (XXIII) firewall
网安学习(二十四)传输层协议
使用Google colab进行机器学习的经验
Unity实用框架(一)场景管理框架
2022-7-15 第八小组 顾宇佳 学习笔记
计算机408+数据库【适合考研复试或期末复习】
Network Security Learning (XIX) HSRP protocol
网络安全学习(十四)IP协议
黑马程序员单元测试:Junit框架入门
[2022/7/17]科研整理
Leetcode:20. 有效的括号【三种思路+不同语言实现】
解决问题phpstudy导入数据库失败
使用gem5在fft上进行测试beta版本
服务器硬件及RAID配置与实战
网安学习(二十)ACL
Leshan normal programming competition 2020-a: good pairs
雷达基础知识
FPGA skimming P4: use 8-3 priority encoder to realize 16-4 priority encoder, use 3-8 decoder to realize full subtracter, realize 3-8 decoder, use 3-8 decoder to realize logic function, and use data se