GameFrameWork框架(Unity3D)使用笔记(三)ProcedureMenu

Unity Game FrameWork—模块使用—框架组件简要说明 Global Helper为相关配置为数据(文本,xml,json等)解析方式,其他组件的Helper选项配置,均为数据加载以及解析的结构定义,框架提供了一套默认的解析方式。UI也有分组,需注意。数据表使用的是框架默认的解析方式DefaultDataTableHelper,如果我们数据表定义的结构和Demo默认的不一样,这个时候我们需要扩展自己的数据解析脚本,并选择自定义的解析方式。调试窗口没必要纠结,使用默认的即可,如果有新的需求可以看具体的框架逻辑去修改,当然也有很多其他的调试工具和调试手段可以使用。 阅读详情

前言:

        前面已经成功通过ProcedureChangeScene流程转到了菜单流程,并且能够成功加载出菜单场景。

        但是目前菜单场景里面空无一物,这篇的主要内容就是加载出菜单UI。所以这一次又会用到框架里的一个新的模块——UI。


前置准备:

背景图

一张场景的背景图:

然后在Menu场景里面装上背景图(创建材质,Shader选择为Unlit/Texture然后选上背景图):

然后挂到场景的一个Quad板子上:

UI预制体

然后就直接在这个场景里面拼UI,创建一个Canvas改名为MenuForm:

然后拼一个极丑UI:

但是嘞,看StarForce的菜单UI就会发现一些事情:

它的UI中的文字内容有点奇怪,比如开始是:Menu.StartButton。我猜测最终显示之前,框架会对UI的这些文字内容进行替换(为了方便配置本地化语言之类的吧)。

不过这次先不搞本地化了。。。

 然后就是按钮逻辑。

StarForce作者是真的强,按钮组件是自己写的:

阅读一下它的源码,分析一波菜单UI的组织结构:

首先它的每个按钮都挂上了CommonButton类,这样就可以如上面的图里面Inspector里面那样选择脚本的函数挂到按钮的点击等事件上。

然后按钮的点击事件(逻辑)的实现,都在当前UI页面的一个类里面。比如菜单页面就是在MenuForm.cs里面:

然后我们再分析这个类的内容,可以看到每个Ui面板的类都继承自UGuiForm类:

而UGuiForm是StarForce中实现的,继承自框架中UIFormLogic类的一个抽象类:

UIFormLogic类主要管理了界面的逻辑(外部自定义的UI界面主要通过继承这个类来受到框架管理),比如初始化要干啥,关闭的时候要干啥,每一帧要轮询干啥,界面激活的时候要干啥等等。可以通过重写对应的一些函数自定义一个界面的逻辑,如下为部分函数截图: 

然后UGuiForm类是StarForce作者大佬自己封装的一个继承自UIFormLogic的抽象类。。。里面加了一些功能比如对本界面进行Text的本地化,字体设置,开关界面的渐变效果等。。。

行呗,开始复刻(抄)!

首先,按钮我们就不写新的脚本了,就用UnityEngine内置的Button组件。

然后再照着StarForce完成UGuiForm抽象类(好叭就是复制过来删改一些东西)(其实直接写界面类继承UIFormLogic也可以运行,但是后期扩展不方便)。

不过里面有些函数需要仿照StarForce里面的UIExtension.cs类对UIComponent进行扩展,也出现了其他封装的类。这里就不复刻了否则的话感觉花在学大佬封装的精力都远超学习框架了。

最终修改完的UGuiForm的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;

namespace ShadowU
{
    public abstract class UGuiForm : UIFormLogic
    {
        public const int DepthFactor = 100;
        private const float FadeTime = 0.3f;

        //private static Font s_MainFont = null;
        private Canvas m_CachedCanvas = null;
        private CanvasGroup m_CanvasGroup = null;
        private List<Canvas> m_CachedCanvasContainer = new List<Canvas>();

        public int OriginalDepth
        {
            get;
            private set;
        }

        public int Depth
        {
            get
            {
                return m_CachedCanvas.sortingOrder;
            }
        }

        public void Close()
        {
            Close(false);
        }

        public void Close(bool ignoreFade)
        {
            StopAllCoroutines();

            if (ignoreFade)
            {
                GameEntry.UI.CloseUIForm(this.UIForm);
            }
            else
            {
                StartCoroutine(CloseCo(FadeTime));
            }
        }
        /*
        public void PlayUISound(int uiSoundId)
        {
            GameEntry.Sound.PlayUISound(uiSoundId);
        }
        */
        /*
        public static void SetMainFont(Font mainFont)
        {
            if (mainFont == null)
            {
                Log.Error("Main font is invalid.");
                return;
            }

            s_MainFont = mainFont;
        }*/

#if UNITY_2017_3_OR_NEWER
        protected override void OnInit(object userData)
#else
        protected internal override void OnInit(object userData)
#endif
        {
            base.OnInit(userData);

            m_CachedCanvas = gameObject.GetOrAddComponent<Canvas>();
            m_CachedCanvas.overrideSorting = true;
            OriginalDepth = m_CachedCanvas.sortingOrder;

            m_CanvasGroup = gameObject.GetOrAddComponent<CanvasGroup>();

            RectTransform transform = GetComponent<RectTransform>();
            transform.anchorMin = Vector2.zero;
            transform.anchorMax = Vector2.one;
            transform.anchoredPosition = Vector2.zero;
            transform.sizeDelta = Vector2.zero;

            gameObject.GetOrAddComponent<GraphicRaycaster>();
            /*
            Text[] texts = GetComponentsInChildren<Text>(true);
            for (int i = 0; i < texts.Length; i++)
            {
                texts[i].font = s_MainFont;
                if (!string.IsNullOrEmpty(texts[i].text))
                {
                    texts[i].text = GameEntry.Localization.GetString(texts[i].text);
                }
            }*/
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnRecycle()
#else
        protected internal override void OnRecycle()
#endif
        {
            base.OnRecycle();
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnOpen(object userData)
#else
        protected internal override void OnOpen(object userData)
#endif
        {
            base.OnOpen(userData);

            m_CanvasGroup.alpha = 0f;
            StopAllCoroutines();
            StartCoroutine(FadeToAlpha(m_CanvasGroup,1f, FadeTime));
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnClose(bool isShutdown, object userData)
#else
        protected internal override void OnClose(bool isShutdown, object userData)
#endif
        {
            base.OnClose(isShutdown, userData);
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnPause()
#else
        protected internal override void OnPause()
#endif
        {
            base.OnPause();
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnResume()
#else
        protected internal override void OnResume()
#endif
        {
            base.OnResume();

            m_CanvasGroup.alpha = 0f;
            StopAllCoroutines();
            StartCoroutine(FadeToAlpha(m_CanvasGroup,1f, FadeTime));
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnCover()
#else
        protected internal override void OnCover()
#endif
        {
            base.OnCover();
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnReveal()
#else
        protected internal override void OnReveal()
#endif
        {
            base.OnReveal();
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnRefocus(object userData)
#else
        protected internal override void OnRefocus(object userData)
#endif
        {
            base.OnRefocus(userData);
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
#else
        protected internal override void OnUpdate(float elapseSeconds, float realElapseSeconds)
#endif
        {
            base.OnUpdate(elapseSeconds, realElapseSeconds);
        }

#if UNITY_2017_3_OR_NEWER
        protected override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
#else
        protected internal override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
#endif
        {
            int oldDepth = Depth;
            base.OnDepthChanged(uiGroupDepth, depthInUIGroup);
            // int deltaDepth = UGuiGroupHelper.DepthFactor * uiGroupDepth + DepthFactor * depthInUIGroup - oldDepth + OriginalDepth;
            int deltaDepth = 10000 * uiGroupDepth + DepthFactor * depthInUIGroup - oldDepth + OriginalDepth; //直接把StarForce里面的值替换过来了
            GetComponentsInChildren(true, m_CachedCanvasContainer);
            for (int i = 0; i < m_CachedCanvasContainer.Count; i++)
            {
                m_CachedCanvasContainer[i].sortingOrder += deltaDepth;
            }

            m_CachedCanvasContainer.Clear();
        }

        private IEnumerator CloseCo(float duration)
        {
            yield return FadeToAlpha(m_CanvasGroup,0f, duration);
            GameEntry.UI.CloseUIForm(this.UIForm);
        }
        /// <summary>
        /// 从StarForce的UIExtension.cs里面搬过来改改的
        /// </summary>
        /// <param name="canvasGroup"></param>
        /// <param name="alpha"></param>
        /// <param name="duration"></param>
        /// <returns></returns>
        private IEnumerator FadeToAlpha(CanvasGroup canvasGroup, float alpha, float duration)
        {
            float time = 0f;
            float originalAlpha = canvasGroup.alpha;
            while (time < duration)
            {
                time += Time.deltaTime;
                canvasGroup.alpha = Mathf.Lerp(originalAlpha, alpha, time / duration);
                yield return new WaitForEndOfFrame();
            }

            canvasGroup.alpha = alpha;
        }
    }
}

然后写MenuForm.cs(因为我这里没有学StarForce里面那样写CommonButton组件,所以这里对于按钮事件的添加就采用public拖动变量的方法):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace ShadowU
{
    public class MenuForm : UGuiForm
    {
        public Button button_start;
        public Button button_settings;
        public Button button_about;
        public Button button_quit;


        private ProcedureMenu m_procedureMenu = null;
        
        private void OnStartButtonClick()
        {
            m_procedureMenu.StartGame();
        }
        private void OnSettingsButtonClick()
        {

        }
        private void OnAboutButtonClick()
        {

        }
        private void OnQuitButtonClick()
        {

        }

        protected override void OnOpen(object userData)
        {
            base.OnOpen(userData);
            m_procedureMenu = (ProcedureMenu)userData;
            if(m_procedureMenu == null)
            {
                Log.Warning("ProcedureMenu is invalid  when opening Menu");
                return;
            }

           
        }

        protected override void OnInit(object userData)
        {
            base.OnInit(userData);

            //添加按钮事件
            button_start.onClick.AddListener(OnStartButtonClick);
            button_settings.onClick.AddListener(OnSettingsButtonClick);
            button_about.onClick.AddListener(OnAboutButtonClick);
            button_quit.onClick.AddListener(OnQuitButtonClick);

        }
    }

}

(顺便在菜单流程里面加了个开始游戏方法(待完成)):

using GameFramework.Fsm;
using UnityGameFramework.Runtime;

namespace ShadowU
{
    public class ProcedureMenu :ProcedureBase
    {
        public override bool UseNativeDialog
        {
            get
            {
                return true;
            }
        }
        public void StartGame()
        {
            Log.Debug("开始游戏!"); 
        }
        protected override void OnEnter(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner)
        {
            base.OnEnter(procedureOwner);

            Log.Debug("成功转到菜单流程");
           
            
        }
    }
}


然后我们把写好的MenuForm挂到拼好的菜单UI界面上,并且把按钮拖进去:

然后把做好的页面拖成预制体放到UIForms目录下:


ProcedureMenu菜单流程

终于我们可以回到ProcedureMenu里面继续了。在OnEnter里面注册加载UI成功的事件,设置游戏开始的标志为false,然后打开UI界面:

using GameFramework.Fsm;
using UnityGameFramework.Runtime;
using GameFramework.Event;
namespace ShadowU
{
    public class ProcedureMenu :ProcedureBase
    {
        private bool m_StartGame = false;
        //private MenuForm m_MenuForm;
        public override bool UseNativeDialog
        {
            get
            {
                return true;
            }
        }
        public void StartGame()
        {
            Log.Debug("开始游戏!"); 
        }
        protected override void OnEnter(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner)
        {
            base.OnEnter(procedureOwner);

            Log.Debug("成功转到菜单流程");

            GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);

            m_StartGame = false;

            //打开菜单界面
            GameEntry.UI.OpenUIForm(AssetUtility.GetUIFormAsset("MenuForm"),"Default");

           
        }

        protected override void OnLeave(IFsm<GameFramework.Procedure.IProcedureManager> procedureOwner, bool isShutdown)
        {
            base.OnLeave(procedureOwner, isShutdown);

            GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);

            /*
            if (m_MenuForm != null)
            {
                m_MenuForm.Close(isShutdown);
                m_MenuForm = null;
            }
            */
        }
        private void OnOpenUIFormSuccess(object sender, GameEventArgs e)
        {
            OpenUIFormSuccessEventArgs ne = (OpenUIFormSuccessEventArgs)e;
            if (ne.UserData != this)
            {
                return;
            }

           // m_MenuForm = (MenuForm)ne.UIForm.Logic;
        }
    }
}


细心点可以注意到框架中OpenUIForm函数第二个参数需要UIGroup,我写的是"Default"。如果现在运行的话,会报错,界面并不会加载出来。因为这里需要在场景里框架预制体的子物体UI中设置一下,添加个UI组Default:

最后运行:

按钮可以点击,但是开始按钮点击后报错了。。。。(如果按钮没反应检查Menu场景是否加了EventSystem) 很显然是m_procedureMenu没有获取成功。原因是ProcedureMenu里面打开Form的函数用得不对:

用这个方法的话传入的userData就是为空null:

所以最终传给MenuForm里面OnOpen函数的userData也是空的了:

所以我们改一下打开界面函数为这样:

(优先级1随便设置的设的不好别怪我)

然后再运行看看结果:

终于  搞定了

 

 

 

        

 

 

 

 

 

 

 

 

 

 

 

 

 

Unity3D开发小贴士(六)Lua里调用C#扩展 C#语法小知识(八)扩展介绍过如何扩展C#的类型,Unity3D开发小贴士(五)Lua调用C#里介绍了如何使用ToLua插件在Lua脚本里调用C#代码。那么本文介绍一下如何在Lua里调用C#类型的扩展方法。 阅读详情

相关推荐

GameFramework框架 (五)UI组件

GameFramework框架 UI组件

weixin_36961960的博客 2654

Unity常用函数扩展(一)—— GetOrAddComponent()

实现获取Transform或者GameObject上的组件,若获取不到则自动添加该组件

纸飞机 2494

【Unity3D框架】GameFramework框架完全教程《全网最全》-专栏文章目录

最近准备学习框架,了解到GameFramework框架是国产Unity3D框架,准备学习一下,但是奈何全网关于这个框架的教程实在太少。为了让自己学习方便一些,也为了让后来者乘凉。将框架以自己的理解整理目录,并且补全教程。觉得教程有帮助别忘了一键三连哦。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2万+

【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)

【Unity 3D】GameFramework、QFramework框架简介及应用实战(超详细 附源码)

showswoller的博客 1万+

GameFramework教程✨一、本专栏概述及注意事项

大家好,我是SKODE。 小提示:选中左侧目录,可快速找到所需内容 本系列博客地址:传送门

星河造梦坊 7756

GameFramework教程✨三、流程

大家好,我是SKODE。 小提示:选中左侧目录,可快速找到所需内容 本系列博客地址:传送门 E大该章链接:传送门 一、什么是流程 贯穿游戏运行时整个生命周期的有限状态机。通过流程,将不同的游戏状态进行解耦将是一个非常好的习惯。对于网络游戏,你可能需要如检查资源流程、更新资源流程、检查服务器列表流程、选择服务器流程、登录服务器流程、创建角色流程等流程,而对于单机游戏,你可能需要在游戏选择菜单流程和游戏实际玩法流程之间做切换。如果想增加流程,只要派生自 ProcedureBase 类并实现..

星河造梦坊 6126

GameFrameWork框架(Unity3D)使用笔记(四)ProcedureMenu更多的界面

主菜单及各个界面之间切换的几个功能基本完成。中间鸽了几天用来解决中间遇到的bug了,解决过程中读了大量源码,理解得到了进一步提升。

HowToPause的博客 2313

Agent测试框架Harbor指南

Harbor是一个AI Agent单元测试框架,用于自动化测试AI代理在容器环境中的任务执行能力。它支持18+种AI代理,通过沙箱隔离和自动验证机制评估任务完成情况。任务必须具有可编程验证的输出结果,适合代码、数据、系统等可量化任务,不适合创意写作等主观任务。Harbor采用CLI操作方式,核心架构包含Job管理、Trial执行和验证器三个层级,执行流程包括环境启动、Agent执行和结果验证。任务目录包含指令文件、配置文件、Docker环境定义和测试脚本等必需组件,通过测试脚本自动判断任务完成质量。

loo_Charles_ool的博客 1401

Unity GameFramework StarForce 流程介绍

根据提供的案例参考即可实现自己的组件。

zzzsss123333的博客 1558

Auto.js凉了之后,我们该用啥?AutoX.js保姆级环境搭建与第一个脚本实战(2024最新)

本文详细介绍了AutoX.js作为Auto.js替代方案的环境搭建与脚本开发实战指南。从技术生态现状分析到2024最新环境配置,再到编写第一个实用脚本和进阶调试技巧,帮助开发者无缝迁移至AutoX.js平台。特别适合需要手机自动化的JavaScript开发者,涵盖从基础到企业级应用的全套解决方案。

weixin_28737073的博客 389

大数据实时+离线项目架构----智慧物流大数据平台(超流行框架!)

智慧物流大数据平台 文章目录智慧物流大数据平台一、项目背景二、逻辑架构三、解决方案技术亮点:数据流转四、项目的技术选型4.1流式处理平台4.2 分布式计算平台4.3 海量数据存储框架软件版本总结 一、项目背景 本项目基于一家大型物流公司研发的智慧物流大数据平台。该物流公司是国内综合性快递、物流服务商,并在全国各地都有覆盖的网点。经过多年的积累、经营以及布局,拥有大规模的客户群,日订单达上千万。如此规模的业务数据量,传统的数据处理技术已经不能满足企业的经营分析需求。公司需要基于大数据技术构建数据中心,从而挖

weixin_48143996的博客 6430

Unity拓展方法

合理运用Unity的一些拓展方法可使代码更简洁,还能提升工作效率! using UnityEngine; //这里要用静态,否则会报错 static class UnityExtension { static public T GetOrAddComponent<T>(this GameObject go) where T : Component { T...

Dr.long-成龙的博客 415

cmu15445(2024fall) project 2

project 2比p1难度要更大,代码量更大且涉及的知识更多,实现中出现的bug更多,好在是最后全部解决了。我最大的收获在于对于多线程编程的理解更深入了,实际发现解决了多个多线程相关的bug,学会了更多多线程下debug的技巧方法,也见识了更多多线程的bug情况。在之后可以更系统的学习一下多线程编程。同时学会实现B+树也是需要掌握的基础。

Jerome_Yi的博客 1559

Unity UI框架

初始化 在场景中挂载一个脚本,用于创建初始界面 using UnityEngine; //创建开始界面 public class CreateStartPanel : MonoBehaviour { //管理面板顺序的栈 PanelStack panelStack; void Awake() { panelStack = new PanelStack(); } void Start() { panelS.

海月的博客 9260

Cadence 17.4 PSpice仿真555定时器输出方波

这里利用555定时器组成多谐振荡器产生1Hz的方波并用PSpice仿真其输出的方波波形。555定时器是一种广泛应用的中规模集成电路。根据其内部组成的不同,可分为双极型(555B)和CMOS型(555C)两类。两种类型的定时器各有所长。双极型定时器具有较大的驱动能力,其输出电流可达200mA,可直接驱动发光二级管、扬声器、继电器等负载。而CMOS型定时器的输入阻抗高、功耗低。

tj_nonstoper的博客 1万+

horizon之为connection服务器配置证书

打开connection1服务器(connection2 同connection1)再输入connection1的IP地址 可通过域名和IP地址进行登录。这时候用域名登录就发现证书已经没有警告了。win+R 调出“运行”,输入mmc。connection2 同上。如果还有报错请重启一下服务器。打开connection1。可以把这个先删掉 没用。打开DC_01服务器。右键选择证书颁发机构。友好名称只能是vdm。重启之后就没有报错了。

送个祝福给小豪的博客 2960

Unity开发——UGUI框架搭建

Unity:2021.1.14flc1 在B站跟着视频 [Unity编程]这大概是最好理解的UI框架了吧搭建的一个UGUI的框架,处理了一些小问题,参考MissingReferenceException: The object of type ‘GameObject‘ has been destroye 整个框架分层比较乱,而且实际运行的话要根据你在unity工程里面具体的资源放置来修改代码里的资源路径,所以这里主要是给我自己做个记录 UIType.cs /* 存储单个UI的信息,包括名字和路径 */

jhin_lx的博客 2044

驯服电源尖峰:从BUCK/BOOST环路剖析到高di/dt噪声的实战抑制

本文深入探讨了电源系统中高di/dt噪声的产生机制及抑制方法,通过BUCK/BOOST电路的环路分析,揭示了电流路径不连续导致的电压尖峰问题。文章提供了实用的PCB布局技巧和噪声抑制策略,包括最短回路原则、铺铜优化和过孔阵列战术,帮助工程师有效降低EMI噪声,提升电源系统的稳定性。

weixin_29587015的博客 273

【Unity】简单的UI框架

最近在写项目,但是模型比较慢,之前一直是硬写程序,也有用过其他人的框架,现在自己在B站上看了一些视频,也搜了一些文章,写了几天的简单框架,有一些心得,发出来,让大家看一看,有什么问题的大家多喷一下哈 核心的类有如下几个: UIType:物体的基本属性,包含名称和地址。 public class UIType { public string Name { get; private set; } public string Path { get; private set; } ...

好吃的和好看的都需要用实力来争取 1163

Libero SoC v2021.1离线安装与IP核配置全攻略

本文详细介绍了Libero SoC v2021.1在离线环境下的完整安装与配置流程。核心内容包括如何选择正确的离线安装包、获取并配置许可证、安装与挂载MegaVault IP库,以及将ModelSim仿真器切换至免费SE模式的关键步骤。文章旨在帮助内网开发者避开常见陷阱,顺利完成FPGA开发环境的搭建。

weixin_29279101的博客 406

AccessData FTK Imager_x64_4.2.0 含中文语言包

AccessData FTK Imager是经典的windows硬盘取证工具,可用于分析外来人员或者外来入侵人员对机器的操作,从中追踪溯源。此为安装版,可以减少很多不必要的麻烦。同时打包了中文语言包,直接使用中文版。

Unity Game FrameWork—模块使用—Event事件

除了 Game Framework 内置事件外,使用者也可以定义自己的游戏逻辑事件,游戏中所有事件均派生自GameEventArgs 类,事件对象使用了引用池技术,以避免使用事件过程中频繁的内存分配。注意:OpenUIFormSuccessEventArgs这个事件是UI打开事件,不单是菜单界面,其他界面可能也会注册事件,那怎么区分是哪个页面打开的事件呢?看一下下图的源码,传入的this就是userData参数,userData用来创建事件,赋值给事件的属性了。官方说明:游戏逻辑监听、抛出事件的机制。

qq_37619255的博客 904

FBG-SimPlus-comsol_comsol_matlab_FBG.zip

FBG-SimPlus-comsol_comsol_matlab_FBG.zip

Unity简单操作:Unity中添加组件的几种方法

一、在编辑器上面添加一个组件。这个不用多说。 二、在脚本中利用AddComponent函数添加一个组件,例如: usingUnityEngine; usingSystem.Collections; publicclassCharacterSpawner:MonoBehaviour{ publicvoidSpawn(GameObjectCharacterSlected){ if(CharacterSlected){ GameOb...

weixin_39114763的博客 1万+

JEDEC PUBLICATION 95 (JEP95) 4.23.pdf

JEDEC PUBLICATION 95 (JEP95) 4.23.pdf

Excel数据清洗工具

Excel数据清洗工具是一款专为Excel文件设计的数据处理软件。它可以有效地帮助用户完成一系列的数据清洗任务,如删除重复值、处理缺失值、格式化数据等。无论是单个文件还是整个文件夹中的多个文件,这款工具都能够轻松应对。功能强大- 删除重复值:重复数据不仅浪费存储空间,还会导致统计结果失真。该工具可以一键删除所有列完全相同的重复记录,确保数据的唯一性。- 处理缺失值:缺失值是数据清洗中的常见问题。该工具支持填充或删除缺失值,甚至可以根据用户的需求自定义填充值。- 格式化数据:对于日期和数值等数据类型,统一格式是进行后续分析的前提。工具提供了日期数据和数值数据的格式化功能。- 去除空格和非打印字符:文本数据中的多余空格或非打印字符可能会影响数据的正确性,该功能可以有效清理这些字符。- 数据验证:确保数据满足一定的约束条件,如数值范围等,从而保证数据的有效性。

Unity复制组件和移除组件,以及删除本地资源文件

删除项目中的资源:File.Delete(path); //注意Path是相对路径,Assets/xxx Unity中只有AddComponent,没有RemoveComponent。移除组件如果是运行中用Destroy,如果是编辑器脚本用DestroyImmediate。 DestroyImmediate(component, true); //第一个参数是组件类型,后面的bool参数是是否允许销毁资源。 ...

lcy的博客 7938

在 Unity 中,添加组件的两种方式

在 Unity 中,添加组件有两种方式。

qq_20179331的博客 6316

Unity Game FrameWork—模块使用—UI组件

官方解释:提供管理界面和界面组的功能,如显示隐藏界面、激活界面、改变界面层级等。不论是 Unity 内置的 uGUI 还是其它类型的 UI 插件(如 NGUI),只要派生自 UIFormLogic 类并实现自己的界面类即可使用。界面使用结束后可以不立刻销毁,从而等待下一次重新使用。制作UI预制件,以及添加UI交互逻辑这一块就不说了,任意一个UI界面都需要这样的操作。

qq_37619255的博客 1806

【Unity】Game Framework框架学习使用

这篇文章主要是自己学习GameFramework的时候的一些使用心得

好吃的和好看的都需要用实力来争取 4665
上一篇: GameFrameWork框架(Unity)学习资料汇总(持续更新)
下一篇: 按钮Button点击后页面刷新咋办?(Web;Html;Css;Javascript)
咖啡咖_CoffCa
博客等级 码龄6年 116粉丝 58原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咖啡咖_CoffCa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值