任务8:前端-登录注册界面和使用UI组件及ReferenceCollector
为了方便大家练习,本节提供了登录注册界面资源,下载后放到\Assets\Bundles\Landlords\目录下。
使用ReferenceCollector脚本为游戏物体绑定游戏资源
Global下面创建UI空物体
使用ReferenceCollector脚本添加引用绑定Canvas在UI物体上
绑定方法是:
- 选择需要添加引用绑定的物体,给他挂ReferenceCollector脚本。
- 拖动层级面板中的物体到右边Reference组件上面“添加引用”下方的空白处,即可挂载绑定元件。
Global下面创建一个Camera
设置为Depth only,UI,Orthographic
把Camera作为Canvas的渲染相机
Bundles>picture 下有Loading图片设置为Sprite。
在层级面板中,Canvas下创建一个Image,把上面的Loading_bg作为Source
LandLogin界面的元件绑定
注意一下啊,可能你下载界面资源到你的项目目录,用unity打开项目后,出现丢失脚本的问题,
你需要对照上面的图都一一重新挂好ReferenceCollector脚本,并挂载好界面元件。
而且需要一一把丢失脚本的元件都挂好ReferenceCollector脚本并挂载好绑定元件,再保存,不然是保存不了的。
在前端的Init.cs中添加UI组件和调用初始场景界面
\Assets\Model\Init.cs
//添加UI组件 Game.Scene.AddComponent<UIComponent>(); //执行斗地主初始事件,也就是创建LandLogin界面 Game.EventSystem.Run(UIEventType.LandInitSceneStart);
Run的参数UIEventType.LandInitSceneStart是如何关联到我们定义的事件方法的呢?
如下图,我们只需要给定义的事件方法加上[Event(UIEventType.LandInitSceneStart)]特性,就可以用Game.EventSystem.Run() 方法调用对应的事件方法。(接下来UIEventType.cs中有定义)
在前端添加UIEventType
\Assets\Model\Landlords\LandUI\UIEventType.cs
using System; using System.Collections.Generic; namespace ETModel { public static partial class LandUIType { public const string LandLogin = "LandLogin"; } public static partial class UIEventType { public const string LandInitSceneStart = "LandInitSceneStart"; } [Event(UIEventType.LandInitSceneStart)] public class InitSceneStart_CreateLandLogin : AEvent { public override void Run() { Game.Scene.GetComponent<UIComponent>().Create(LandUIType.LandLogin); } } }
添加登录注册界面的工厂类LandLoginFactory
上面我们使用 Game.Scene.GetComponent<UIComponent>().Create(LandUIType.LandLogin) 即是调用LandLoginFactory创建了登录注册界面。
这是如何做到的呢?
ETCore帮我们实现了对程序集中有定义了[UIFactory(LandUIType.LandLogin)]特性的类对象的Create方法的调用。
\Assets\Model\Landlords\LandUI\LandLogin\LandLoginFactory.cs
using System; using UnityEngine; namespace ETModel { [UIFactory(LandUIType.LandLogin)] public class LandLoginFactory:IUIFactory { public UI Create(Scene scene, string type, GameObject parent) { try { //加载AB包 ResourcesComponent resourcesComponent = Game.Scene.GetComponent<ResourcesComponent>(); resourcesComponent.LoadBundle($"{type}.unity3d"); //加载登录注册界面预设并生成实例 GameObject bundleGameObject = (GameObject)resourcesComponent.GetAsset($"{type}.unity3d", $"{type}"); GameObject landLogin = UnityEngine.Object.Instantiate(bundleGameObject); //设置UI层级,只有UI摄像机可以渲染 landLogin.layer = LayerMask.NameToLayer(LayerNames.UI); UI ui = ComponentFactory.Create<UI, GameObject>(landLogin); ui.AddComponent<LandLoginComponent>(); return ui; } catch (Exception e) { Log.Error(e); return null; } } public void Remove(string type) { Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle($"{type}.unity3d"); } } }
添加LandLoginComponent组件
上面在LandLogin工厂中创建了登录界面:
UI ui = ComponentFactory.Create<UI, GameObject>(landLogin);
ui.AddComponent<LandLoginComponent>();
这就是ETCore的UI组件的用法:
- 传入UI实例创建UI实体
- UI实体添加UI组件
- 在UI组件中获取UI的绑定元件和添加事件方法等
借助ReferenceCollector 组件,获取绑定引用
ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>()
例如LandLoginComponent,UI组件的父对象是UI实体,UI实体持有UI实例,再获取实例上的ReferenceCollector脚本组件。
\Assets\Model\Landlords\LandUI\LandLogin\LandLoginComponent.cs
using UnityEngine; using UnityEngine.UI; namespace ETModel { [ObjectSystem] public class LandLoginComponentAwakeSystem : AwakeSystem<LandLoginComponent> { public override void Awake(LandLoginComponent self) { self.Awake(); } } public class LandLoginComponent : Component { //提示文本 public Text prompt; public InputField account; public InputField password; //是否正在登录中(避免登录请求还没响应时连续点击登录) public bool isLogining; //是否正在注册中(避免登录请求还没响应时连续点击注册) public bool isRegistering; public void Awake() { ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>(); //初始化数据 account = rc.Get<GameObject>("Account").GetComponent<InputField>(); password = rc.Get<GameObject>("Password").GetComponent<InputField>(); prompt = rc.Get<GameObject>("Prompt").GetComponent<Text>(); this.isLogining = false; this.isRegistering = false; //添加事件 rc.Get<GameObject>("LoginButton").GetComponent<Button>().onClick.Add(() => LoginBtnOnClick()); rc.Get<GameObject>("RegisterButton").GetComponent<Button>().onClick.Add(() => RegisterBtnOnClick()); } public void LoginBtnOnClick() { if (this.isLogining || this.IsDisposed) { return; } this.isLogining = true; } public void RegisterBtnOnClick() { if (this.isRegistering || this.IsDisposed) { return; } this.isRegistering = true; } } }
大功告成,Unity中Play运行,就可以看到登录注册界面了!