Unity3d 周分享(20期 2019.6.30 )

选自过去1~2周 自己所看到外文内容:https://twitter.com/unity3d 和各种其他博客来源吧 

1、Unity的Android音频延迟在2019.1.0 中改进

https://gametorrahod.com/unitys-android-audio-latency-improvement-in-2019-1-0/

文章作者因为这个延迟问题,弄了一个,正是基于OpenSL 原生音频 - 通过OS的原生音频库降低音频延迟。

Native Audio是一个插件,可以帮助您使用每个平台最快的本机方法轻松加载和播放音频... beyond7.com

其中也提到一些有名的插件: 除了FMOD和wwise之外,还有来自日本的Criware。 文章真的好长~~

有关使用Unity的Android音频的复习,我建议你阅读这篇长达一小时的关于我的研究的文章。

适用于Unity开发人员的Android原生音频入门

我将揭开围绕Android音频系统的“黑匣子”的神秘面纱,并分析为什么Unity使用它的方式会让人失望... gametorrahod.com

作者使用 小米 miA2 (2018年发布/奥利奥8.1.0)和 Xperia Z5 (2015年发布/ Nougat 7.1.1)两个手机做了测试。

结果

令人印象深刻!在小米米A2上,从以前的Unity版本减少是一个疯狂的-200毫秒!(如果完全跳过Unity到本机,-317ms)

在Xperia Z5上没有任何有意义的改进,表明手机已经在之前的版本中使用了OpenSL ES。

摘要

我建议所有节奏游戏开发者尽快升级到2019.1,因为这些小米设备因价格低而非常普及。谁知道哪些设备能够实际处理低延迟时报告错误的低延迟功能标志?

 

 

 

 

2、 了解实体组件系统的面向数据的设计--GDC 2019年的Unity 【Understanding data-oriented design for entity component systems - Unity at GDC 2019】 https://www.youtube.com/watch?time_continue=565&v=0_Byw9UMn9g

          与传统的面向对象的游戏系统设计方式相比,Unity的新ECS功能可以实现巨大的性能提升,但面向数据的设计是一种截然不同的思维方式。观察如何以面向数据的方式思考,以便您可以利用这些新功能。演讲人:Elizabeth Baumel(DOTS软件工程师,Unity Technologies)了解有关面向数据技术堆栈(DOTS)的更多信息:

https://unity.com/dots?utm_source=youtube&utm_medium=social&utm_campaign=engine_global_generalpromo_2019-04-09_gdc19&utm_content=video_understanding-dots

PPT : https://docs.google.com/presentation/d/1s8XV63Dy092i1FSfUFUvfXrne2OmisrlxM5zbr4F8gQ/edit#slide=id.p

 

 

Unity at GDC - A Data Oriented Approach to Using Component Systems

https://www.youtube.com/watch?v=p65Yt20pw0g

 

 

 

3、 使用Unity的AudioMixer

音频混音器音量设置 , http://tsubakit1.hateblo.jp/entry/2015/05/23/234053 这个文章使用 mixer.SetFloat("MasterVolume", Mathf.Lerp(-80, 0, value)); 这种方式控制音量。

https://qiita.com/u-n-k-man1gou/items/ea206c700ed5076ecd79 volume 和 DB 有一个转换关系的~~

             因为AudioMixer的音量是Digibell(-80~0)。 如果你在AudioSource.volume的0f-1f意义上这样做,那将毫无用处。

0.5f = -40dB如果你考虑一下,声音将会低于50%。

            Digibell(dB)转换的公式是

dB = 20.0 × log10(i0/i1) ※「i0/i1」是一个比例,

             所以用C#写

20 * Mathf.Log10(volume);

volume 就是Slider的值(0f至1f)。

public void SetBgmVolume(float _volume)
{
    float volume = Mathf.Clamp(_volume, 0.0001f, 1.0f);
    var volumeDB = (float) (20.0d * Math.Log10(volume));
    audioMixer.SetFloat("BGMVol", Mathf.Clamp(volumeDB, -80.0f, 0.0f));
}

 

 

 

 

4、

这个手册之前看过两边吧, 最近有看了一遍~~~~

ARM 针对Unity推出的 手册 : 中文最新 3.3 版本

ARM® Unity 开发者指南 版本 3.3 优化移动游戏图形 https://developer.arm.com/-/media/developer/Graphics%20and%20Multimedia/Developer%20Guides%20-%20PDFs/Unity%20Developer%20Guides/Oct18%20-%20%20Unity%20%20ARM%20-%20Chinese.pdf?revision=2dd4b6af-bf6d-4930-ac23-2ed841fbd55b&la=en

https://developer.arm.com/tools-and-software/graphics-and-gaming/gaming-engine/unity/unity-guides-and-white-papers

           Unity 5 及更高版本会自动缓存Transform组件。

 

 

 

 

 

5、在Unity 2018的PlayerLoop中,禁用Unity调用每一帧的处理或在Update之前添加您自己的处理

这次,使用从Unity 2018添加的PlayerLoop,您可以添加或自定义您自己的事件,例如Unity事件(Update,FixedUpdate等

                 在Unity 4和Unity 5时,基本上使用MonoBehaviour调用Unity事件,例如Update和LateUpdate,除非由ScriptExecutionOrder设置,否则顺序是未知的。

            基本上它适用于Component, 但是好像没有场景相关的事件。

RuntimeInitializeOnLoad似乎可以调用与场景无关的初始化处理。

            Unity 2018.1 引入了一个名为PlayerLoop 的功能。这是Unity引擎重新更新过程的顺序,或停止特定的事件,或插入自己的处理似乎是有可能这样。

获取标准事件列表

using UnityEngine;
using UnityEngine.Experimental.LowLevel;
public class ShowPlayerLoop
{
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void Init()
    {
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();

        foreach (var header in playerLoop.subSystemList)
        {
            Debug.LogFormat("------{0}------", header.type.Name);
            foreach (var subSystem in header.subSystemList)
            {
                Debug.LogFormat("{0}.{1}", header.type.Name, subSystem.type.Name);
            }
        }
    }
}

          首先var playerLoop = PlayerLoop.GetDefaultPlayerLoop();获得所有标准事件。

           重要的是playerLoop.subSystemList,存储在此列表中的方法是递归调用的。如果要自定义调用,则将编辑此subSystemList的各个部分。

           此外,此部分中要获取的方法列表似乎与UnityEngine.Experimental.PlayLoop中可以检查的方法相匹配。

------Initialization------
Initialization.PlayerUpdateTime
Initialization.AsyncUploadTimeSlicedUpdate
Initialization.SynchronizeInputs
Initialization.SynchronizeState
Initialization.XREarlyUpdate
------EarlyUpdate------
EarlyUpdate.PollPlayerConnection
EarlyUpdate.ProfilerStartFrame
EarlyUpdate.GpuTimestamp
EarlyUpdate.UnityConnectClientUpdate
EarlyUpdate.CloudWebServicesUpdate
EarlyUpdate.UnityWebRequestUpdate
EarlyUpdate.ExecuteMainThreadJobs
EarlyUpdate.ProcessMouseInWindow
EarlyUpdate.ClearIntermediateRenderers
EarlyUpdate.ClearLines
EarlyUpdate.PresentBeforeUpdate
EarlyUpdate.ResetFrameStatsAfterPresent
EarlyUpdate.UpdateAllUnityWebStreams
EarlyUpdate.UpdateAsyncReadbackManager
EarlyUpdate.UpdateTextureStreamingManager
EarlyUpdate.UpdatePreloading
EarlyUpdate.RendererNotifyInvisible
EarlyUpdate.PlayerCleanupCachedData
EarlyUpdate.UpdateMainGameViewRect
EarlyUpdate.UpdateCanvasRectTransform
EarlyUpdate.UpdateInputManager
EarlyUpdate.ProcessRemoteInput
EarlyUpdate.XRUpdate
EarlyUpdate.TangoUpdate
EarlyUpdate.ScriptRunDelayedStartupFrame
EarlyUpdate.UpdateKinect
EarlyUpdate.DeliverIosPlatformEvents
EarlyUpdate.DispatchEventQueueEvents
EarlyUpdate.DirectorSampleTime
EarlyUpdate.PhysicsResetInterpolatedTransformPosition
EarlyUpdate.NewInputBeginFrame
EarlyUpdate.SpriteAtlasManagerUpdate
EarlyUpdate.PerformanceAnalyticsUpdate
------FixedUpdate------
FixedUpdate.ClearLines
FixedUpdate.NewInputEndFixedUpdate
FixedUpdate.DirectorFixedSampleTime
FixedUpdate.AudioFixedUpdate
FixedUpdate.ScriptRunBehaviourFixedUpdate
FixedUpdate.DirectorFixedUpdate
FixedUpdate.LegacyFixedAnimationUpdate
FixedUpdate.XRFixedUpdate
FixedUpdate.PhysicsFixedUpdate
FixedUpdate.Physics2DFixedUpdate
FixedUpdate.DirectorFixedUpdatePostPhysics
FixedUpdate.ScriptRunDelayedFixedFrameRate
FixedUpdate.ScriptRunDelayedTasks
FixedUpdate.NewInputBeginFixedUpdate
------PreUpdate------
PreUpdate.PhysicsUpdate
PreUpdate.Physics2DUpdate
PreUpdate.CheckTexFieldInput
PreUpdate.IMGUISendQueuedEvents
PreUpdate.NewInputUpdate
PreUpdate.SendMouseEvents
PreUpdate.AIUpdate
PreUpdate.WindUpdate
PreUpdate.UpdateVideo
------Update------
Update.ScriptRunBehaviourUpdate
Update.ScriptRunDelayedDynamicFrameRate
Update.DirectorUpdate
------PreLateUpdate------
PreLateUpdate.AIUpdatePostScript
PreLateUpdate.DirectorUpdateAnimationBegin
PreLateUpdate.LegacyAnimationUpdate
PreLateUpdate.DirectorUpdateAnimationEnd
PreLateUpdate.DirectorDeferredEvaluate
PreLateUpdate.UpdateNetworkManager
PreLateUpdate.UpdateMasterServerInterface
PreLateUpdate.UNetUpdate
PreLateUpdate.EndGraphicsJobsLate
PreLateUpdate.ParticleSystemBeginUpdateAll
PreLateUpdate.ScriptRunBehaviourLateUpdate
PreLateUpdate.ConstraintManagerUpdate
------PostLateUpdate------
PostLateUpdate.PlayerSendFrameStarted
PostLateUpdate.DirectorLateUpdate
PostLateUpdate.ScriptRunDelayedDynamicFrameRate
PostLateUpdate.PhysicsSkinnedClothBeginUpdate
PostLateUpdate.UpdateCanvasRectTransform
PostLateUpdate.PlayerUpdateCanvases
PostLateUpdate.UpdateAudio
PostLateUpdate.ParticlesLegacyUpdateAllParticleSystems
PostLateUpdate.ParticleSystemEndUpdateAll
PostLateUpdate.UpdateCustomRenderTextures
PostLateUpdate.UpdateAllRenderers
PostLateUpdate.EnlightenRuntimeUpdate
PostLateUpdate.UpdateAllSkinnedMeshes
PostLateUpdate.ProcessWebSendMessages
PostLateUpdate.SortingGroupsUpdate
PostLateUpdate.UpdateVideoTextures
PostLateUpdate.UpdateVideo
PostLateUpdate.DirectorRenderImage
PostLateUpdate.PlayerEmitCanvasGeometry
PostLateUpdate.PhysicsSkinnedClothFinishUpdate
PostLateUpdate.FinishFrameRendering
PostLateUpdate.BatchModeUpdate
PostLateUpdate.PlayerSendFrameComplete
PostLateUpdate.UpdateCaptureScreenshot
PostLateUpdate.PresentAfterDraw
PostLateUpdate.ClearImmediateRenderers
PostLateUpdate.PlayerSendFramePostPresent
PostLateUpdate.UpdateResolution
PostLateUpdate.InputEndFrame
PostLateUpdate.TriggerEndOfFrameCallbacks
PostLateUpdate.GUIClearEvents
PostLateUpdate.ShaderHandleErrors
PostLateUpdate.ResetInputAxis
PostLateUpdate.ThreadedLoadingDebug
PostLateUpdate.ProfilerSynchronizeStats
PostLateUpdate.MemoryFrameMaintenance
PostLateUpdate.ExecuteGameCenterCallbacks
PostLateUpdate.ProfilerEndFrame

覆盖PlayerLoop本身

我将用我认为最强大的进程取代PlayerLoop 。

正确地说,一旦你没有调用Unity的基本功能的各种处理,请将处理插入其中。

           这本身很容易实现。但是,如果您不调用进程== Unity循环被完全销毁,Unity使用的大多数函数都将停止。 物理操作,输入和UI 的所有操作都死掉了。

using UnityEngine;
using UnityEngine.Experimental.LowLevel;
public class SpawnSystem
{
    [RuntimeInitializeOnLoadMethod()]
    static void Init()
    {
        var mySystem = new PlayerLoopSystem()
        {
            type = typeof(MyLoopSystemUpdate),
            updateDelegate = () =>
            {
                Debug.Log("DO IT!!!");
            }
        };
        var playerLoop = new PlayerLoopSystem();
        playerLoop.subSystemList = new PlayerLoopSystem[] { mySystem };
        PlayerLoop.SetPlayerLoop(playerLoop);
    }
    public struct MyLoopSystemUpdate { }
}

这次,我会尝试在更新之前执行类似...的 函数你可以看到每帧都在打印Log, 但是画面都是静止的, 因为之前的正常循环都被覆盖没有了。

using UnityEngine;
using UnityEngine.Experimental.LowLevel;
using System.Collections.Generic;
public class PreUpdateSystem
{
    [RuntimeInitializeOnLoadMethod()]
    static void Init()
    {
        var mySystem = new PlayerLoopSystem()
        {
            type = typeof(MyLoopSystemUpdate),
            updateDelegate = () =>
            {
                Debug.Log("DO IT!!!");
            }
        };
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
        var updateSystem = playerLoop.subSystemList[4]; // Update
        var subSystem = new List<PlayerLoopSystem>(updateSystem.subSystemList);
        subSystem.Insert(0, mySystem);
        updateSystem.subSystemList = subSystem.ToArray();
        playerLoop.subSystemList[4] = updateSystem;
        PlayerLoop.SetPlayerLoop(playerLoop);
    }
    public struct MyLoopSystemUpdate { }
}

我正在做的就是重写subSystemList的内容并反映它。playerLoop.subSystemList[4];从更新过程中取出,在顶部添加您自己的进程并返回。现在整个显示如果有动画的话, 又动起来了~~~

下面的列表是Unity调用的事件获取的事件列表。

 

指数

类型

内容

0

Initialization

“时间”更新或状态?同步

1

EarlyUpdate

更新“输入”等

2

FixedUpdate

物理操作系统,调用FixedUpdate

3

PreUpdate

物理计算的反映?或鼠标输入

4

Update

更新过程

5

PreLateUpdate

动画更新等。最后是LateUpdate

6

PostLateUpdate

布料更新,渲染等

结果如下,我在FixedUpdate和Update之间插入了自己的事件。

 

禁用特定事件

最后,尝试禁用某些事件。这也很简单,只需准备一个已删除特定事件的PlayerLoop版本,然后执PlayerLoop.SetPlayerLoop。

这次,我将尝试禁用FixedUpdate.PhysicsFixedUpdate。

using UnityEngine;
using UnityEngine.Experimental.LowLevel;
using UnityEngine.Experimental.PlayerLoop;
using System.Collections.Generic;
public class StopPhysicsFixedUpdate
{
    static PlayerLoopSystem[] originalPlayerLoop, updatedPlayerLoop;
    [RuntimeInitializeOnLoadMethod()]
    static void Init()
    {
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
        originalPlayerLoop = playerLoop.subSystemList[2].subSystemList; // Update
        var subSystem = new List<PlayerLoopSystem>(originalPlayerLoop);
        subSystem.RemoveAll(c => c.type == typeof(FixedUpdate.PhysicsFixedUpdate));
        updatedPlayerLoop = subSystem.ToArray();
        PhysicsOFF();
    }
    public static void PhysicsOFF()
    {
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
        var sub = playerLoop.subSystemList[2];
        sub.subSystemList = updatedPlayerLoop;
        playerLoop.subSystemList[2] = sub;
        PlayerLoop.SetPlayerLoop(playerLoop);
    }
    public static void PhysicsON()
    {
        var playerLoop = PlayerLoop.GetDefaultPlayerLoop();
        var sub = playerLoop.subSystemList[2];
        sub.subSystemList = originalPlayerLoop;
        playerLoop.subSystemList[2] = sub;
        PlayerLoop.SetPlayerLoop(playerLoop);
    }
}

因为它是一个低级函数,所以最好小心如何使用它。

             就个人而言,我认识到在Update之前添加初始化处理以及在帧结束时收集信息是一个很好的用法。

 

 

 

 

6、 CEDEC 2018摘要

[CEDEC 2018摘要]发布了47篇报告文章,重点关注与智能手机游戏相关的会议

计算机娱乐协会(CESA)于8月22日至24日在Pacifico Yokohama举行日本最大的游戏开发者大会“2018年计算机娱乐开发者大会”(CEDEC 2018),创下历史新高254进行了一次会议 其中,社交游戏信息发布了47篇关于智能手机游戏相关会话的报道文章。

今年的主题是“幻想成为现实”。在CEDEC开始时,许多被认为远未实现的“梦想”现在正在变为现实,他们表示新的“梦想”将在不久的将来成为现实。 。

下面,我们将提供已发布会话的列表,作为每个制造商的摘要。

· Applibot(1) 【CEDEC 2018】揭示了成功的营销改革......也证明了ROAS翻倍!数字营销发展业务

·Aiming(1) “开发和管理分析自己的数据的文化!”(瞄准Koichiro Shibao)改善游戏的方法和措施是什么?

· Epic Games(1) 降低CPU成本并按预期执行!在UE4中使用许多角色的技术

·Craft Egg(1) “Galpa”管理中最上游的思想是“用户至上”......这个想法随着Craft Egg的价值而被揭示出来

· gumi(1) “为什么我们需要分析数据?”......根据“海鸥订单”的例子,介绍可用于“决策”的分析数据

· KLab(2) 为用户提供更高品质的音响体验!在社交游戏中实现响度控制的工作流程构建和考虑 ※本次会议也是Sono Logic Design,腾讯也在舞台上。 “Uta no Tsu☆Prince-sama♪Shining Live”用“CRIWARE”产生逼真的现场感...... KLab展示声音和指挥技术

· 格力(2) 测试〜游戏应用程序,随着时代的变化误传措施母鸡- ...误传的风险,可以提前检测 发生在外包和解决方案的时间问题...委托从两家公司的角度评论了接收方的“格力”和接受方的“GREVO”

· 谷歌(1) 通过Google Play上的智能手机游戏提高防范退款,改装,作弊等安全性的对策和要点

· Kokonone(1) 许多女性在“Pokekoro”中进行客户通信的秘密传递......“真正面对顾客的态度”

· Cygames (4) UI设计和原型开发,用于快速,高质量地制作UI ......“Prince Connect!Re:Dive的生产案例将会发布 Cygames拥有的最佳内容...靠近支持它的客户支持系统 Cygames与Pasco的融合,航空摄影摄影测量技术和激光扫描技术我们在

※※中实现了“最佳舒适体育场”的3D数据转换方法。本次会议也在Pasco上。 从“Dereste”的案例看“大更新成功的秘诀”...从Cygames的图形观点看评论

史克威尔(1) 从“Glimmnots Repage”看遗传算法的游戏平衡调整中的案例及其可视化......将目标“事实”改为“真相”的方法

,世嘉游戏(5) 在“D×2 Shin,女神新生解放”中尝试和发现新的UI设计制作方法,其中眼动仪用户测试是关键 SEGA Games'Kotodaman'的800万DL成就支持阴影的“Monobit Unity Networking 2.0”展示了单比特引擎采用示例 ※此会话还包括单比特引擎。 SEGA Games正在建设和运营“D2 Megaten Kotodaman新标题”的支持系统...... AI真的很多功能吗? 通过短期外包创造“D x 2 Shin,女神重生启示”魔鬼动画的提示被传递 不断变得复杂的订单管理更简单!SEGA Games推荐的进步管理工具“SHOTOGUN”的优势来自“Kotodaman”的例子 ※本次会议还有一个关于 Autodesk 的讨论。

喜悦工程(5) “命运”是那须蘑菇!...... DW的代表Yuji先生解释了发起“Fate / Grand Order”的过程 Delightworks Shiokawa描述的“Discard,Produce”的含义......现在,它被揭示为“FGO” 继续,“爱”和“勇气”的故事。“ 大爆炸,伟大的魔术”Matsuri“带来了”FGO“!... Delightworks的演示营销技巧 “FGO Arcade”的“疯狂”策划技术突破了“我不能做○○......”概念的基础是“已知”ד未知”和“如果是”形成 介绍Delightworks“PM”的基础知识,进行团队管理......从今天开始使用的FGO PROJECT和PM技术案例!

代纳(3) “反Oseronia”制片人的魅力城市大沽说,Nanzo,是一个“游戏管理社区和联创”? DeNA谈论的AR测量的最大好处是什么?“2D角色有三个维度!-AR测量歌曲Macross-”? “在”扭转奥赛利亚“中使用人工智能”......一起思考目标并始终分享预期值“

Dorikomu(3) “ENZA”在使用机器学习,过去,来分析未来的TCG当前元游戏在运行的“龙珠Z布奇吉利匹配” ※本次会议也是在舞台上万代南梦宫游戏 教的手机游戏开发位置信息“AROW”挑战AR地图便宜,Dorikomu游戏更快的发展是使用位置信息的3D实景图,以及如何解决 移动浏览器我们宣布了如何制作“Idol Master Shiny Colors”,它实现了全面的游戏开发和提供。*本次会议还有Namco BANDAI Entertainment

任天堂(1) 任天堂先生和Miyamoto先生正在关注的移动游戏市场的未来......对“退役”模式的挑战

PACkage(1) PACkage谈论“关西电子竞技的现状和前景”的电子竞技冠军的成功条件是什么?

- 万代纳木错娱乐(1) 简单的“阅读”和“寻找”困难的“专利”......如何检查专利纠纷

- 万代纳木错工作室(2) BanaCAST发布的动作捕捉技术,支持CG人物生活提供了...“THE IDOLM @ STER”采用大型直播活动的效果 基于物理的HDR的移动版渲染“铁拳”我们遵循的困难和成功【阴影处理技术USM,PSM, SLPSM 这都是什么技术怎么搜搜不到?】

六驱动器(1) 了解为什么许多女性坠入爱河“什么是Tokimeki-一种导致恋爱中的少女的新方法 - ”......旨在为全世界带来快乐的应用程序

· Pokerabo(6) 通过设置“约束”创造的头像和效果......“SINoALICE-Sino Alice-”战斗方向的背面 非常独特的讲座,发生在“SINoALICE”发布时维修地狱“工程师-Kakuhari先生的背面Pokerabo的坦白供认 Poke Lab关于如何在大规模开发中讨论Unity的“弱点”解决方法的讲座被报道为“SINoALICE-在Synorice中使用Unity的技术 - ” Pokelab从“Senki Zessho Symphogear XD”的案例中加强了“在新游戏开始时分配UI·UX专业工程师的优点”! UI的制作过程充分反映了Yoko Otaro对世界的看法......社交游戏中表达的世界深度观点 Poke Labo同时开发多个游戏的效率提升提案:什么是负责基础和框架共性的“跨职能团队”?

· Wright Flyer Studios(3) “Dunmachi-Memoria·Flase ......”运营团队介绍的自动游戏最佳参数模拟的框架是什么? 莱特飞行器影城,对应的AI聊天机器人查询手机游戏推出了多项削减约20%的......快到秘密 从大约一年释放和半已经过去了,“另一个伊甸园宣布Cats Beyond Space-Time的开发工具的变化和发现

※按字母顺序列出

 

 

 

 

 

 

 

7、 [Unity]在Inspector中拖动和更改值时,在拖动时按住Shift或Alt 可以加快或者减慢值改变的速度。 SHIFT (faster) or ALT (slower).

按住Shift拖

按住Alt并拖动

 

 

 

 

 

 

 

8、Expressio - 算术表达式求解器 https://connect.unity.com/p/expressio-arithmetic-expression-solver

https://zzatomiic.gitlab.io/expressio/index.html

 

 

9、 宣雨凇 的 Profiler 深挖系列 ~~~

Profiler深挖-导航条(1)

Profiler深挖-CPU面板(2)

Profiler深挖-GPU面板(3)

Profiler深挖-Rendering面板(4)

Profiler深挖-Memory面板(5)

Profiler深挖-UI面板(6)

Profiler深挖-真机(7)

private void OnGUI()

{

GUILayout.Label(string.Format("<size=50>FPS : {0}</size>", (1f / Time.smoothDeltaTime).ToString("F2")));

}

一个查看FPS的方法,只需要一行代码即可。

Time.smoothDeltaTime表示Time.deltaTime的平滑时间

 

7)SetPass Call:这个数值有点意思,官方给的意思是 The number of rendering passes. Each pass requires Unity runtime to bind a new shader which may introduce CPU overhead. 翻译一下 渲染的Pass数量,每个渲染的Pass都需要绑定一个新的shader,它可能会导致CPU的开销。

这里你肯定会有疑问,到底SetPass Call 和Draw Call有啥区别呢?SetPass Call绑定了新的Shader所以它会更新到新的渲染状态,而DrawCall呢就是根据这个状态来进行绘制,但是一个Shader可能由多个Pass组成,所以同一个SetPass Call 就会产生多个DrawCall了。还不明白?我在举个更详细点的例子。将下面有两个Pass的shader放入游戏。

你会发现无论怎么复制,SetPass Call永远不会变。因为它渲染的shader没有变,所以渲染状态也不需要变。但是由于shader有两个不同的pass所以无法进行动态合批,那么自然每添加一个对象,DrawCall就会增加两个了。

1)Dynamic Batching :动态合批其实就是在CPU先将Mesh动态合并好,然后在一次性送进GPU。如果Mesh特别的大,那么动态合批肯定就非常慢了。所以Unity的动态合批是有要求的,只有顶点属性和1套UV限制900顶点以内,在增加法线后限制300顶点以内,在增加2套UV、切线限制180顶点以内。

3)Instancing:GPU Instancing技术,同mesh、同材质、同shader、同参数。一般可用来做草、石头,比较坑的是不支持lightingmap,unity2018支持了lightingmap 但是需要开启实时GI.

 

 

 

 

 

10、 VFX Toolbox Image Sequencer

Unity官方工具: https://forum.unity.com/threads/release-thread-vfx-toolbox-image-sequencer.438465/ 看视频就知道怎么使用了~~

该工具旨在成为图像序列处理的基础,其首要目标之一是以简单的方式生成flipbook纹理表。

比如说有一堆序列散图, 但是这个工具可以调整切换曲线, 生成新的flipbook图集。

文档:

https://docs.google.com/document/d/1eTJ9XTqvtKhaXUBZPLTgHiHmy4DF4uM2Zvs3SZFrAjc/edit

https://blogs.unity3d.com/2016/11/28/free-vfx-image-sequences-flipbooks/

下载:

LATEST(f2)版本在这里: ImageSequencer Only带有Assets的ImageSequencer

 

 

 

使用新的Terrain工具包加快您的工作速度

Unity 2019.1

文档: https://docs.unity3d.com/Packages/com.unity.terrain-tools@1.1/manual/

 

 

 

 

 

 

 

 

11、 Sprite有个模式, 镜像模式

它包括使用一半的图像作为资产。只有在完整图像对称的情况下才能使用。然后, 将总大小的一半保存在地图集中, 并将其绘制为 "镜像" 的两倍, 以获得完整的图像。

如果图像在垂直和水平两层都是对称的, 也可以使用图像来完成。

https://engineering.etermax.com/unity-performance-introduction-a1ede6f3b5b5

 

如果是UI 好像不能正常合批了, 使用不再是图集中的贴图。 不知道是否还有别的用处~

 

 

 

 

 

 

12、

是什么要求贴图最好是POT , 硬件? GL ? 还是贴图压缩算法? 操作系统?

https://docs.unity3d.com/Manual/ImportingTextures.html 提到npot 了 , platform or GPU

https://answers.unity.com/questions/957259/npot-non-power-of-two-textures-take-a-huge-space.html 早期版本会有这种警告, 包括预览内存大小。 这个视频就会看到内存大小的变化 。 https://www.youtube.com/watch?v=6FP5oLtyxm8

如果启用了mipmap,则只能压缩POT纹理

如果您尝试使用mipmaps压缩NPOT纹理,Unity可能会警告您“如果启用了mipmap,则只能压缩POT纹理”。您可以直接编辑纹理或使用Unity的内置纹理导入设置来强制压缩或拉伸纹理为2的幂。

扩展高级有一个'Non Power of 2'的选项,这将允许你使Unity稍微挤压或拉伸纹理到最接近的2的力量.POT纹理很重要的原因是因为除非纹理是POT你不会能够使用一些压缩格式和mipmap不能在纹理上使用。(在旧的硬件上你可能会发现NPOT纹理使用的内存比预期的要多,因为它们作为下一个最高的POT大小存储在内存中!)

 

 

 

 

 

如何:在 Unity 中创建视频聊天应用程序

使用 Agora.io的 SDK ~~~

 

 

13、 策划反馈IphoneX 上UI元素特别小(本身接近19:9 然后屏幕物理上还比较窄) 。

https://docs.unity3d.com/2019.1/Documentation/Manual/script-CanvasScaler.html

https://docs.unity3d.com/2019.1/Documentation/Manual/HOWTO-UIMultiResolution.html

https://medium.com/@johntucker_48673/building-a-responsive-ui-unity-a201a1014f9 (缩放比例计算)

           理想设置可能是下面的样子。 大部分参考分辨率都设置为 16:9 . 这个设置0.5 对于界面集中在中间的UI(就是全屏UI, 对于大部分游戏主界面基本没有问题, 因为都是靠四周的), 这个0.5可以解决这个问题。 但是会导致其他问题,比如切换到 19:9 ,, 内容可能会超出边界。 我们之前项目是设置 mathch 为1 . 但是今天发现如果设置为1基本上和 设置为 Expand 类似了。 这个是 IphoneX 上UI元素特别小的原因。

 

 

 

14、

Unity 的 Package 的另外一个地址:

https://unity.bintray.com/unity/

.npm/

com.autodesk.fbx/

com.ptc.vuforia.engine/

com.unity.2d.animation/

com.unity.2d.common/

com.unity.2d.ik/

com.unity.2d.path/

com.unity.2d.pixel-perfect/

com.unity.2d.psdimporter/

com.unity.2d.spriteshape/

com.unity.2d.triangle/

com.unity.addressables/

com.unity.ads/

com.unity.ai.planner/

com.unity.analytics/

com.unity.animation.cs-jobs-samples/

com.unity.animation.rigging/

com.unity.assetbundlebrowser/

com.unity.audio.megacityprototype/

com.unity.burst/

com.unity.cacheserver.client/

com.unity.canary-coin-game/

com.unity.canary-package.tests/

com.unity.canary-package/

com.unity.cinemachine/

com.unity.cloud-vetting-canary/

com.unity.cloud.userreporting/

com.unity.code-analysis/

com.unity.collab-proxy/

com.unity.collections/

com.unity.connect.share/

com.unity.dummy-test/

com.unity.dummypackagea/

com.unity.dummypackageb/

com.unity.dummypackagec/

com.unity.dummypackaged/

com.unity.editorcoroutines/

com.unity.entities/

com.unity.ext.nunit/

com.unity.facebook.gameroom.sdk/

com.unity.film-tv.toolbox/

com.unity.formats.alembic.tests/

com.unity.formats.alembic/

com.unity.formats.fbx/

com.unity.formats.usd/

com.unity.google.resonance.audio/

com.unity.ide.rider/

com.unity.ide.visualstudio/

com.unity.ide.vscode/

com.unity.immediate-window/

com.unity.incrementalcompiler/

com.unity.inputsystem/

com.unity.jobs/

com.unity.learn.iet-framework/

com.unity.localization/

com.unity.mathematics/

com.unity.memoryprofiler/

com.unity.mobile.adaptiveperformance/

com.unity.mobile.android-logcat/

com.unity.mobile.notifications/

com.unity.multiplayer-hlapi/

com.unity.package-manager-ui/

com.unity.package-manager.metadata/

com.unity.package-manager/

com.unity.package-under-test/

com.unity.package-validation-suite.tests/

com.unity.package-validation-suite/

com.unity.performance.profile-analyzer/

com.unity.pge/

com.unity.physics/

com.unity.playablegraph-visualizer/

com.unity.polybrush/

com.unity.postprocessing/

com.unity.probuilder/

com.unity.progrids/

com.unity.properties/

com.unity.purchasing.udp/

com.unity.purchasing/

com.unity.quicksearch/

com.unity.recorder/

com.unity.render-pipelines.core/

com.unity.render-pipelines.high-definition/

com.unity.render-pipelines.lightweight/

com.unity.rendering.hybrid/

com.unity.resourcemanager/

com.unity.scriptablebuildpipeline/

com.unity.searcher/

com.unity.settings-manager/

com.unity.shadergraph/

com.unity.standardevents/

com.unity.subsystemregistration/

com.unity.template.canary-template/

com.unity.terrain-tools/

com.unity.test-framework.performance/

com.unity.test-framework.tests/

com.unity.test-framework/

com.unity.test-package/

com.unity.test.big/

com.unity.textmeshpro/

com.unity.tiny/

com.unity.traceeventprofiler/

com.unity.uiwidgets/

com.unity.vectorgraphics/

com.unity.visualeffectgraph/

com.unity.xiaomi/

com.unity.xr.arcore/

com.unity.xr.arextensions/

com.unity.xr.arfoundation/

com.unity.xr.arkit-face-tracking/

com.unity.xr.arkit/

com.unity.xr.arsubsystems/

com.unity.xr.facesubsystem/

com.unity.xr.googlevr.android/

com.unity.xr.googlevr.ios/

com.unity.xr.interactionsubsystems/

com.unity.xr.legacyinputhelpers/

com.unity.xr.magicleap/

com.unity.xr.management/

com.unity.xr.oculus.android/

com.unity.xr.oculus.standalone/

com.unity.xr.oculus/

com.unity.xr.openvr.standalone/

com.unity.xr.windowsmr.metro/

com.unity.xr.windowsmr/

nuget.castle-core/

nuget.mono-cecil/

nuget.moq/

 

 

 

15、 Unity 2019.1.5f1中包含天空盒变化

Unity2018时还是如下:

Unity 2019.1.5 没有了 , 需要

Procedural Sky 与Skybox设置类似

Sky > Gradient Sky

Sky > HDRI Sky

https://twitter.com/z_zabaglione/status/1139116015848050688

https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@6.7/manual/Static-Lighting-Sky.html

 

 

 

16、 【Unity】如何使用Assembly Definition Files访问internal成员

https://qiita.com/toRisouP/items/156eb91dfe7e4a848dc3

AssemblyInfo.cs中

using System.Runtime.CompilerServices;

//允许从指定的dll访问内部访问级别

[assembly: InternalsVisibleTo("MyLibrary.Test")] //匹配adf中定义的名称

解决上图中的问题, 测试程序MyLibrary.Test 库要测试 MyLibrary 库, 自然需要访问 internal访问权限的成员。 就是这个应用~

 

 

 

 

 

 

 

 

17、 关于 Assetbundle 打包策略 ;

https://docs.unity3d.com/Manual/AssetBundles-Preparing.html?_ga=2.145653108.1332958240.1560227147-1366382285.1535636176

https://unity3d.com/cn/learn/tutorials/topics/best-practices/assetbundle-usage-patterns?playlist=30089

无论您遵循何种策略,这里都有一些额外的提示,这些提示可以全面记住:

  • 将频繁更新的对象拆分为AssetBundle,与很少更改的对象分开
  • 对可能同时加载的对象进行分组。例如模型,纹理和动画
  • 如果您注意到多个AssetBundle中的多个对象依赖于来自完全不同的AssetBundle的单个资产,请将依赖项移动到单独的AssetBundle。如果多个AssetBundle引用其他AssetBundle中的同一组资产,则可能值得将这些依赖项拉入共享AssetBundle以减少重复。
  • 如果不可能同时加载两组对象,例如标准和高清属性,请确保它们位于自己的AssetBundle中。
  • 如果同时经常加载50%的捆绑包,请考虑拆分AssetBundle
  • 考虑组合小型(少于5到10个资产)但其内容经常同时加载的AssetBundle
  • 如果一组对象只是同一对象的不同版本,请考虑AssetBundle Variants

决定如何将项目的资产划分为AssetBundle并不简单。采用简单的策略是很诱人的,例如将所有对象放在他们自己的AssetBundle中或只使用一个AssetBundle,但这些解决方案有明显的缺点:

  • AB太少......
    • 增加运行时内存使用量
    • 增加加载时间
    • 需要更大的下载量
  • 太多AssetBundles ......
    • 增加构建时间
    • 可以使开发复杂化
    • 增加总下载时间

关键决定是如何将对象分组为AssetBundles。主要策略是:

  • 逻辑实体
  • 对象类型
  • 并发内容

一个大AB, 三个小AB , 当然了我用的是Audio,可能根设置有关。 现象上看因为使用LoadFromFile 方式, 加载AB只是取索引 并不是LoadInMemory,所以每次都差不多(跟AB大小无关,次数越多越耗时), 但是从AB中读取读取的差别可能会不一样

从空间上看, AB本身差别不到,大的是 序列化文件。

 

 

 

 

 

 

18、

Unity\2018.2.19\Editor\Data\Resources :

unity default resources

unity editor resources

unity_builtin_extra

他们不能被移除, 我尝试更改名称, Editor没办法正常打开项目了~~

Resources / unity_builtin_extra是指整个标准资产文件夹。

不引用他们中的内容,就会被Unity进行相应的剔除~~

原始大小

 

Unity 5.x AssetBundle零冗余解决方案: https://blog.uwa4d.com/archives/1577.html

Object[] UnityAssets = AssetDatabase.LoadAllAssetsAtPath("Resources/unity_builtin_extra");
// Object[] UnityAssets = AssetDatabase.LoadAllAssetsAtPath("Library/unity default resources");
foreach (var asset in UnityAssets)
{
   // create asset...
}

 

           进一步的探索后,发现Unity具有两种内置资源,一套是"Resources/unity_builtin_extra",主要包含了是Shader,Material,UGUI的Sprite和Sprite对应的Texture,另外一套资源的路径是"Library/unity default resources",同样可以使用AssetDataBase.LoadAllAssetsAtPath()来加载,主要包含是GUI,内置Mesh这些资源以及一些未知的资源。两者的guid也各不相同:

Resources/unity_builtin_extra下资源对应的guid始终为0000000000000000f000000000000000。

Library/unity default resources下资源对应的guid始终为0000000000000000e000000000000000。

个别资源冗余的原因是中发现一些本应属于Resources/unity_builtin_extra的Material和Shader,被引用时guid却是0000000000000000e000000000000000,尝试将其修改为0000000000000000f000000000000000后发现并无差异。具体原因不明,猜测和Unity的版本、开发平台(Windows,Mac)有一定的关系。为了解决这个问题,我们对Material和Shader做了“兼容性”处理,在建立内置资源与提取出的内置资源映射关系时,手动添加一份对Library/unity default resources的映射。

 

可以使用拆包工具查看 包中都包含哪些内容 ~~~

 

 

 

 

 

19、 看到文章 ~~

如何在Unity 中使用纹理数组Texture2DArray: https://medium.com/@calebfaith/how-to-use-texture-arrays-in-unity-a830ae04c98b 感觉是个很重要的优化技术, UWA好像也分享过?

“Array textures are an alternative to atlases, as they can store multiple layers of texture data for objects without some of the problems of atlases.” — OpenGL Wiki

“数组纹理是图集的替代品,因为它们可以为对象存储多层纹理数据,而不会出现图集的某些问题。” - OpenGL Wiki

https://docs.unity3d.com/ScriptReference/Texture2DArray.html

https://docs.unity3d.com/Manual/SL-TextureArrays.html

https://answer.uwa4d.com/question/5a7e9f79847802258a065084

Texture2D Array example, https://gist.github.com/Spaxe/57de76c993a4dc8bb37275acbe597ef2

 

 

 

 

20、当“显卡驱动程序不支持GPU分析”错误时该怎么办。

           两个点, 一个是要看图形API是否支持, 比如Mac 上可能有两个选项,调整一下顺序。

           第二个就是可能因为勾选了 Graphics Jobs(Experimental)* 。 (使用HDRP创建Unity 2019.1.6.f1的项目时,默认情况下会选中此处的复选框)。 https://docs.unity3d.com/2018.3/Documentation/Manual/ProfilerGPU.html

Note that GPU profiling is disabled when Graphics Jobs (Experimental) is enabled in the Player settings. See documentation on Standalone Player settings for more information. On macOS, GPU profiling is only available under OSX 10.9 Mavericks and later versions.

 

 

 

 

21、 UGUI 的RichText 确实产生更多的三角面和顶点

<color=red><size=18>N</size></color>

N

 

 

 

 

 

22、set Quad scale to match videoplayer aspect ratio

设置Quad scale 以匹配videoplayer 纵横比

需要快速videoplayer四网格缩放器,以匹配视频大小,所以这是一个小编辑器帮助脚本

访问脚本表单VideoPlayer上下文菜单(右键单击VideoPlayer组件标题)

using UnityEngine;
using UnityEditor;
using UnityEngine.Video;
namespace UnityLibrary
{
    public class GetVideoAspectRatioEditor : MonoBehaviour
    {
        [MenuItem("CONTEXT/VideoPlayer/Get Aspect Ratio for Mesh")]
        static void DoubleMass(MenuCommand command)
        {
            // get aspect ratio
            VideoPlayer v = (VideoPlayer)command.context;
            if (v.clip == null)
            {
                Debug.LogError("No videoclip assigned..");
                return;
            }
            float aspectRatioY = v.height / (float)v.width;

            // record undo
            Undo.RecordObject(v.transform, "Set scale");

            // scale mesh
            Vector3 scale = v.transform.localScale;
            // fix only height
            scale.y *= aspectRatioY;
            v.transform.localScale = scale;
        }
    }
}

 

 

 

23、

[Unite Tokyo 2018]什么!Unity!是什么支持Mirita的“AKANE Daisakusen”?

https://www.slideshare.net/UnityTechnologiesJapan002/unite-2018-tokyo-96336266?ref=https://learning.unity3d.jp/726/

https://learning.unity3d.jp/726/

《[Unite Tokyo 2018]实现“Mirishita”的“13人生活”的“AKANE Daisakusen”优化项目的全貌明显......!》

https://gamebiz.jp/?p=210335

此外,为低GPU性能的终端准备了低分辨率模式,然后应用MSAA使锯齿变得不明显。

为了优化。 有必要组建一个可以与开发团队分开的特殊团队。 。

我们的目标是最终使平均FPS接近60,前提是“不要降低视觉质量”作为实现目标的政策。我们的目标是首先达到以下四点,大致分为两点。

  • SetPassCall(DrawCall)减少
  • GPU负载减少

纹理图集

索引缓冲区合并

减少材质

调整绘图顺序

  • CPU负载减少

加快摆动计算处理

  • 处理线程处理(允许非工作CPU工作)内存优化

有没有生成GC的设备?

结果,平均FPS接近60。

(在16.6666 ...... ms内完成该过程)

 

UnityProfiler之外,我们一直确认使用Snapdragon Profiler等,以了解我们所做的改进如何反映在图中。

 

实施方式: PDCA 步骤

P 优化思路的优先次序

D实施

C建立和测量(简介)

A进一步的想法

※Plan(计划)→Do(执行)→Check(评估)→Act(改进)

为了更容易测试 可以打开/关闭优化项目。

 

为了处理绘图负载, 我们没有重建Asset。因此,加藤先生宣布它使用了一种称为子网格集成的方法。

在“Mirishita”中,角色的模型分为头部和身体。这一次,我解释了塑造身体的衣服,亮片,皮肤和人物颜色。

 

https://learning.unity3d.jp/event/

https://learning.unity3d.jp/event/unite-tokyo-2018/

https://learning.unity3d.jp/event/cedec-2018/

 

 

 

 

 

 

 

24、 https://support.unity3d.com/hc/en-us/articles/206619726-The-characters-are-displayed-with-a-different-font-Where-can-I-see-the-Fallback-font-list-per-platform-

          关于有些文字会不显示的问题~

Font Names:当字体或字符不可用时使用的后备字体列表(见下文)。

默认字体资产

          默认字体资源是动态字体,设置为使用Arial。如果Unity无法在您的计算机上找到Arial字体(例如,如果您没有安装它),它将回退到Unity捆绑的字体,名为Liberation Sans。

           andriod系统有自己的默认字体Droid Sans(只含西文字符),和默认中文字体Droid Sans Fallback。unity把Arial字体在andriod平台上映射为Droid Sans (Fallback)。但是由于Android的碎片问题,国内低端手机(小米,魅族等)砍掉系统默认字体。

          使用Arial的另外一个问题是,作为unity默认字体,unity不会把Arial真正打包进安装文件,无法找到这个字体源文件,无法更改Font Names属性,在找不到默认字体的系统里就会不显示中文了。

            所以更好的一个做法是做空壳。导入一种字体但不打包到安装文件,设置好Font Names属性(包含各个平台的字体名列表),则在不同的平台上调用不同的字体。只要确保发布时指定的Font Names属性里有目标平台的字体就行。

 

https://docs.unity3d.com/Manual/class-Font.html

Unity Arial Font 反编译得到的数据: Unity对内置资源做了保护, 没办法拷贝出来。

Font font = Resources.GetBuiltinResource<Font>("Arial.ttf"); // 加载

Font clonedFont = (Font)Object.Instantiate(font); // 这个会报错。

AssetDatabase.CreateAsset(font, "Assets/ArialFont.TTF");// 这个也会报错, 提示已经存在了

pathID:10102
PPt:{fileID: 0 (unity default resources), pathID: 10102, m_Name: Arial, type: Font}
PPt.h:1551892732
PPt.u:4250982280371110140
AssetName:unity default resources
classID: 128 (Font)
Asset offset: 113272 (0x0001BA78)
Asset length: 51094 (0x0000C796)
baseDefinitions: False for 2018.2.0b9
AssetBundleName: 
AsLink: {fileID: 12800000, guid: dd36cb7b5e7f46ac8cd65035df5b2976, type: 3}
AsLinkUnity: {fileID: 12800000, guid: dd36cb7b5e7f46ac8cd65035df5b2976, type: 3}
- required version metadata: 2018.2.0b9(gen: 17)
- will be used version    : 2018.2.0f2(gen: 17)
Metadata:
----------
  m_Name: "Arial"
  m_LineSpacing: 14.94873
  m_DefaultMaterial: {fileID: 2100000, guid: 7047a5e4536a404bb2b56489a7813706, type: 2}
  m_FontSize: 13
  m_Texture: {fileID: 2800000, guid: 16ba080aab6c4a898e0daa310b4929c0, type: 3}
  m_AsciiStartOffset: 0
  m_Tracking: 1
  m_CharacterSpacing: 0
  m_CharacterPadding: 1
  m_ConvertCase: -2
  m_CharacterRects: []
  m_KerningValues:
  - 70: 44: -1
  - 70: 46: -1
  - 80: 44: -1
  - 80: 46: -1
  - 84: 44: -1
  - 84: 46: -1
  - 84: 58: -1
  - 84: 59: -1
  - 84: 97: -1
  - 84: 99: -1
  - 84: 101: -1
  - 84: 111: -1
  - 84: 115: -1
  - 86: 44: -1
  - 86: 46: -1
  - 89: 44: -1
  - 89: 45: -1
  - 89: 46: -1
  - 89: 101: -1
  - 89: 111: -1
  - 89: 113: -1
  m_PixelScale: 0.1
  m_FontData: byte[50788]{....}
  m_Ascent: 11.76855
  m_Descent: -2.754883
  m_DefaultStyle: 0
  m_FontNames:
  - "Liberation Sans"
  - "Arial"
  m_FallbackFonts: []
  m_FontRenderingMode: 0
  m_UseLegacyBoundsCalculation: 0
  m_ShouldRoundAdvanceValue: 1
----------
Metada-end

https://blog.csdn.net/cp1001/article/details/31409659网上类似文章很多:

https://blog.csdn.net/oSKyTonight/article/details/45250071

Unity 中有API 判斷一個字符是否在Font中: 但是有點問題。

https://answers.unity.com/questions/1150139/why-fonthascharacter-always-returns-true-on-dynami.html

https://answers.unity.com/questions/1474367/fontgetcharacterinfo-always-returns-false.html

https://docs.unity3d.com/ScriptReference/Font.GetCharacterInfo.html

https://docs.unity3d.com/ScriptReference/Font.HasCharacter.html

https://docs.unity3d.com/ScriptReference/Font.RequestCharactersInTexture.html

 

 

 

 

25、 https://twitter.com/XRofFlynn/status/1140418091836248064

在2019.3中,我们添加了将Unity嵌入其他原生iOS或Android应用程序的支持。 想要将Unity仅用于部分应用程序(例如,您可能想要Unity for AR体验),或者您希望进行高度自定义初始化,您现在可以! 了解如何:

https://blogs.unity3d.com/2019/06/17/add-features-powered-by-unity-to-native-mobile-apps/?utm_source=twitter&utm_medium=social&utm_campaign=vrar_global_generalpromo_2019-06-17_2019.3-library&utm_content=blog_unity-as-library (中国官方应该会翻译)

https://forum.unity.com/threads/using-unity-as-a-library-in-native-ios-android-apps.685195/

在某些情况下,使用本机平台技术(如Android / Java和iOS / Objective C)的开发人员希望在他们的应用/游戏功能中包含Unity(通常用于3D / 2D实时渲染),如AR体验,与3D模型的交互,2D迷你游戏等。

从Unity 2019.3.a2开始,我们引入了一项新功能,通过将Unity运行时组件和您的内容集成到本机平台项目中,将Unity用作本机应用程序中的库。Unity Runtime Library公开控件以管理本机应用程序中何时以及如何加载/激活/卸载。

请注意,使用Unity作为库需要您深入了解Android / Java和iOS / Objective C应用程序的体系结构。

限制

虽然我们测试了Unity作为由本机应用程序托管的库的许多场景,但Unity不再控制运行时的生命周期,因此我们无法保证它在所有可能的用例中都能正常工作。

例如:

Unity作为库支持仅渲染全屏,不支持在屏幕的一部分上渲染。

不支持加载Unity运行时的多个实例。

您可能需要调整第三方插件(本机或托管)才能正常工作。

工作原理

整体构建过程仍然相同,Unity创建了iOS Xcode和Android Gradle项目,但为了启用此功能,我们更改了生成的iOS Xcode和Android Gradle项目,它们现在具有以下结构:

包含所有源代码和插件的库部件(iOS框架和Android Archive(AAR)文件)

一个精简的启动器部件,包括应用程序表示数据和运行库

有关如何在需要时将iOS / Android库部件包含到本机应用程序中的分步说明。

本文的其余部分描述了Xcode / Android Gradle项目的变化。

 

 

 

 

 

26、

Guilty Gear Xrd的日漫风shader一直被看作是业内这方面的标杆。几年前看了GGX的制作人在GDC上讲他们的shader

GDC视频链接:https://www.youtube.com/watch?v=yhGjCzxJV3E

虽然游戏中照片般逼真的实时图形质量每天都在提升到近乎特色电影的质量,但Arc System Works的RED团队采用了与Guilty Gear Xrd完全不同的方法来追求令人印象深刻的艺术风格。 在这种竞争激烈的环境 该团队的使命是在现代化的全3D图形框架内重建经典的2D格斗游戏,同时保持其所有的老派2D魅力。 在本次GDC 2015演讲中,技术艺术家Junya C Motomura将讨论艺术和编程研发,以及所有艺术决策,从而获得屡获殊荣的成果。

https://www.element3ds.com/thread-151972-1-1.html

https://www.bilibili.com/video/av23586843/

下载素材: https://share.weiyun.com/57YSmlJ

早就有人在Unity中的实现:

https://forum.unity.com/threads/guilty-gear-xrd-shader-test.448557/

https://forum.unity.com/attachments/guilty-gear-xrd-shader-test-unitypackage.213646/

PPT: http://www.ggxrd.com/Motomura_Junya_GuiltyGearXrd.pdf

https://www.dropbox.com/s/65cwf6kjuezhwdl/GuilltyGearXrd_shader.pdf?dl=0

 

 

 

 

 

 

 

 

 

27、 基本上每个项目都会做 字体剔除, 但是字体剔除导致有些生僻字或者别的语言可能显示不出来。 如果字体中不包含通常就是看不到没有任何宽度。

如果是使用工具剔除的,通常就是表现为固定宽高的空格。

 

Unity 中有API 判斷一個字符是否在Font中: 但是有點問題。

https://answers.unity.com/questions/1150139/why-fonthascharacter-always-returns-true-on-dynami.html

https://answers.unity.com/questions/1474367/fontgetcharacterinfo-always-returns-false.html

https://docs.unity3d.com/ScriptReference/Font.GetCharacterInfo.html

https://docs.unity3d.com/ScriptReference/Font.HasCharacter.html

https://docs.unity3d.com/ScriptReference/Font.RequestCharactersInTexture.html

 

話不錯1を1シ111ыжиб1ż111ęཔ1པཔཔ1པ11鄜᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛᠛‍ᡌ1ᠨᠨ111

 

注意宽高=2的判断不知道是否保险。 比如误杀 空格了 。

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

/// <summary>
/// 检查输入的文字如果不在字体内,或者在字体内被剔除的处理
/// </summary>
[RequireComponent(typeof(InputField))]
public class InputFieldCheck : MonoBehaviour
{
    [SerializeField] private InputField inputField;
    private List<Char> charactersList;

#if UNITY_EDITOR
    private void Reset()
    {
        inputField = GetComponent<InputField>();
    }
    private void OnValidate()
    {
        inputField = GetComponent<InputField>();
    }

#endif

    private void Awake()
    {
        if (inputField == null)
        {
            inputField = GetComponent<InputField>();
        }
        if (inputField.characterLimit > 0)
        {
            charactersList = new List<char>(inputField.characterLimit);
        }
        else
        {
            charactersList = new List<char>();
        }

        inputField.onValueChanged.AddListener(InputOnValueChanged);
    }

    /// <summary>
    /// Unity这个回调,会对每次改变处理,如果是拷贝会对每次增加一个字符处理(字数越多调用越多)
    /// </summary>
    /// <param name="str"></param>
    private void InputOnValueChanged(string str)
    {
        var textCom = inputField.textComponent;
        Font font = textCom.font;

        // Request characters. 强制立即处理不要等UGUI的渲染(由于不是Unicode,必须调用后才有数据)
        var oldStr = str;
        font.RequestCharactersInTexture(oldStr);

        charactersList.Clear();
        for (int i = 0; i < oldStr.Length; i++)
        {
            CharacterInfo charInfo;
            //var charInfors = font.characterInfo;   // Editor测试,如果将字体导入设置为 ,数组大小是28522,所有都处理了?  如果就是默认的Dynamic,就很少,我看到是200多。  
            //TrueTypeFontImporter fontData = (TrueTypeFontImporter)AssetImporter.GetAtPath("Assets/SparkAssets/Fonts/Font0.ttf");
            //fontData.fontTextureCase = FontTextureCase.Unicode;   // Dynamic
            //fontData.SaveAndReimport();

            var have = font.GetCharacterInfo(oldStr[i], out charInfo);

            //have = !font.HasCharacter(Text.text[i]);
            if (!have || (charInfo.glyphHeight == 2 && charInfo.glyphWidth == 2 && oldStr[i] != ' '))
            {
                CharToList(i, '*');
            }
            else
            {
                CharToList(i, oldStr[i]);
            }
        }

        var newStr = new string(charactersList.ToArray());
        inputField.text = newStr;  // 不会触发 onValueChanged
    }

    private void CharToList(int index, char c)
    {
        if (charactersList.Count <= index)
        {
            charactersList.Add(c);
        }
        else
        {
            charactersList[index] = c;
        }
    }
}

 

 

 

 

28、指定文件夹下的内容强制变脏 Dirty ,重新序列化

问题是(也不算问题):

public class Example : MonoBehaviour
{
    public int m_AAAAA;
    public int m_BBBBB = 151;
}

例如,如果预制件附有上述组件

如果有一点脚本更改为:

public class Example : MonoBehaviour
{
}

但是Prefab中已经序列化的内容是不会被删除的, 这个是Unity的机制问题。

有人写了一个Editor脚本, Project中选中组件, 通过点击菜单,就可以让引用这个组件的所有Prefab变脏。

https://github.com/Syy9/UnityForceDirty/blob/master/UnityForceDirty.cs

 

 

 

 

 

 

29、详细了解Unity的本机UI系统的工作原理

https://connect.unity.com/p/ui-batching-in-unity

Canvas的主要功能是将元素批处理在一起。批处理意味着它需要具有相同纹理和材质的所有相同元素,并且如果可以的话,尝试将它们放入1个绘制调用中。如果它不能这样做,它会创建更多的绘制调用,你拥有的越多,你的UI设计效率就越低。 自5.2版以来,UI使用的批处理系统已经被拆分。这意味着所有sorting 代码都被拆分为快速的小线程,这些线程在有时间时执行(这样它们就不会阻塞主线程)。

UI合批主要是下面这四步, 了解每一步在做什么?

1. GenerateRendableUIInstructions

- 获取所有Canvas Renderers数据并复制它(因为线程)。

- 确定实际可以被渲染的指令;

-----alpha是零吗?(如果是,则不会将其添加到渲染中,因为无需渲染)

-----是零大小?(如果是,则不会将其添加到渲染中,因为无需渲染)

-----它是否被RectMask2D调用?(它是否在剔除区域之外? - 如果是,那么它会被丢弃)

2. SortForBatchingJob

- 这里所有批处理的东西都被分类成'桶'(buckets)

- 一旦计算了order ,它就开始准备批处理作业batch jobs

3. PrepareBatchesJob

- 这实际上是准备将可渲染的UI指令传递给图形设备以进行一些处理

4. UIGeometryJob

- 这会转换顶点,修改颜色并应用光照(如有必要)

 

一旦UIGeometryJob完成,就会发生以下两种情况之一:

1. 如果它是Overlay canvas,canvas 将数据直接呈现给显卡本身(在帧的末尾,在绘制其他所有内容之后)

2. Screen Space Camera和World Space canvases,将自身插入到相机的渲染队列中,并进一步处理以与您拥有的所有其他世界几何体进行分类。

提示:如果您不需要照明,也不需要UI内的粒子系统,Overlay画布是最快的选择,因为您不必等待其他任何事情。Unity没有对它进行任何额外的处理。

 

BATCHING - Sorting Buckets

每个网格'square'被认为是一个bucket(桶)。在处理排序并通过所有可渲染指令rendable instructions时,他们系统需要弄清楚 Image(用Image来说)可以放入多少桶中。如果Image 跨越3x4网格方块squares,它将被拆分为12个不同的存储区。

如果同一个桶中有多个“items”,则会进行额外处理。计算深度((sorting order)。

批量 - 常见问题

1. 元素未对齐

- 看z轴; 你应该使用相同的z; 没有相同的对齐方式会导致批次中断,因为它会影响绘制顺序并显着增加批次数。 (因为默认z是0,所以普遍认为z不为0导致问题)

- 这可以在绘制调用计数(或调试器)中看到; 所以这是一个需要注意的巨大优化

- 轻松解决此问题 - >选择所有UI并将其置于z = 0或任何其他值,只需将整个UI放在同一个z

2. Sprite不共享相同的纹理

- 不在一个图集中 (填写相同的图集名称, 确保精灵的设置相同(例如,一个可以在mip贴图上,另一个不在;)如果属性不匹配,你会得到不同的地图集; 所以只需检查您的导入设置(对于您的ui图形)并使它们完全相同,以便它们可以一起批处理)

3. 动静分离

- Canvas子元素属性发生变化时(例如RectTransform的值,或者可能是Image的颜色 )

4. Graphic Raycaster与Canvas组件携手合作。它用于捕获UI的点击/触摸。

- 如果您有多个堆叠的Graphic Raycasters,则只会触发顶部的一个。如果你使用override sorting,这是非常有效的,因为如果一个Graphic Raycaster'被触发',那么在该帧上不会检查(忽略)所有其他的。这对于按钮或阻止UI上的点击/触摸尤其有用。

 

 

在2019.6.22 (笔记2019.6.15)的文章中 提到过:: 《在不使用UnityEngine.UI的情况下在Canvas上绘图》

看Unity UGUI的开源代码,UnityEngine.UI.dll的内容在Bitbuckethttps://bitbucket.org/Unity-Technologies/ui中。每个人都可以阅读它, 会看到是有Dirty脏标记(顶点,材质,Layout三个脏标记吧),Unity 会在 Canvas.willRenderCanvases事件中检查脏标记,如果有就会重新绘制合批等等操作。

http://light11.hatenadiary.com/entry/2019/06/02/214125 《如何防止因uGUI重建而导致性能下降》 uGUI性能下降有两个主要原因:图形重建和布局重建。 填充率和set-pass调用次数是导致uGUI性能下降的主要原因。 文章有分析原因和最后的建议。 特别是两者重建的不同。

http://light11.hatenadiary.com/entry/2019/06/04/200423 《总结了降低uGUI性能的所有主要原因和解决方案。》

Profiler的关于UI的两个统计:

 

 

 

 

 

 

 

30、 【Unity】如何从文本中删除富文本标签(HTML标签)

需求比如要统计文字个数(不应该算上标签) https://www.hanachiru-blog.com/entry/2018/12/29/164557

使用C#正则表达式删除标签。

https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expressions

using UnityEngine;
using System.Text.RegularExpressions;     
public class TestDeleteTag : MonoBehaviour
{
    private const string TEXT = "请<size=12>关注</size><color=red> Twitter </color>。";
    void Start()
    {
        //请<size=12>关注</size><color=red> Twitter </color>。
        Debug.Log(TEXT);

        //删除<O>或<O>
        string text = Regex.Replace(TEXT, "<[^>]*?>", string.Empty);

        //请关注Twitter。
        Debug.Log(text);
    }
}

 

 

 

31、【Visual Studio】使用Format on Save插件自动代码格式化

Format on Save :

https://marketplace.visualstudio.com/items?itemName=WinstonFeng.FormatonSave

 

Format document on Save : https://marketplace.visualstudio.com/items?itemName=mynkow.FormatdocumentonSave

 

ReSharper Format On Save : https://marketplace.visualstudio.com/items?itemName=MackenzieZastrow.ReSharperFormatOnSave

 

插件可以执行:

  • 使用BOM将字符代码设置为UTF8
  • 指定换行代码(Mac / Win)
  • 删除未使用的命名空间
  • 将制表符转换为空格
  • 调整{}的位置

 

 

 

 

 

 

32 、 关于枚举 Enum

enum Color
{
    Red, // 0        //默认情况下,第一个为0
    Green, // 1
    Blue // 2
}

可以使用初始化器。

enum Color
{
    Red = 1,
    Green = 2,
    Blue = 3
}

每种类型的枚举都有一个基类型,可以是除char之外的任何整数类型(默认为int)。也可以明确指定。

enum Color : byte
{
    Red = 1,
    Green = 2,
    Blue = 3
}

UnityInspector默认支持 枚举的显示和选择。 单选。 做位运算不会报错,但是VS会提示警告改为Flags,也没办法位运算生效。

但是我们有的时候需要Unity的 camera 的 CullingMask , 物理的 LayerMask 可以做多选。

Flags

要将枚举用作标志,请添加特殊属性System.FlagsAttribute。这需要显式初始化值,每个值都是幂值(因为要支持位运算)。

[System.FlagsAttribute]
    public enum Color : byte    // 注意在最后测试的时候不能是byte, 因为byte没办法赋值-1
    {
        //None = 0,
        Red = 1, // 2 ^ 0
        Green = 2, // 2 ^ 1
        Blue = 4 // 2 ^ 2
    }

使用按位OR运算,您可以组合枚举的元素,并使用HasFlag(Enum)方法检查实例中是否存在位字段。

var color = Color.Red | Color.Green | Color.Blue;
var hasFlag = color.HasFlag(Color.Red | Color.Green); // True

使用按位AND操作,您还可以执行检查。

var aColor = Color.Red | Color.Green;
var bColor = Color.Green | Color.Blue;
// 检查位字段
var contains = (aColor & bColor) == bColor; // False
// 检查位域的交集
var overlaps = (aColor & bColor) != 0; // True

 

但是遗憾的是UnityInspector并没有对 Flags 做默认支持。 所以需要开发自己处理。 方式最最简单就是覆盖全局的Enum显示。

接下来,您需要实现PropertyDrawer。如果被序列化的属性具有Flags属性,那么我们将使用EditorGUI.MaskField方法进行绘制,否则使用标准的EditorGUI.PropertyField方法。另请注意,属性可以是数组的元素。下面的代码应放在名为Editor的文件夹中。

[CustomPropertyDrawer(typeof(Enum), true)]
public sealed class EnumPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        using (new EditorGUI.PropertyScope(position, label, property))
        {
            if (HasEnumFlagsAttribute())
            {
                var intValue = EditorGUI.MaskField(position, label, property.intValue, property.enumDisplayNames);

                if (property.intValue != intValue)
                {
                    property.intValue = intValue;
                }
            }
            else
            {
                EditorGUI.PropertyField(position, property, label);
            }
        }

        bool HasEnumFlagsAttribute()
        {
            var fieldType = fieldInfo.FieldType;

            if (fieldType.IsArray)
            {
                var elementType = fieldType.GetElementType();

                return elementType.IsDefined(typeof(FlagsAttribute), false);
            }

            return fieldType.IsDefined(typeof(FlagsAttribute), false);

        }
    }
}

除了特定的枚举值之外,编辑器还增加了两个:

Nothing - 整数值为0 ;

Everything - 整数值为-1。

当然了如果使用插件 Odin Inspector ,这些都包含了。

 

 

 

 

 

 

33、 典型的递归

https://docs.unity3d.com/Manual/DeactivatingGameObjects.html

void DeactivateChildren(GameObject g, bool a) 
{
    g.activeSelf = a;
    
    foreach (Transform child in g.transform) 
    {
        DeactivateChildren(child.gameObject, a);
    }
}

 

 

 

34、 如何处理从Unity到iOS和Android的剪贴板(2019版)

Debug.Log($"剪贴板文本 = {GUIUtility.systemCopyBuffer}");
GUIUtility.systemCopyBuffer = "新剪贴板文本";

2017.4

Note: iOS and Android do not support this feature.

此时它不受支持,所以我不得不编写一个原生插件。

2018.1

Note: tvOS and Tizen do not support this feature.

除了tvOS和Tizen之外。

2019.1

Note: tvOS does not support this feature.

还不支持tvOS。

 

 

 

35、 https://www.lua.org/gems/sample.pdf

            这个机制有点类似于C# 的List 。

a = {} a.x = 1; a.y = 2; a.z = 3 目前Lua创建的空表没有预先分配的插槽。如果你用C语言编程,你可以避免与Lua的那些重复

API函数lua_createtable。它在无所不在之后收到两个论点

lua_State:数组部分的初始大小和散列部分的初始大小

通过给新表提供适当的大小.

           在Lua中编程时,您可以使用构造函数来避免那些初始化

rehashings。 当你写{true,true,true}时,Lua事先就知道了

该表的数组部分需要三个插槽,因此Lua创建了表

那个大小。 同样,如果你写{x = 1,y = 2,z = 3},Lua将创建一个表

哈希部分有四个插槽。 例如,下一个循环在2.0秒内运行:

          同理,不建议: table.insert , 改为使用构造器更好。

    local buttonTypes = {}
    table.insert(buttonTypes, ButtonType.Info)
    table.insert(buttonTypes, ButtonType.Chat)
    table.insert(buttonTypes, ButtonType.AddFriend)
    table.insert(buttonTypes, ButtonType.AddBlack)
    table.insert(buttonTypes, ButtonType.SendFlower)

 

通过反编译工具看到 , 这种创建就是数组部分, 数组长度在构造器中已经输出了

还有一个命令表明 每50个newtable 就会进行setList 就是对数组部分操作。

local collent2 = {

{},

{},

{},

local collent2 = {

{1,2,3,4,5,6,7},

{},

{},

{},

构造器方式没有扩容,直接分配指定大小容量

这种创建就是 Hash 部分, hash 长度在构造器中输出了

还有一个命令表明 每newtable 就会进行settable 就是对hash部分操作。

local collent2 = {

[1] = {},

[2] = {},

[3] = {},

[4] = {},

 

 

 

 

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:Age of Ai 设计师:meimeiellie 返回首页

打赏作者

u010019717

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值