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对象,但是消耗的资源要少得多。

开发人员http:/starasgames.xyz/

所有的相关信息都在这边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>快来旧返回APINativeArray<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的组件搜索更加轻松

https://github.com/Unity-Technologies/ShaderGraph/blob/master/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs

 

 

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%

https://sharplab.io/

              会看到下面连着的指令多与少(猜测是这个影响的性能)

 

 

 

 

20、今天看文档:  发现Unity多了一些API ; 

BoxcastCommand

Use this struct to set up a box cast command to be performed asynchronously during a job.

RaycastCommand

Struct used to set up a raycast command to be performed asynchronously during a job.

SpherecastCommand

Use this struct to set up a sphere cast command that is performed asynchronously during a job.

CapsulecastCommand

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

https://blogs.unity3d.com/es/2018/11/12/physics-changes-in-unity-2018-3-beta/?_ga=2.170637536.1333645541.1572165056-1185295926.1569768188

             批处理物理查询是一种在主线程之外运行物理查询的方法。需要此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 )的主要内容,如果未能解决你的问题,请参考以下文章

CSDN精品专栏第23期

CSDN精品专栏第23期

Unity3D外包团队——技术分享U3D全景漫游

软件测试周刊(第23期):你理想中的工作是什么?

[ 第136期 ] 23款商务出行响应式网页设计PSD源文件

分享Kali Linux 2017年第30周镜像文件