选自过去1~2周 本身所看到外文内容:https://twitter.com/unity3d 和各类其余博客来源吧 html
Unity2019中彷佛准备了专用的方法git
GameObjectUtility.RemoveMonoBehavioursWithMissingScriptgithub
Unity2018支持的方法web
HDRgradient.cs编程
[GradientUsage(true)] public Gradient color;canvas
只需写一个名为GradientUsage的属性。api
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环境中彷佛没有问题,所以若是图形质量没有问题,您能够主动使用它。
记得好像 之前发过这个截图:
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(); } }
[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" );
}
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;
如今,当构建成功时,个人构建脚本会发出一声蜂鸣声,若是构建失败,则会发出三声蜂鸣声。 多任务处理或在其余时方便
https://docs.unity3d.com/ScriptReference/EditorApplication.Beep.html
Shift + Ctrl + V能够将您在VS中复制的内容带到剪贴板
很方便y
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/
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的对象。
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
如今您能够建立法线贴图了
在显示的窗口中自由调整参数,而后按“肯定”
( 可是在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}
使用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可能会很高兴,记住,当你遭受之间英寸
跟池子的概念可能不太同样:
https://michaelscodingspot.com/cache-implementations-in-csharp-net/
缓存是软件开发中最经常使用的模式之一。
缓存很是适合不常常更改的数据。甚至更好,永不改变。不断变化的数据(例如当前计算机的时间)不该被缓存,不然您将获得错误的结果。
https://michaelscodingspot.com/avoid-gc-pressure/
https://michaelscodingspot.com/ways-to-cause-memory-leaks-in-dotnet/
值得思考:
https://michaelscodingspot.com/class-instantiation-guidelines-2/
这是一个使用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/
https://michaelscodingspot.com/10-tips-gain-mastery-fixing-bugs/
https://michaelscodingspot.com/7-debugging-techniques-know-c-net/
这个扩展工具蛮有用的: 由于Hierarchy中进行的搜素默认应该是针对GameObject name的模糊查询。
两个函数:
从四元数转换为Vector3
从Vector3转换为四元数
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%
会看到下面连着的指令多与少(猜想是这个影响的性能)
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的一个文章:
https://web.stanford.edu/class/cs248/pdf/CS248-PocketGems-ProgrammingParadigms.pdf
目标
1.有关您项目的游戏架构的高级技巧
2.关于Unity不足之处的一些观点
大纲
1.游戏循环和模拟
2.处理交互
3.控制
4.实体组件系统
游戏循环处理全部游戏模拟逻辑:
-添加/删除实体
-处理玩家输入
-更新游戏逻辑系统
-处理运动,物理和碰撞
-为视图层生成状态
Unity的游戏循环
在初始化步骤中,组件之间也可能具备循环依赖性。
您能够拆分组件来解决此问题,可是这可能须要更新许多预制件,并可能增长组件之间的耦合。
您能够在Awake()和Start()之间分割初始化代码,但这确实很糟糕。
解决此问题的一种好方法是将您的行为与您的状态分开,而且不要对大多数组件使用Unity的回调。
模拟Simulation
封装循环和状态的对象
在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
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
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}
使用后:
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}
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
2七、Mesh Optimizer 插件:、
我尝试使用网格优化器,它能够免费将高多边形更改成低多边形
https://qiita.com/matchyy/items/a4b1e232c3531ab8272a
2八、GameCreator概述
什么是GameCreator? (这种编辑器的设计思想值得学习!!)
Visual Scripting和UnityEditor扩展资产
指令处理已添加到Unity的Inspector中,而且处理从顶部开始按顺序执行
基本逻辑由动做,触发器和条件三部分组成,将它们组合在一块儿便可构建游戏。
除上述内容外,还包括用于操做播放器的播放器,用于管理变量的变量,用于控制相机操做的相机电机等。
添加您本身的动做,触发器和条件(适用于工程师)
几个额外的扩展模块正在销售中,能够添加以添加各类游戏功能
https://assetstore.unity.com/packages/templates/systems/game-creator-89443