【unity框架开发起步】一些框架开发思维和工具类封装

embedded/2024/10/15 19:55:45/

文章目录

  • 前言
  • 一、Editor操作
  • 二、快捷导出unity
  • 三、快捷打开存储目录
  • 四、封装概率函数
  • 五、方法过时
  • 六、partial 关键字,拆开合并类
  • 七、从数组中随机取⼀个数值并进⾏返回
    • 1、实现
    • 2、object 类优化
    • 3、泛型,结构复⽤利器
    • 4、params 关键字优化
  • 八、abstract 关键字定义抽象类和抽象方法
    • 1、抽象类
    • 2、抽象方法
  • 完结

前言

游戏开发中,Unity作为一个强大的引擎,提供了丰富的功能和灵活的开发环境。然而,随着项目规模的扩大和复杂度的增加,仅依赖Unity的基本功能往往无法满足高效、可维护的开发需求。因此,建立一个完善的框架,以及进行工具类的封装,成为了每个Unity开发者提升工作效率和项目质量的重要一步。

在本篇文章中,我们将探讨一些基本的框架开发思维,同时介绍如何有效地进行工具类的封装。希望通过这些实践经验,能够帮助你在Unity开发的旅程中打下坚实的基础,提高开发效率,并最终实现更加优秀的游戏作品。无论你是刚入门的初学者,还是有一定经验的开发者,掌握框架思维和工具类封装都将为你的项目带来意想不到的便利和提升。

一、Editor操作

# 菜单按钮
[MenuItem("XYFrame/XYFrame/1.一键打包XYFrame")]# 快捷键调用MenuItem菜单按钮
//最后有个 “ %e”,这个就是快捷键的符号,意思是 ctrl/cmd + e
[MenuItem("XYFrame/XYFrame/1.一键打包XYFrame %e")]# MenuItem菜单按钮排序
//第三个参数,意思是优先级,表示 MenuItem 所在的显示顺序,数值越⼤越在底部。
[MenuItem("XYFrame/XYFrame/2.打开存储目录, false, 1")]# 直接调⽤MenuItem菜单按钮【XYFrame/XYFrame/1.一键打包XYFrame】
EditorApplication.ExecuteMenuItem("XYFrame/XYFrame/1.一键打包XYFrame");# 这⾏代码执⾏之后,会⾃动运⾏Unity
UnityEditor.EditorApplication.isPlaying = true;

如果不⽤ Editor ⽂件夹了,取⽽代之的是在代码中给每个 UnityEditor API 都加上#if UNITY_EDITOR宏判断,这样做的⽬的,是为了不影响⾃⼰所在项⽬打包。放在Editor ⽂件夹就不需要了

#if UNITY_EDITOR
using UnityEditor;
#endif
#if UNITY_EDITOR[MenuItem("XYFrame/XYFrame/1.一键打包XYFrame")]
#endif

unity_36">二、快捷导出unity

using UnityEditor;
using System;namespace XYFrame
{/// <summary>/// 打包XYFrame框架文件夹/// </summary>public class ExportUnityPackage{[MenuItem("XYFrame/XYFrame/1.一键打包XYFrame %e")]private static void MenuClicked(){//要打包的文件夹路径string assetPathName = "Assets/XYFrame";//要导出的文件路径和⽂件名字string fileName = "Assets/XYFrame_" + DateTime.Now.ToString("yyyyMMdd_HH") + ".unitypackage";//获取当前时间//Recurse:递归选项,意思是说包含⼦⽬录。AssetDatabase.ExportPackage(assetPathName, fileName, ExportPackageOptions.Recurse);}}
}

效果
在这里插入图片描述
打包结果
在这里插入图片描述

三、快捷打开存储目录

using UnityEditor;
using UnityEngine;namespace XYFrame
{/// <summary>/// 打开存储目录/// </summary>public class OpenSaveInFolder{[MenuItem("XYFrame/XYFrame/2.打开存储目录")]private static void OpenInSaveFolder(){OpenInFolder(Application.persistentDataPath);}/// <summary>/// 打开某个文件夹/// </summary>/// <param name="folderPath">文件夹路径</param>public static void OpenInFolder(string folderPath){Application.OpenURL("file:///" + folderPath);}}
}

效果
在这里插入图片描述
点击就打开了目录
在这里插入图片描述

四、封装概率函数

输⼊百分⽐返回是否命中概率

/// <summary>
/// 输⼊百分⽐返回是否命中概率
/// </summary>
public static bool Percent(int percent)
{return Random.Range (0, 100) <= percent;
}

调用

Debug.Log(Percent(50));

输出结果为,有⼀半的概率会输出 true。

五、方法过时

一般修改方法时,为了不影响旧版本的使用,我们会做中转,然后提示过时

[Obsolete("⽅法以过时,请使⽤ Exporter.GenerateUnityPackageName();")]
public static string GenerateUnityPackageName()
{//调用新方法位置return Exporter.GenerateUnityPackageName();
}

调用会报警告
在这里插入图片描述
代码编辑器可能也会提示
在这里插入图片描述

六、partial 关键字,拆开合并类

在C#中,partial关键字用于定义一个类、结构或接口的部分实现。这意味着一个类型的定义可以被拆分到多个文件中。这样做的好处是可以使代码更加组织化和易于管理,尤其是在大型项目中。

例如,使用工具自动生成代码时,可以将自动生成的代码与手动编写的代码分开。多个开发者可以同时在不同的文件中工作,而不会相互冲突。

你可以将一个类的实现分散到多个文件中。例如:

// File1.cs
partial class MyClass
{public void MethodA(){// 方法实现}
}// File2.cs
partial class MyClass
{public void MethodB(){// 方法实现}
}

在编译时,编译器会将这些部分合并为一个完整的类MyClass。

partial关键字不仅可以用于类,还可以用于结构体和接口。例如:

// PartialStruct1.cs
partial struct MyStruct
{public int Value;
}// PartialStruct2.cs
partial struct MyStruct
{public void DisplayValue(){Console.WriteLine(Value);}
}

七、从数组中随机取⼀个数值并进⾏返回

1、实现

实现从 int 类型数组中随机取⼀个数值进⾏返回

public static int GetRandomValueFrom(int[] values)
{return values[Random.Range(0, values.Length)];
}

这里只是int类型,如果还有string、float其他类型怎么办?再复制一份代码改改类型吗,当然可以,但是很麻烦。

public static int GetRandomValueFrom(int[] values)
{return values[Random.Range(0, values.Length)];
}
public static string GetRandomValueFrom(string[] values)
{return values[Random.Range(0, values.Length)];
}
public static float GetRandomValueFrom(float[] values)
{return values[Random.Range(0, values.Length)];
}

2、object 类优化

我们可以使用⾯向对象特性(封装、继承、多态)中的继承特性

那么 int、string、float 有没有共同的⽗类?答案是有的,它们共同继承了 object 类。不⽌是int、string、float,C# 中的所有类型都继承了 object 类。

改完的代码如下:

public static object GetRandomValueFrom(object[] values)
{return values[Random.Range(0, values.Length)];
}

调用

var intRandomValue = (int)GetRandomValueFrom(new int[]{1,2,3});
var stringRandomValue = (string)GetRandomValueFrom(new string[]{"asdasd","123123"});
var floatRandomValue = (float)GetRandomValueFrom(new float[]{ 0.1f,0.2f });

调用起来的代码虽然⽐较难看(1.强制类型转换;2.再加上每次传⼊参数都要构造数组;)

使⽤上有⼀点麻烦,不过还好,我们最起码解决了结构重复的问题,⽽且我们还复习了⼀下继承。

这样搞其实还有个问题,就是值类型转引⽤类型会造成效率问题,当然除了使⽤ object 接收,还有更好的⽅法-使⽤泛型

3、泛型,结构复⽤利器

泛型对很多初学者来说是⽐较⾼级的概念,这⾥我们顺便复习⼀下泛型。

泛型是什么呢?对于⽅法来说,⽅法结构中的部分或全部类型都可以先不进⾏定义,⽽是到调⽤⽅法的时候再去定义。

前面的代码通过泛型优化

public static T GetRandomValueFrom<T>(T[] values)
{return values[Random.Range(0, values.Length)];
}

测试调用

var intRandomValue = GetRandomValueFrom(new int[]{1,2,3});
var stringRandomValue = GetRandomValueFrom(new string[]{"asdasd","123123"});
var floatRandomValue = GetRandomValueFrom(new float[]{ 0.1f,0.2f });

从测试调用代码中可以⽐较出来,使⽤泛型之后的代码确实好⽤了很多。

⼤家思考下泛型是不是这样的?结构中的部分或全部类型都可以先不进⾏定义,⽽是到调⽤的时候再去定义。

我们右收获了⼀个法宝泛型。要说⽅法是逻辑上的复⽤,那么泛型就是结构上的复⽤。两⼤复⽤法宝。

4、params 关键字优化

⽬前⽐较麻烦的是数组构造代码了。
这个也是有办法搞定的。我们把⽅法的实现改成如下:

public static T GetRandomValueFrom<T>(params T[] values)
{return values[Random.Range(0, values.Length)];
}

⼤家注意下,参数前边加上了⼀个 params 关键字。这个是什么意思呢?意思是 GetRandomValueFrom 可以传任意数量的参数。

测试调用代码

var intRandomValue = GetRandomValueFrom(1, 2, 3);
var stringRandomValue = GetRandomValueFrom("asdasd", "123123");
var floatRandomValue = GetRandomValueFrom(0.1f, 0.2f);

是不是清爽了很多?这就是 params 的⽤法。

⽽通过 params 修饰的 values 参数来说,如果传⼊的是⼀个数组,那么 values 本身就是这个数组,如果传⼊的是若⼲个值,那么 values 中就包含了这若⼲个值。

总结⼀句话,就是可以传⼀整个数组,也可以传若⼲个参数,设计得⾮常⼈性化。

八、abstract 关键字定义抽象类和抽象方法

  • 使用 abstract 关键字可以创建灵活的类层次结构,允许不同的子类实现特定的行为。
  • 抽象类可以包含常规方法和属性,提供共享功能,而抽象方法则强制子类提供具体实现。

1、抽象类

定义:抽象类不能被实例化,通常作为其他类的基类。
用途:可以包含抽象方法(没有实现)和具体方法(有实现),提供子类共享的基本功能。

public abstract class MonoBehaviourXY
{public abstract void MakeSound(); // 抽象方法,没有实现public void Sleep() // 具体方法,有实现{Debug.Log("The animal is sleeping.");}
}

如果想通过外部实例化 这个MonoBehaviourXY,调用会报错
在这里插入图片描述

2、抽象方法

  • 定义:抽象方法必须在抽象类中声明,并且没有方法体。
  • 用途:强制子类实现这些方法,以便提供特定的功能。
public class Dog : MonoBehaviourXY
{public override void MakeSound() // 实现抽象方法{Debug.Log("Woof!");}
}public class Cat : MonoBehaviourXY
{public override void MakeSound() // 实现抽象方法{Debug.Log("Meow!");}
}

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述


http://www.ppmy.cn/embedded/128039.html

相关文章

产品经理或项目经理考PMP,薪资会不会提高?

你要知道一个事情&#xff0c;薪资和证书不是划等号的。没有公司会为你多一个证书而去给你涨薪&#xff0c;人家也不是傻子。想要提高薪资还得看公司的情况&#xff0c;还有你在公司岗位的价值&#xff0c;自己的能力以及工作上做出的成绩&#xff0c;是跟这些挂钩的。找一家前…

成都爱尔李晓峰主任讲解“寒”已至,眼需“养”

温度逐渐走低&#xff0c;寒冷空气的到来带走夏季闷热潮湿&#xff0c;也带走了空气中的水分&#xff0c;环境变得干燥&#xff0c;眼睛水分蒸发加快&#xff0c;十分容易造成眼部不适&#xff0c;干眼患者尤其需要注意&#xff01; 有干眼问题的患者&#xff0c;在这样的天气下…

Python | Leetcode Python题解之第464题我能赢吗

题目&#xff1a; 题解&#xff1a; class Solution:def canIWin(self, maxChoosableInteger: int, desiredTotal: int) -> bool:cachedef dfs(usedNumbers: int, currentTotal: int) -> bool:for i in range(maxChoosableInteger):if (usedNumbers >> i) & 1…

CSS也可以赋一个变量值?是的

声明一个自定义属性&#xff0c;属性名需要以两个减号&#xff08;--&#xff09;开始&#xff0c;属性值则可以是任何有效的CSS值。 /*:root 选择器匹配文档根元素。*/ /*在 HTML 中&#xff0c;根元素始终是 html 元素。*/ /*也就是说&#xff1a;root 表示的是根元素*///声…

HT878T 可任意限幅、内置自适应升压的2x8.0W立体声音频功放

1、特征 可任意配置的限幅功能 -自由配置音频限制幅度&#xff0c;使输出音频信号限制在 固定失真水平内 内置自动限温控制功能 -适应不同散热条件&#xff0c;避免出现过温关断现象 高效自适应G类升压功能&#xff0c;有效延长播放时间 -可调节最大限流值&#xff0c;有效防止…

第六章 RabbitMQ之Work模式

目录 一、介绍 二、Work模式 三、案例演示 3.1. 案例需求 3.2. 案例代码实现 3.2.1. 创建SpringBoot工程 3.2.2. 父工程pom依赖 3.2.3. 生产者pom依赖 3.2.3. 生产者配置文件 3.2.4. 生产者核心代码 3.2.5. 消费者RabbitMQConfig 3.2.6. 消费者pom依赖 3.2.7. 消…

【bug】finalshell向远程主机拖动windows快捷方式导致卡死

finalshell向远程主机拖动windows快捷方式导致卡死 问题描述 如题&#xff0c;作死把桌面的快捷方式拖到了finalshell连接的服务器面板中&#xff0c;导致finalshell没有响应&#xff08;小概率事件&#xff0c;有时会触发&#xff09; 解决 打开任务管理器查看finalshell进…

AD9680(adc直采芯片)使用说明

写这篇文章之前我是没有使用过AD9680的芯片&#xff0c;但是使用过GMS011芯片&#xff08;是国内24S&#xff09;下的公司出来的芯片&#xff0c;寄存器和管脚全对标。 在这里我就大概说一下芯片的说用方法 一、硬件设计 该芯片支持双通道射频直采 支持协议JESD204B 14位 采样…