Unity3d 周分享(23期 2019.11.10 )
Posted u010019717
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3d 周分享(23期 2019.11.10 )相关的知识,希望对你有一定的参考价值。
选自过去1~2周 自己所看到外文内容:https://twitter.com/unity3d 和各种其他博客来源吧
1\\ 如何批量删除Unity Missing 组件
Unity2019中似乎准备了专用的方法
GameObjectUtility.RemoveMonoBehavioursWithMissingScript
Unity2018支持的方法
2、 [Unity]提示:在Inspector 中显示HDR模式渐变。
HDRgradient.cs
[GradientUsage(true)] public Gradient color;
只需写一个名为GradientUsage的属性。
3、对 Unity 2017.3中引入的“RGB Crunched ETC”和“RGBA Crunched ETC2”的验证
Updated Crunch texture compression library – Unity Blog
https://blogs.unity3d.com/jp/2017/11/15/updated-crunch-texture-compression-library/
Crunch compression of ETC textures – Unity Blog
https://blogs.unity3d.com/jp/2017/12/15/crunch-compression-of-etc-textures/
这似乎可以在ios上使用,但iOS有PVRTC的图像,android有ETC,所以我试图验证这些格式是否在iOS环境中是有用的。
验证方法
使用Unity版2017.3.0f3。
准备了三种类型的512x512 / 1024x1024 / 2048x2048纹理,并使用非透明(RGB)和透明(RGBA)纹理进行验证。带有image〜的纹理名称 没有透明度, 而imageTrans~具有透明度。
在MemoryProfiler (https://bitbucket.org/Unity-Technologies/memoryprofiler)上检查实际机器上的内存消耗。
使用Mac终端上的 ls -alh 命令检查“PNG文件”的大小。
括号中的文件大小是Build Report确认的值。
单击此处查看用于验证的项目 https://github.com/nakamura001/Unity-TestCrunch。
iOS版
*原始尺寸图像可以显示在上一页上。
在iOS环境中,由于图形API(Metal / OpenGL ES 3 / OpenGL ES 2)而出现差异。
由于Metal不支持ETC(支持ETC2),因此在Metal环境中执行“RGB Crunched ETC”时,实际上会消耗RGBA 32位大小的内存。即使纹理略微增加文件大小但没有透明度,使用“RGBA Crunched ETC2”也可以减少内存使用量。
由于OpenGL ES 2环境不支持ETC / ETC2,因此在执行期间使用“RGB Crunched ETC”或“RGBA Crunched ETC2”会消耗RGBA 32位大小的内存。
在PVRTC中,由于图形API的差异,尺寸没有差异。
除了存储容量最重要的游戏之外,PVRTC基本上是平衡和推荐的。
Android的
在Android环境中似乎没有问题,因此如果图形质量没有问题,您可以主动使用它。
4、计算机语言的保留字数量(英文)
5、UGUI 为什么要动静分离?
记得好像 以前发过这个截图:
6、[Unity]使用字符串插值时,添加ToString时GC Alloc减少
using UnityEngine;
using UnityEngine.Profiling;
public class Example : MonoBehaviour
private void Update()
int num1 = 1;
int num2 = 2;
// 有ToString
var sampler1 = CustomSampler.Create( " 有ToString" );
sampler1.Begin();
var str1 = $"num1.ToString() / num1.ToString()";
sampler1.End();
// 没有ToString
var sampler2 = CustomSampler.Create( "没有 ToString " );
sampler2.Begin();
var str2 = $"num1 / num2";
sampler2.End();
7、[Unity]使用EditorUtility.RevealInFinder打开文件夹时,打开的是父级路径。
[MenuItem( "Tools/Hoge" )]
private static void Hoge()
EditorUtility.RevealInFinder( "Assets" );
当我尝试使用System.Diagnostics.Process.Start打开Assets文件夹时
[MenuItem( "Tools/Hoge" )]
private static void Hoge()
Process.Start( "Assets" );
8、[C#]如何通过反射获取特定类的所有子类
System.Reflection.Assembly.GetAssembly(typeof(Example))
.GetTypes()
.Where(x => x.IsSubclassOf(typeof(Example)) && !x.IsAbstract)
.ToArray();
子类的实例的
顺便说一下,使用Activator 实例化如上所述获得的子类。
var instance = System.Activator.CreateInstance(subClassType) as Example;
9、您是否知道可以使用EditorApplication.Beep在#unity3d中播放系统提示音?
现在,当构建成功时,我的构建脚本会发出一声蜂鸣声,如果构建失败,则会发出三声蜂鸣声。 多任务处理或在其他时方便
https://docs.unity3d.com/ScriptReference/EditorApplication.Beep.html
10、在Visual Studio中处理Unity游戏时,请尝试:
Shift + Ctrl + V可以将您在VS中复制的内容带到剪贴板
很方便y
11、 Imposter System
https://assetstore.unity.com/packages/tools/modeling/imposter-system-69651
在不进行预处理的情况下将3D对象转换为2D面片渲染。从而减少场景中多边形的数量。
看起来就像3D对象,但是消耗的资源要少得多。
所有的相关信息都在这边tps:/forum.unity3d.com/threads/w-i-p-realtime-imposter-system-fake-3d-optimization-plugin.426478/
12、#Unity 2020.1.0a7:
Scripting: Added a parameter to FindObjectOfType and FindObjectsOfType called includeInactive, this will return objects that are also attached to disabled GameObjects.
脚本编写:向FindObjectOfType和FindObjectsOfType添加了一个名为includeInactive的参数,这将返回还附加到禁用的GameObjects的对象。
13、[GIMP]启用创建法线贴图(法线贴图)
https://code.google.com/archive/p/gimp-normalmap/downloads
下载“ gimp-normalmap-winXX-1.2.3.zip”,
下载完成后将其解压缩
解压缩后,将“ normalmap.exe”移动到以下文件夹
C:\\Program Files\\GIMP 2\\lib\\gimp\\2.0\\plug-ins
接下来,将以下三个文件移动到下一个文件夹
glew32.dll
libgdkglext-win32-1.0-0.dll
libgtkglext-win32-1.0-0.dll
C:\\Program Files\\GIMP 2\\bin
现在您可以创建法线贴图了
在显示的窗口中自由调整参数,然后按“确定”
14、我一直在使用协程Coroutine,但是请尝试正确地理解异步Aysync/等待Await(第1部分)
( 但是在Unity中是建议使用协程的)
15、[Unity]将结构体数据“重新解释”为不同类型
当您在ECS中执行各种操作时,内部数据是相同的,但是由于类型不同,必须将其转换。
例如float,当有一个通过注入缓冲区执行批处理的API时,NativeArray<FloatData>不能直接输入诸如本地数据之类的结构数组。但是,这两个在内存方面几乎相同。所以Reinterpret<T, U>()在和重新解释数据NativeArray<FloatData> 与 NativeArray<float> 试图把它作为。
例子不起作用
会报错。
例如,考虑以下代码:我想一次显示MyData此结构ShowFloatLog(NativeArray<float> inputs)。自然,即使MyData的内容是浮点型的,处理也不是浮点型的,因此下面的代码将导致错误。
1using Unity.Collections; 2using UnityEngine; 3 4struct MyData public float Value; 5 6public class Sample: MonoBehaviour 7 8 void Start() 9 10 var input1 = new NativeArray<MyData>(new[] 11 new MyData Value = 11 , 12 new MyData Value = 22 , 13 new MyData Value = 33 , 14 , Allocator.Temp); 15 16 ShowLog(input1 ); // 注意 注意 注意 这一句会报错 17 18 input1.Dispose(); 19 20 21 static void ShowFloatLog(NativeArray<float> inputs) 22 23 foreach (var data in inputs) 24 Debug.Log(data); 25 26
Reinterpret<T, U>()以“重新解释”为其他类型
使用NativeArray<MyData>() 的NativeArray解释()。该API是Collection因为它们包含在包中,你必须导入包。
如下所示使用它。由于MyData的内容只是浮点数,因此可以将它们解释为浮点数。另外,由于仅是解释,请勿配置。参考指针是相同的。
1void Start() 2 3 var input1 = new NativeArray<MyData>(new[] 4 new MyData Value = 11 , 5 new MyData Value = 22 , 6 new MyData Value = 33 , 7 , Allocator.Temp); 8 9 // MyDataをFloatに再解釈 10 var floatInput = input1.Reinterpret<MyData, float>(); 11 12 // NativeArray<float>なので動作 13 ShowLog(floatInput); 14 15 input1.Dispose(); 16
这种重新解释似乎是一个指针,如果内部数据相同,则可以解释为各种数据。例如,float3的数组可以解释为float。当然,数据的长度是不同的,因此您需要小心,但这似乎一点也不有趣。
还是float3 -> float在的情况下,特别是问题不大,但float -> float3在的情况下被3整除数的基石素数将不等于错误。许多人似乎对矢量化更有利,但是要小心。
1 void Start() 2 3 var input1 = new NativeArray<float3>(new[] 4 new float3(111, 222, 33), 5 new float3(444, 555, 666), 6 new float3(777, 888, 999), 7 , Allocator.Temp); 8 9 // float3をfloatに再解釈 10 var floatInput = input1.Reinterpret<float3, float>(); 11 12 // output : input length 3, reinterpret length 9 13 // float3をfloatにするにあたり、配列の長さが変わっている 14 Debug.Log($"input length input1.Length, reinterpret length floatInput.Length"); 15 16 // 111 ~ 999 までの要素を個別に出力 17 ShowLog(floatInput); 18 19 input1.Dispose(); 20
感想
NativeArray<Vector3>
快来旧返回API和NativeArray<float3>
新要求的API可能会很高兴,记住,当你遭受之间英寸
16、看到C#优化相关开发者的文章
跟池子的概念可能不太一样:
- C#.NET中的缓存实现
https://michaelscodingspot.com/cache-implementations-in-csharp-net/
缓存是软件开发中最常用的模式之一。
缓存非常适合不经常更改的数据。甚至更好,永不改变。不断变化的数据(例如当前计算机的时间)不应被缓存,否则您将得到错误的结果。
- C#.NET中8种避免GC压力并提高性能的技术
https://michaelscodingspot.com/avoid-gc-pressure/
- .NET中导致内存泄漏的8种方法
https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/
值得思考:
- 面向对象语言的类实例化指南:何时选择单例,静态,扩展方法或依赖项注入
https://michaelscodingspot.com/class-instantiation-guidelines-2/
- 您应该知道的5种避免C#.NET中的事件引起的内存泄漏的技术
这是一个使用Prism 受欢迎的事件汇总器(与NuGet Prism.Core一起提供)的示例。
https://michaelscodingspot.com/5-techniques-to-avoid-memory-leaks-by-events-in-c-net-you-should-know/
https://www.nuget.org/packages/Prism.Core/
- 掌握bug的10条技巧
https://michaelscodingspot.com/10-tips-gain-mastery-fixing-bugs/
- 您应该在C#.NET中了解的7种调试技术
https://michaelscodingspot.com/7-debugging-techniques-know-c-net/
这个扩展工具蛮有用的: 因为Hierarchy中进行的搜素默认应该是针对GameObject name的模糊查询。
17、编辑器扩展使使用Hierarchy的组件搜索更加轻松
18、关于Unity四元数和Vector3的手写转换
两个函数:
从四元数转换为Vector3
从Vector3转换为四元数
19、性能测试(虽然数据意义不是特别大)
https://www.shibuya24.info/entry/constructor_performance
C# 在使用new 关键字构造对象,两种方式,一种直接有参构造函数。 还有一种是自变量的模式。
// 无参构造函数的方式
new Hoge x = 24, foo = "shibuya24";
// 有参构造函数方式
new Piyo (24, "shibuya24");
1public class Piyo 2 3 public int x; 4 public string foo; 5 public Piyo(int x, string foo) 6 7 this.x = x; 8 this.foo = foo; 9 10 11public class Hoge 12 13 public int x; 14 public string foo; 15
1void Start() 2 3 int ii = 10000000; 4 Profiler.BeginSample("#### a ####"); 5 for (int i = 0; i < ii; i++) 6 new Piyo x = 0, foo = "foo"; 7 Profiler.EndSample(); 8 Profiler.BeginSample("#### b ####"); 9 for (int i = 0; i < ii; i++) 10 new Hoge x = 24, foo = "shibuya24"; 11 Profiler.EndSample(); 12
前者在速度上约快5%
会看到下面连着的指令多与少(猜测是这个影响的性能)
20、今天看文档: 发现Unity多了一些API ;
Use this struct to set up a box cast command to be performed asynchronously during a job.
Struct used to set up a raycast command to be performed asynchronously during a job.
Use this struct to set up a sphere cast command that is performed asynchronously during a job.
Use this struct to set up a capsule cast command that is performed asynchronously during a job.
First introduced in:
#if UNITY_2018_3_0
Present in:
#if UNITY_2018_3_OR_NEWER
批处理物理查询是一种在主线程之外运行物理查询的方法。需要此API,因为一个人不能从另一个线程执行通常的API。在Unity 2018.1中,我们发布了RaycastCommand.ScheduleBatch,可帮助计算主线程的射线广播。在Unity 2018.3中,我们将其扩展为添加其他单结果查询,例如SphereCast,CapsuleCast和BoxCast。
https://connect.unity.com/p/unity-2019-3zhong-de-wu-li-geng-xin
今天看到一个pdf的一个文章:
21、斯坦福大学的 : 游戏编程范例
https://web.stanford.edu/class/cs248/pdf/CS248-PocketGems-ProgrammingParadigms.pdf
目标
1.有关您项目的游戏架构的高级技巧
2.关于Unity不足之处的一些观点
大纲
1.游戏循环和模拟
2.处理交互
3.控制
4.实体组件系统
游戏循环处理所有游戏模拟逻辑:
-添加/删除实体
-处理玩家输入
-更新游戏逻辑系统
-处理运动,物理和碰撞
-为视图层生成状态
Unity的游戏循环
在初始化步骤中,组件之间也可能具有循环依赖性。
您可以拆分组件来解决此问题,但是这可能需要更新许多预制件,并可能增加组件之间的耦合。
您可以在Awake()和Start()之间分割初始化代码,但这确实很糟糕。
解决此问题的一种好方法是将您的行为与您的状态分开,并且不要对大多数组件使用Unity的回调。
模拟Simulation
封装循环和状态的对象
在Unity中,始终有一个模拟正在运行。
您对此几乎没有控制权:
-您无法快进/快退/重播
-您无法实例化多个模拟
-您无法区分初始化顺序和更新顺序
-您不能在同一组件上定义多个初始化/更新行为
22、如何启动多个Unity并共享同一项目
Unity是不能用多个exe实例打开一个Project的。
*请注意,此方法不是正常用法。
接下来,从“ unity-proj1”复制“ unity-proj2”并创建它。
并从“ unity-proj2”中删除“ Assets”,“ Pakcages”和“ ProjectSettings”。
接下来,为了与“ untiy-proj1”文件夹共享这三个文件夹,我想启动一个命令行并创建一个符号链接。
使用“管理员权限”启动命令行。
然后输入以下命令共享目录:
mklink /d <パス>\\unity-proj2\\Assets <パス>\\unity-proj1\\Assets
mklink /d <パス>\\unity-proj2\\Packages <パス>\\unity-proj1\\Packages
mklink /d <パス>\\unity-proj2\\ProjectSettings <パス>\\unity-proj1\\ProjectSettings
如果命令成功,将显示以下消息。
〜<< === >>〜创建符号链接
如果上述所有命令均成功执行,则快捷方式之类的箭头标记将显示在“ unity-proj2”的“ Assets”,“ Pakcages”和“ ProjectSettings”文件夹中,如下所示。
https://twitter.com/FreyaHolmer/status/1184218791334612999
23、Inverse Lerp上的thread -超级有用,但经常被忽略的功能!✨
Lerp(a,b,t)=值
InvLerp(a,b,value)= t
•lerp基于分数t返回a和b之间的混合
•逆lerp根据a和b之间的值返回分数t
用例! 🔊
说您要根据距离控制音频源的音量
•在10米处,您需要音量1
•在20米处,您要音量0
然后volume由
volume = InvLerp(20,10,distance)
如果您曾经使用过Photoshop的色阶工具,那么您会同时使用lerp和逆lerp! 🎨
输入值使用inverse lerp,输出值使用lerp!
当与图像一起使用时,可以使用inverse lerp来增加值对比度! 例如,这是inverse lerp前后的自拍
另外,请注意,某些Lerp / InvLerp函数也可以推断(例如在着色器中),而其他函数会将值限制在给定范围内(例如Unity的Mathf.Lerp / InverseLerp函数)。
make sure you clamp unless you want to extrapolate 📈
确保钳位📈,除非您想推断clamp
这是一个有趣的用例!
一个inv lerp,其中a和b是颜色,并且value参数是该水的深度,您可以通过深度实现色相平移以消除颜色
无论如何,仅此而已! 希望你觉得这个有用〜
附录-另一个有用的功能是Remap!
remap将给定输入范围内的值转换为给定输出范围,该值基本上是反lerp和lerp的组合!
这是这三个代码!
(此外,这些都不是固定的-它们都可以推断)
如果您想了解更多关于lerp的信息,请访问另一个主题!
https://twitter.com/FreyaHolmer/status/1175925033002254338
24、[Unity]编辑器扩展示例,使用UIElements将工具栏添加到“场景”视图
1using UnityEditor; 2using UnityEngine; 3using UnityEngine.UIElements; 4[InitializeOnLoad] 5public static class Example 6 7 static Example() 8 9 foreach ( var sceneView in Resources.FindObjectsOfTypeAll<SceneView>() ) 10 11 var toolbar = new VisualElement(); 12 var style = toolbar.style; 13 var backgroundColor = new Color32( 203, 203, 203, 255 ); 14 var rootVisualElement = sceneView.rootVisualElement; 15 16 style.flexDirection = FlexDirection.Row; 17 style.top = 20; 18 style.backgroundColor = new StyleColor( backgroundColor ); 19 style.height = 20; 20 21 toolbar.Add( new Label text = "ピカチュウ" ); 22 toolbar.Add( new Button( () => Debug.Log( "ピカチュウ" ) ) text = "ピカチュウ" ); 23 toolbar.BringToFront(); 24 25 rootVisualElement.Clear(); 26 rootVisualElement.Add( toolbar ); 27 28 29
使用后:
25、[Unity]启用移动和移动World Space uGUI元素的功能
canvas的渲染模式Render Mode是世界空间World Space的状态。
1public class Draggable : MonoBehaviour 2 3 Canvas canvas; 4 Vector2 diff; 5 static public void SetEventTrigger(Graphic element, EventTriggerType eventType, UnityEngine.Events.UnityAction<BaseEventData> callbackFunc) 6 7 // 任意のエレメント(Buttonなど)に 任意のトリガーで発生する コールバック関数を登録する。 8 EventTrigger trigger = element.gameObject.AddComponent<EventTrigger>(); 9 EventTrigger.Entry entry = new EventTrigger.Entry(); 10 entry.eventID = eventType; 11 entry.callback.AddListener(callbackFunc); 12 trigger.triggers.Add(entry); 13 // EventTriggerTypeによって、BaseEventDataを派生クラスにキャストできる。 14 // https://docs.unity3d.com/ja/2017.4/ScriptReference/EventSystems.EventTrigger.html 15 16 private void Awake() 17 18 Graphic element = GetComponent<Graphic>(); 19 // Canvasを探す。 20 canvas = null; 21 Transform parent = element.transform.parent; 22 while (parent != null) 23 24 canvas = parent.GetComponent<Canvas>(); 25 if (canvas != null) 26 break; 27 parent = parent.parent; 28 29 SetEventTrigger(element, EventTriggerType.PointerDown, data => Donw(data)); 30 SetEventTrigger(element, EventTriggerType.Drag, data => Drag(data)); 31 32 Vector2 GetLocalPos() 33 34 Vector2 localPoint = Vector2.zero; 35 Vector3 screenPoint = Input.mousePosition; 36 // 【Unity】【uGUI】RectTransformUtilityでスクリーン座標をUIのローカル座標やワールド座標に変換する - LIGHT11 37 // http://light11.hatenadiary.com/entry/2019/04/16/003642 38 RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPoint, canvas.worldCamera, out localPoint); 39 return localPoint; 40 41 void Donw(BaseEventData data) 42 43 Vector2 v = transform.localPosition; 44 diff = GetLocalPos() - v; 45 46 void Drag(BaseEventData data) 47 48 transform.localPosition = GetLocalPos() - diff; 49 50 51public class DragSample : MonoBehaviour 52 53 public Button button; 54 public Scrollbar scrollbar; 55 public RawImage rawImage; 56 void Start() 57 58 // 任意のuGUIエレメントにDraggableをアタッチすることで、ドラッグ移動できるようになる。 59 button.gameObject.AddComponent<Draggable>(); 60 scrollbar.gameObject.AddComponent<Draggable>(); 61 rawImage.gameObject.AddComponent<Draggable>(); 62 63
26、使处理Unity GL类更加容易
Unity中的线条绘制
绘制一条简单的线(例如用于在3D空间中的Unity中进行调试)时,似乎经常使用GL,但是如果使用此GL类,则只能使用OnRenderObject方法,或者如果您有多个摄像头 有些点难以使用,难以使用。
诸如Debug.DrawLine之类的Debug类也具有线条绘制功能,但是仅在“Scene”视图中显示,不能由实际计算机处理。
因此,我尝试使用GL复制易于处理的内容,例如Debug.DrawLine和Debug.DrawRay。
像Debug.DrawLine一样易于处理
可以从Update方法中调用
也可以显示在“Game”视图中
https://qiita.com/NegiuraRoman/items/09df1d4f72fc44099db0
27、Mesh Optimizer 插件:、
我尝试使用网格优化器,它可以免费将高多边形更改为低多边形
https://qiita.com/matchyy/items/a4b1e232c3531ab8272a
28、GameCreator概述
什么是GameCreator? (这种编辑器的设计思想值得学习!!)
Visual Scripting和UnityEditor扩展资产
指令处理已添加到Unity的Inspector中,并且处理从顶部开始按顺序执行
基本逻辑由动作,触发器和条件三部分组成,将它们组合在一起即可构建游戏。
- Actions将动作赋予GameObject等。
- Triggers火灾事件,例如动作
- Conditions执行控制处理,例如条件分支
除上述内容外,还包括用于操作播放器的播放器,用于管理变量的变量,用于控制相机操作的相机电机等。
添加您自己的动作,触发器和条件(适用于工程师)
几个额外的扩展模块正在销售中,可以添加以添加各种游戏功能
https://assetstore.unity.com/packages/templates/systems/game-creator-89443
https://docs.gamecreator.io/game-creator/game-creator
以上是关于Unity3d 周分享(23期 2019.11.10 )的主要内容,如果未能解决你的问题,请参考以下文章