In this blog post I have documented the simple application of State mode in game development, which is used to switch individual game scenes . But in the actual game development, I do not recommend this way to switch the game scene, because unity is a component-based game engine. However, the knowledge is more harmful and useless, for learning and learning.
First the general Picture:
The above figure is divided into two modules, the first is a common mode of the prototype code (mainly related to the state model of the concept of understanding and prototype code implementation, not to do a detailed explanation of HA), the second is in the game development of the actual application , three scenarios corresponding to three states, Use the status mode to switch individual game scenes (states).
1. Simply give the prototype code for the state mode in common mode:
Create a new scene in unity and attach the following script to any game object
Using Unityengine;
Using System.Collections; public class Statedesignmood:monobehaviour {//initialization void Start () {Context con
Text = new Context (); Context.
SetState (new Concretestatea (context)); Context.
Handle (5); Context.
Handle (20); Context.
Handle (30); Context.
Handle (4); Context.
Handle (50); }}///1.
Overview: When an object's internal state changes to allow it to change its behavior, the object looks like it has changed its class. 2. Problem solved: The main solution is when the conditional expression that controls an object state transition is too complex.
It is possible to simplify the complex logic judgment by transferring the judgment logic of the state to a series of classes that represent different kinds.
<summary>/////Context class: It defines the interfaces required by the client program and maintains an instance of a specific state role, delegating state-related operations to the current concrete.
Just like the class is a protagonist in the game, he needs to do a variety of different states//</summary> public class Context {private istate state;
public void SetState (Istate state) {this.state = state; } public void Handle (int arg) {state.
Handle (ARG);
}}///<summary>///Abstract State interface: Defines an interface to encapsulate a specific state-related behavior using the context environment. </summary> public interface Istate {void Handle (int ARG);
}//<summary>///Specific status Class A (concrete Statea): interface for implementing abstract state Definitions///</summary> public class Concretestatea:istate {
Private context context;
Public Concretestatea (Context context) {This.context = context;
} public void Handle (int arg) {Debug.Log ("I am a specific state Class A," + arg);
if (Arg > 10)//If the passed in parameter is greater than 10, turn to another specific State B processing {this.context.SetState (new Concretestateb (This.context)); }}}///<summary>//Specific State Class B (concrete Stateb): interface to implement abstract state definition///</summary> public class Concretes
Tateb:istate {Private context context;
Public Concretestateb (Context context) {This.context = context;
} public void Handle (int arg) {Debug.Log ("I am a specific state Class B," + arg);
if (ARG <= 10)//If the incoming parameter is greater than 10, turn to another specific state a processing {this.context.SetState (new Concretestatea (This.context)); }
}
}
2. In this game development, the state corresponds to the scene, there are 3 game scenes: Start scene, menu scene, Battle scene, these scenes are just a simple prototype, not to implement its specific function, because our model of the theme content is not here, but in the use of State mode to achieve the scene switching.
Three of scenarios:
Six scripts (specific features are explained below):
Scripting UML diagrams (with a focus on understanding the UML diagram of prototype code in normal mode):
The Gameloop script is used to start the entire project:
Using Unityengine;
Using System.Collections;
<summary>////
This class is used to start the scene manager in state mode////
</summary> public
class Gameloop:monobehaviour {
private Scenestatecontroller Statecontroller = null;
private void Awake ()
{
dontdestroyonload (this.gameobject);
}
Use the this for initialization
void Start () {
Statecontroller = new Scenestatecontroller ();
Statecontroller.setstate (New Startstate ("Start", Statecontroller), false);
}
Update is called once per frame
void Update () {
statecontroller.stateupdate ();//start Scene manager
}
}
The
Scenestatecontroller is used to control the transitions for each state (scene):
Using Unityengine;
Using System.Collections;
Using Unityengine.scenemanagement; <summary>///Scene Manager///</summary> public class Scenestatecontroller {private Iscenestate scenestate; Affirms that a Iscenestate object private AsyncOperation ao;//is used to receive the return value of the asynchronous load scene and to determine if the asynchronous loading scenario is loaded private bool Isrunstart = false;//is Run the Statestart () method to ensure that Statestart () is only called once///<summary>///////</summary>///<PA Ram Name= "Scenestate" > Scene state Interface object </param>//<param name= "Isloadscene" > whether a scene needs to be loaded (default first scene does not load) </
param> public void SetState (iscenestate scenestate,bool Isloadscene = True) {if (scenestate! = null) {scenestate.stateend ();//After the scene is over, do some cleanup work. This.scenestate = scenestate;//Updates the state (the scene) to a new state (
New scene) if (Isloadscene = = True) {ao = Scenemanager.loadsceneasync (scenestate.scenename);
Isrunstart = false; } else {thiS.scenestate.statestart ();
Isrunstart = true; }}///<summary>//Update status (Scene) method///</summary> public void Stateupdate () {if (AO ! = NULL && Ao.isdone = = False) return;//If you are in the process of loading, you do not have to update the status if (AO! = null && Ao.isdone = = Tru E && Isrunstart = = false)//If the asynchronous load is complete and the Statestart () method has not been run to execute the load resource, the method {Scenestate.statestart ()
;
Isrunstart = true;
} if (scenestate! = null) {scenestate.stateupdate ();
}
}
}
Next is the specific state mode code to implement the switch function of the specific implementation steps in the above general diagram is described in total, divided into 7 steps.
2.1 Create the base interface for the scene state:
Using Unityengine;
Using System.Collections;
<summary>/////Scene State interface (not strictly an interface, this is a parent class, because there will be a method in which subclasses need to inherit)///</summary> public class Iscenestate { Private string scenename;//The scene name that needs to be loaded protected Scenestatecontroller scenecontroller;//represents the owner of the state, the scene Manager///< summary>///Get Scene name///</summary> public string Scenename {get {ret
Urn Scenename; }}///<summary>//Construction method///</summary>//<param name= "Scenename" > Scene name </param >//<param name= "Scenecontroller" > Scene manager </param> public iscenestate (String Scenename,scenestatecon
Troller scenecontroller) {this.scenename = Scenename;
This.scenecontroller = Scenecontroller; }///<summary>//////The method (which may need to load resources in the game), and call///</summary> public virtual void each time you enter this state Statestart () {}///<summary>/////////////At the end of the scene (may need to release resources in the game), each time you exit to this stateCall///</summary> public virtual void Stateend () {}///<summary>//Update scene///</summ
ary> public virtual void Stateupdate () {}}
2.2 Create three sub-classes of scene state (Start interface, menu interface, Combat Interface):
Using Unityengine;
Using System.Collections;
Using Unityengine.ui;
<summary>//Start status (Start interface)///</summary> public class Startstate:iscenestate {//<summary> Start interface (state) Construction method///</summary>//<param name= "Scenename" > Scene name </param>//<param name = "Scenecontroller" > Scene Controller </param> Public startstate (String scenename, Scenestatecontroller Scenecontroller) : Base (Scenename, Scenecontroller) {} private Image logo;//start interface logo private float smoothingspeed = 2f;//transparency Excessive smoothing speed Rate private Float WaitTime = 3f;//load the next interface wait time public override void Statestart () {logo = gameobject.fi nd ("Logo").
Getcomponent<image> ();
Logo.color = new color (1,1,1,0); } public override void Stateupdate () {logo.color = Color.lerp (logo.color,new color (1,1,1,1), Time.deltati
Me * smoothingspeed);//Set Start UI transparency gradient waitTime-= time.deltatime;
if (waitTime <= 0) { Scenecontroller.setstate (New Mainmenustate ("MainMenu", Scenecontroller));//arrival wait time into the next scene}}} using
Unityengine;
Using System.Collections;
Using Unityengine.ui;
<summary>///second status (Home view)///</summary> public class Mainmenustate:iscenestate {//<summary> Start interface (state) Construction method///</summary>//<param name= "Scenename" > Scene name </param>//<param NA Me= "Scenecontroller" > Scene Controller </param> Public mainmenustate (string scenename, Scenestatecontroller Scenecontroller): Base (Scenename, Scenecontroller) {} Private Button startbutton;//start game button public override void S Tatestart () {Startbutton = Gameobject.find ("Startbutton").
Getcomponent<button> ();
StartButton.onClick.AddListener (Onstartbtndown);//Add Start Game button event listening} private void Onstartbtndown () {//Start Game button Event Scenecontroller.setstate (New Fightstate ("Fightscene", Scenecontroller));//set to combat State (combat Scene)}} using UnityEngine;
Using System.Collections;
Using Unityengine.ui;
<summary>//Third State (Combat scene)///</summary> public class Fightstate:iscenestate {//<summary> Start interface (state) Construction method///</summary>//<param name= "Scenename" > Scene name </param>//<param name = "Scenecontroller" > Scene Controller </param> Public fightstate (String scenename, Scenestatecontroller Scenecontroller)
: Base (Scenename, Scenecontroller) {} Private button returnmenubtn;//return button public override void Statestart () { RETURNMENUBTN = Gameobject.find ("Returnmenubutton").
Getcomponent<button> (); ReturnMenuBtn.onClick.AddListener (Onreturnmenubtndown); Add Return main Menu button event listener private void Onreturnmenubtndown () {//Return button click event scenecontroller.setstate (New Mainmenusta
Te ("MainMenu", Scenecontroller));//Set scene as Main menu scene}}
2.3 UML Diagram of Scene state mode (above is given, not repeat)
2.4 Development Status switch (scene switching) function:
The code is implemented in the Scenestatecontroller scene manager class.
2.5 Controlling the animation playback of the start scene:
Since it is the beginning of the animation of the scene, that is in the beginning of the scene state to do, so the specific code is implemented in the Startstate class (also is a Color.lerp () method).
2.6 switch from the start State to the main menu state:
Design is when the beginning of the animation will go into the main menu scene, so the specific code is also reflected in the startstate.
2.7 Design the main menu interface and the battle scene switch:
Mainly in the main menu screen click the Start Game button and then into the battle scene. So in the main menu interface binding start the game button click event, click into the battle scene.
Note: The entire demo project I will put on GitHub, can download the study: https://github.com/MrZhiFu/Design-Patterns-In-the-game; Recommended download compressed file form