Advanced ET Unity of online game development framework 02-ET client start process analysis

Copyright notice:

  • This article Original starting in the following website:
  1. Blog Park "excellent dream maker culture" in space: https: //www.cnblogs.com/raymondking123
  2. Excellent dream maker culture official blog: https: //91make.top
  3. Excellent game dream maker culture lecture: https: //91make.ke.qq.com
  4. "Excellent dream maker culture" of micro-channel public number: umaketop
  • You are free to reprint, but must include the full copyright notice!

Everything origin: Init.cs

  • Open the sample scenario init.unity, scenes can be found in its hierarchy as follows:
    • The only important thing is Global objects hanging in the init.cs script, on the basis of its code analysis, or suggest that you look at the tutorial has shown signs of (ghithub have links)
    • Here just want to focus on analyzing a problem everyone will care about: how to load the initial interface is init.cs

init.cs how to load the initial interface:

  • Analysis of the lesson, init.cs UILoading loaded first interface, which is substantially the loading process, the first sequence diagram, later in conjunction with FIG affixed sequence code analysis:
sequenceDiagram Unity - >> + Init: StartAsync Init - >> BundleHelper: DownloadBundle () BundleHelper - >> EventSystem: Run (EventIdType.LoadingBegin) EventSystem - >> LoadingBeginEvent_CreateLoadingUI: Run () LoadingBeginEvent_CreateLoadingUI - >> UILoadingFactory: Create () note right of UILoadingFactory: instantiating UILoading preform, and additional UILoadingComponent (updates and displays the loading progress) Init - >> - Unity: startAsync
  • Loading the initial interface several steps as follows:
  1. Call EventSystem.Run(EventIdType.LoadingBegin)triggered LoadingBegin event:
public static class BundleHelper
{
	public static async ETTask DownloadBundle()
	{
		if (Define.IsAsync)
		{
			try
			{
				using (BundleDownloaderComponent bundleDownloaderComponent = Game.Scene.AddComponent<BundleDownloaderComponent>())
				{
					await bundleDownloaderComponent.StartAsync();

					Debug.Log("EventIdType.LoadingBegin");
					Game.EventSystem.Run(EventIdType.LoadingBegin);
					
					await bundleDownloaderComponent.DownloadAsync();
				}
				
				Game.EventSystem.Run(EventIdType.LoadingFinish);
				
				Game.Scene.GetComponent<ResourcesComponent>().LoadOneBundle("StreamingAssets");
				ResourcesComponent.AssetBundleManifestObject = (AssetBundleManifest)Game.Scene.GetComponent<ResourcesComponent>().GetAsset("StreamingAssets", "AssetBundleManifest");
			}
			catch (Exception e)
			{
				Log.Error(e);
			}

		}
	}
}
  • Because in unity editor environment IsAsync flag is set to false (selected in the VS environment IsAsync members, right → Glance definition is visible), that is asynchronous loading of resources was seen loading screen, so will not actually see the loading screen!
  • After waiting 19 acts asynchronously loaded trigger LoadingFinish event, the process is similar to the LoadingBegin, ask someone their own analysis!
  1. Achieve LoadingBegin event handler:

     [Event(EventIdType.LoadingBegin)]
     public class LoadingBeginEvent_CreateLoadingUI : AEvent
     {
     	public override void Run()
     	{
     		UI ui = UILoadingFactory.Create();
     		Game.Scene.GetComponent<UIComponent>().Add(ui);
     	}
     }
    

    Note that here there is a need to learn a method defined event class: 1. Add a class Event flag (fill particular event type parameter) inherited from AEvent 3. 2. At this time, ET automatically recognized as a class of the event handler class (by reflection), and EventSystem.Runthe implementation of Run method LoadingBeginEvent_CreateLoadingUI event class is called!

  2. The sixth line of code UILoadingFactory.Create()responsible for creating UILoading interface, the following code added a note:

     public static class UILoadingFactory
     {
     	public static UI Create()
     	{
     		try
     		{
     			// KV是Resources文件夹下存储的本地预制体资源,主要存储一些键值对数据
     			// 从KV加载UIType.UILoading预制体,并实例化UI对象:
     			GameObject bundleGameObject = ((GameObject)ResourcesHelper.Load("KV")).Get<GameObject>(UIType.UILoading);
     			GameObject go = UnityEngine.Object.Instantiate(bundleGameObject);
     			go.layer = LayerMask.NameToLayer(LayerNames.UI);
    
     			// 创建UI这个Entity,并将上面创建的UI对象作为该Entity的图形表示
     			UI ui = ComponentFactory.Create<UI, string, GameObject>(UIType.UILoading, go, false);
    
     			// 添加UILoadingComponent,该组件负责更新loading进度并刷新显示
     			ui.AddComponent<UILoadingComponent>();
     			return ui;
     		}
     		catch (Exception e)
     		{
     			Log.Error(e);
     			return null;
     		}
     	}
     }
    

    Description: - UI class is an Entity class, Entity indirectly inherited from the Component class, but only Entity class can be add-ons, the Component class does not work - the relationship between Entity and Component is actually the design pattern Composite pattern - UI class can be reused, when when you want to create a UI, in the framework of long ET: - adding a static factory classes of UI, and define a static Create method, with reference to the specific implementation UILoadingFactory - Add a new UI component for the plant (from component class inheritance), and implement the system on which the event (see below)

  3. UILoadingComponent achieve and implement the system event components:

    • UILoading components
     public class UILoadingComponent : Component
     {
     	public Text text;
     }
    
    • UILoading Event System:
     [ObjectSystem]
     public class UiLoadingComponentAwakeSystem : AwakeSystem<UILoadingComponent>
     {
     	public override void Awake(UILoadingComponent self)
     	{
     		self.text = self.GetParent<UI>().GameObject.Get<GameObject>("Text").GetComponent<Text>();
     	}
     }
    
     [ObjectSystem]
     public class UiLoadingComponentStartSystem : StartSystem<UILoadingComponent>
     {
     	public override void Start(UILoadingComponent self)
     	{
     		StartAsync(self).Coroutine();
     	}
    
     	public async ETVoid StartAsync(UILoadingComponent self)
     	{
     		TimerComponent timerComponent = Game.Scene.GetComponent<TimerComponent>();
     		long instanceId = self.InstanceId;
     		while (true)
     		{
     			await timerComponent.WaitAsync(1000);
    
     			if (self.InstanceId != instanceId)
     			{
     				return;
     			}
    
     			BundleDownloaderComponent bundleDownloaderComponent = Game.Scene.GetComponent<BundleDownloaderComponent>();
     			if (bundleDownloaderComponent == null)
     			{
     				continue;
     			}
     			self.text.text = $"{bundleDownloaderComponent.Progress}%";
     		}
     	}
     }
    

    Defined event class: 1. Add [ObjectSystem] 2. flag corresponding XxxSystem inherited from the class, and implements a virtual base class - Unity event class and similar meanings, see Learning own source

to sum up:

  • By learning UILoading, we have a complete contact with the ECS objects ET:
    • E: Entity, the corresponding UI classes
    • C: Component, the corresponding class UILoadingComponent
    • S: System, and the corresponding UiLoadingComponentAwakeSystem class UiLoadingComponentStartSystem

Guess you like

Origin www.cnblogs.com/raymondking123/p/11369623.html