国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity跨平臺(tái)開發(fā)指南(PC/VR/Android/WebGL)

這篇具有很好參考價(jià)值的文章主要介紹了Unity跨平臺(tái)開發(fā)指南(PC/VR/Android/WebGL)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

通常我在進(jìn)行不同平臺(tái)的設(shè)置時(shí)會(huì)基于以下幾點(diǎn):

1:創(chuàng)建、開發(fā)、打包時(shí)我們通常針對(duì)Player和Quality設(shè)置進(jìn)行質(zhì)量的設(shè)定

2:在不同平臺(tái)上運(yùn)行時(shí),有不同的平臺(tái)包體大小,加載方式的限定,測(cè)試、打包上的區(qū)別,幀率穩(wěn)定60

3:代碼封裝上的區(qū)別,特別針對(duì)單一項(xiàng)目轉(zhuǎn)為不同不同平臺(tái)的問題

4:輸入系統(tǒng)的不同

一、PC

PC硬件相對(duì)比較強(qiáng)大,所以對(duì)于內(nèi)存大小,貼圖質(zhì)量,模型面數(shù)的限制沒有其他平臺(tái)那么大,PC和其他平臺(tái)的Input系統(tǒng)也有所差別,PC端更加注重畫面質(zhì)量,細(xì)節(jié),包括燈光、渲染等問題,所以我通常在開發(fā)PC版本的項(xiàng)目時(shí),第一考慮在開發(fā)目的,開發(fā)需求都能滿足的前提下,如何在幀率穩(wěn)定的前提下,將畫面的質(zhì)量提升到最好,當(dāng)然美術(shù)給的資源是確定的,只能使用Profier對(duì)占用資源比較多的部分進(jìn)行優(yōu)化

1:針對(duì)Player Setting、Quality設(shè)置

PlayerSetting如下,我會(huì)針對(duì)如下的所有選項(xiàng)進(jìn)行詳解

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

1:PlayerSetting
Resolution

? ? ? ? FullscreenMode:針對(duì)目標(biāo)軟件是哪種全屏模式

????????????????Fullscreen Window:通常的選項(xiàng),默認(rèn)的全屏模式,始終以桌面分辨率運(yùn)行,其他請(qǐng)求的分辨率將進(jìn)行縮放以適合此窗口

? ? ? ? ? ? ? ? Exlusive FullScreen:此模式會(huì)更改顯示器的操作系統(tǒng)分辨率來匹配應(yīng)用程序選擇的分辨率,設(shè)置應(yīng)用程序以保持對(duì)顯示器的單獨(dú)全屏使用

? ? ? ? ? ? ? ? Maximized Window(Mac):Mac Only

? ? ? ? ? ? ? ? Windowed:窗口模式

? ? ? ? Defult is Native Resolution:是否自動(dòng)分配分辨率

? ? ? ? Run In BackGround:后臺(tái)運(yùn)行,如果為False,則比如OnApplicationPause則不起作用

Standalone Player Options

? ? ? ? Capture Single Screen:Unity定義是全屏游戲是否應(yīng)使輔助顯示變暗。

? ? ? ? Use Player Log:向日志文件寫入調(diào)試信息,一般路徑是C:\user\用戶\AppData\LocalLow\CompanyName\ProjectName找到日志文件

? ? ? ? Resizable Window:在獨(dú)立平臺(tái)播放器構(gòu)建中使用可調(diào)節(jié)大小的窗口

? ? ? ? Visible In Background:與全屏窗口模式結(jié)合使用,如果使用全屏窗口模式,可在后臺(tái)顯示應(yīng)用程序

? ? ? ? Allow Fullscreen Switch:允許用戶使用特定于操作系統(tǒng)的鍵盤快捷鍵在全屏模式和窗口模式之間切換

? ? ? ? Force Single Instance:防止應(yīng)用程序被運(yùn)行兩次

? ? ? ? Use DXHI flip model swapchain for D3D11:翻轉(zhuǎn)模型可確保最佳性能。禁用它可回退到 Windows 7 樣式的 BltBlt 模型

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

D3D11是Direct的圖形API,DXHI可以共享一份swap chain的代碼,管理屏幕輸出的部分

????????Suported Aspect Rations:寬高比適配器

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

? ? ? ? *Shared setting between multiple platforms.針對(duì)上述設(shè)置,切換平臺(tái)后仍然生效

?Other Setting

? ? ? ? ColorSpace:一般PC首選Linear的色彩空間,它的優(yōu)點(diǎn)是隨著光強(qiáng)增加,著色器的顏色會(huì)線性變亮,且Linear的顯示效果更好,一些移動(dòng)設(shè)備不支持Linear的色彩空間

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

? ? ? ? Auto Graphics API for Windows/Mac/Linux:圖形渲染API,如果對(duì)渲染的流程或者有特殊的渲染需求,效果,可以進(jìn)行自己選擇,一般情況下自動(dòng)選擇

? ? ? ? Static Batching:靜態(tài)批處理,通過把物體設(shè)置為Static或者Bathing Static,將靜態(tài)物體合并為一個(gè)大網(wǎng)格,從而以更快的速度渲染它們,這里面會(huì)牽扯到一個(gè)DrawCall的概念,簡(jiǎn)單來說,DrawCall就是CPU先準(zhǔn)備好模型的數(shù)據(jù)(包括模型各個(gè)頂點(diǎn)的坐標(biāo)、法線方向、紋理等),然后CPU告訴GPU,如果我們需要渲染1000個(gè)三角形,那么把它們按1000個(gè)單獨(dú)的網(wǎng)格進(jìn)行渲染(1000次DrawCall)所花費(fèi)的時(shí)間要遠(yuǎn)大于>>直接渲染1個(gè)包含了1000個(gè)三角形的網(wǎng)格(1次DrawCall)。使用批處理,可以減少DrawCall,這就是靜態(tài)批處理的概念, 當(dāng)然還有動(dòng)態(tài)批處理

? ? ? ? GPU Skinning:簡(jiǎn)單的來說就是GPU蒙皮,蒙皮是指將Mesh中的頂點(diǎn)附著(綁定)在骨骼之上,而且每個(gè)頂點(diǎn)可以被多個(gè)骨骼所控制,這樣在關(guān)節(jié)處的頂點(diǎn)由于同時(shí)受到父子骨骼的拉扯而改變位置就消除了裂縫。

說明:此操作只支持VR應(yīng)用,僅在項(xiàng)目中選擇支持虛擬現(xiàn)實(shí)時(shí)才起作用

? ? ? ? 這里講的很詳細(xì):Unity的GPUSkinning進(jìn)一步介紹_gpu skin-CSDN博客

? ? ? ? Graphics Jobs:用來決定Unity是否使用工作線程來承擔(dān)渲染任務(wù)。如果不勾選此項(xiàng),這些工作將由主線程或渲染線程承擔(dān)。如果平臺(tái)支持這個(gè)選項(xiàng),它將會(huì)帶來較大的性能提升。如果我們希望開啟這個(gè)特性,我們應(yīng)該對(duì)比開啟和不開啟的情況的性能表現(xiàn)。?

????????Texture compression format:壓縮方式是有特定的壓縮算法的,DXT是PC端常用的壓縮算法,質(zhì)量比較低,一般的壓縮算法如下:

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

ETC是Android平臺(tái)通用的壓縮格式,質(zhì)量較低

ASTC是Android和IOS平臺(tái)下的一種高質(zhì)量壓縮方式,支持Android5.0和iPhone6以上機(jī)型

具體的可以參照各平臺(tái)的推薦、默認(rèn)和支持的紋理壓縮格式 - Unity 手冊(cè)

? ? ? ? Normal Map Encoding:法線貼圖的編碼方式

? ? ? ? Lightmap Encoding:用于控制光照貼圖的編碼/壓縮,選擇?High Quality?將啟用 HDR 光照貼圖支持,而?Normal Quality?將切換為使用?RGBM?編碼。 在移動(dòng)平臺(tái)上,__Low Quality__ 將切換為?dLDR?編碼,在其他平臺(tái)上相當(dāng)于?Normal Quality

在桌面平臺(tái)和游戲主機(jī)平臺(tái)上,Lighting 窗口中啟用了光照貼圖?Compression?時(shí),將使用?BC6H?壓縮格式來壓縮光照貼圖。對(duì)于移動(dòng)平臺(tái),Unity 根據(jù)下表選擇 HDR 格式,具體的參數(shù)可以參照官方手冊(cè)

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎
? ? ? ?


? ? ? ? Lightmap Streaming:啟用光照貼圖流,在啟用的情況下,可僅在需要時(shí)加載光照貼圖mipmap。要渲染當(dāng)前的游戲攝影機(jī),Unity會(huì)在生成紋理時(shí)將該值應(yīng)用于光照貼圖紋理。

????????Frame Timing Stats:啟用幀計(jì)時(shí)統(tǒng)計(jì),啟用后,播放器會(huì)收集 CPU 和 GPU 幀計(jì)時(shí)統(tǒng)計(jì)信息??梢允褂?FrameTimingManager?類來訪問這些統(tǒng)計(jì)信息。

? ? ? ? OpenGL:Profiler GPU Recorders:GPU Usage Profiler 模塊顯示應(yīng)用程序的 GPU 時(shí)間使用情況。只能在運(yùn)行模式 (Playmode) 下使用 GPU Profiler 或者用于應(yīng)用程序的構(gòu)建。不能用于對(duì) Editor 進(jìn)行性能分析。

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

注意:如果在?Player Settings?中啟用了 __Graphics Jobs__,則不支持 GPU 性能分析。

? ? ? ? Vulkan Setting/MacApp Store Options/Mac Configuration:暫時(shí)一直用GL的API和PC開發(fā),這些設(shè)置沒有用到

? ? ? ? Scripting Backend:腳本后處理(腳本編譯模式),可以選擇Mono和IL2CPP,要徹底了解這兩個(gè)選項(xiàng),就得從跨平臺(tái)Mono說起,它的工作流程是把C#編譯成IL中間語(yǔ)言,然后通過Mono運(yùn)行時(shí)中的編譯器將IL編譯成對(duì)應(yīng)平臺(tái)的原生代碼

? ? ? ? 轉(zhuǎn)譯方式有三種,即時(shí)編譯(Just In Time,JIT),程序運(yùn)行過程中,將CIL的byte code轉(zhuǎn)譯為目標(biāo)平臺(tái)的原生碼。提前編譯(Ahead of time,AOT),程序運(yùn)行之前,將.exe或.dll文件中的CIL的byte code部分轉(zhuǎn)譯為目標(biāo)平臺(tái)的原生碼并且存儲(chǔ)。

? ? ?從官方文檔可以看出兩者的區(qū)別:

  • Mono uses just-in-time (JIT) compilation and compiles code on demand at runtime.
  • IL2CPP uses ahead-of-time (AOT) compilation and compiles your entire application before it is run.

????????unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

? ? ? ? (圖片來源:【Unity游戲開發(fā)】Mono和IL2CPP的區(qū)別 - 知乎 (zhihu.com))

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

從上面兩個(gè)圖,我們可以看出使用Mono和IL2CPP的區(qū)別,Mono在游戲運(yùn)行的時(shí)候,IL和項(xiàng)目里其他第三方兼容的DLL一起,放入Mono VM虛擬機(jī),由虛擬機(jī)解析成機(jī)器碼,而IL2CPP將他們重新變回C++代碼,然后再由各個(gè)平臺(tái)的C++編譯器直接編譯成能執(zhí)行的原生匯編代碼。

所以大致的區(qū)別也如下:

  1. 相比Mono, 代碼生成有很大的提高
  2. 可以調(diào)試生成的C++代碼
  3. 可以啟用引擎代碼剝離(Engine code stripping)來減少代碼的大小
  4. 程序的運(yùn)行效率比Mono高,運(yùn)行速度快
  5. 多平臺(tái)移植非常方便
  6. 相比Mono構(gòu)建應(yīng)用慢
  7. 只支持AOT(Ahead of Time)編譯

IL2CPP比較適合開發(fā)和發(fā)布項(xiàng)目 ,但是為了提高版本迭代速度,可以在開發(fā)期間切換到Mono模式(構(gòu)建應(yīng)用快)

? ? ? ? Api Compatiblity Level:參見微軟官方的介紹在 Unity 中使用 .NET 4.x | Microsoft Learn

  • .NET Standard 2.1。 此配置文件與 .NET Foundation 發(fā)布的?.NET Standard 2.1 配置文件匹配。 Unity 建議新項(xiàng)目使用 .NET Standard 2.1。 它比 .NET 4.x 小,有利于尺寸受限的平臺(tái)。 此外,Unity 承諾在 Unity 支持的所有平臺(tái)上支持此配置文件。

  • .NET Framework。 此配置文件提供對(duì)最新 .NET 4 API 的訪問權(quán)限。 它包括 .NET Framework 類庫(kù)中提供的所有代碼,并且支持 .NET Standard 2.1 配置文件。 如果 .NET Standard 2.0 配置文件中未包含項(xiàng)目所需的部分 API,請(qǐng)使用 .NET 4.x 配置文件。 但此 API 的某些部分并非在所有 Unity 平臺(tái)上均受支持。

? ? ? ? Use Incremental GC:增量式垃圾回收,有關(guān)這個(gè)選項(xiàng),這篇博文講的很清楚

unity 增量式GC_unity 增量gc_紅黑色的圣西羅的博客-CSDN博客

? ? ? ? Assembly Version Validation:when Mono Resolve types from a assembly that is strong Named,Versions have to match with the one already loaded.當(dāng) Mono Resolve 從強(qiáng)命名的程序集鍵入時(shí),版本必須與已加載的版本匹配。

? ? ? ? Active Input Handling:選擇新的輸入系統(tǒng)還是舊的輸入系統(tǒng),還是兩者都允許

? ? ? ? Shader precision model:Shader精度模型,官方有兩種,一種默認(rèn)的,一種全精度

PlatformDefault Use the target platform defaults for sampler precision. This results in lower precision on mobile targets and full precision elsewhere.
Unified Use full sampler precision by default and make it so you have to explicitly declare when you want to use lower precision. This sets BuiltinShaderDefine.UNITY_UNIFIED_SHADER_PRECISION_MODEL when Unity compiles shaders.

????????Keep Loaded Shaders Alive:一般是啟用的,因?yàn)镾hader的加載和解析很耗時(shí),所以不希望Shader被卸載

? ? ? ? Defuult chunk size:可以使用 PlayerSettings.SetDefaultShaderChunkSizeInMB 來限制壓縮塊的大小。

? ? ? ? Default chunk count:同上,用來壓縮Shader精度的,一般默認(rèn)

? ? ? ? suppress Coommon Warnings:Disable this setting to display the C# warnings?CS0169?and?CS0649.

? ? ? ? Allow unsafe Code:允許在預(yù)定義的程序集(例如,Assembly-CSharp.dll)中編譯“不安全”的 C# 代碼。

? ? ? ? Use Deterministic Compilation:啟用此設(shè)置后,每次編譯程序集時(shí),它們都是逐字節(jié)相同的。

? ? ? ? Enable Roslyn Analyzers:

? ? ? ? Prebake Collision Meshes:啟用此選項(xiàng)可在構(gòu)建時(shí)將碰撞數(shù)據(jù)添加到網(wǎng)格中。

????????Managed Stripping Level:這個(gè)功能的主要目的則是通過刪除一些未使用的代碼來減小應(yīng)用程序的大小,?the Unity Linker process can strip unused code from the managed DLLs your Project uses. Stripping code can make the resulting executable significantly smaller, but can sometimes accidentally remove code that is in use,就是說有可能會(huì)把你正在運(yùn)行的代碼也移除

,所以默認(rèn)情況是Disable的

? ? ? ? Vertex Compression:頂點(diǎn)壓縮,可以自定義選擇

? ? ? ? Optimize Mesh Data:選擇此選項(xiàng)將從構(gòu)建中使用的網(wǎng)格中剝離未使用的頂點(diǎn)屬性。
這減少了網(wǎng)格中的數(shù)據(jù)量,這可能有助于減少構(gòu)建大小、加載時(shí)間和運(yùn)行時(shí)內(nèi)存使用量。但是,如果啟用了此設(shè)置,則必須記住不要在運(yùn)行時(shí)更改材質(zhì)或著色器設(shè)置,但是這個(gè)和減少代碼量可能存在一樣的問題,導(dǎo)致的 Mesh 頂點(diǎn)數(shù)據(jù)的丟失,所以一般禁用

? ? ? ? Texture MipMap Stripping:MipMap是分級(jí)細(xì)化紋理,也可以理解為L(zhǎng)OD(Level of Detail),

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

拿這兩張圖片做比較,左邊是開啟了MipMap,右邊是沒有開啟MipMap,當(dāng)我們開啟MipMap時(shí),攝像機(jī)遠(yuǎn)處的紋理變模糊了。而右邊關(guān)閉MipMap的紋理,遠(yuǎn)處沒有模糊,這里這個(gè)功能也是移除沒有使用的貼圖Level以減少包體的大小,一般也是不開啟的

? ? ? ? Stack Trace:輸出堆棧信息,包括如下選項(xiàng)

  • None:?Unity doesn’t output stack trace information.
  • ScriptOnly:?Unity outputs stack trace information only for managed code. This is the default option.
  • Full:?Unity outputs stack trace information for both managed and unmanaged code.

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

2:Quality Setting

Quality - Unity 手冊(cè)

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

這里可以選擇配置文件,渲染管線,貼圖質(zhì)量等

Anisotropic Textures:各向異性紋理,選擇 Unity 是否以及如何使用各向異性紋理。選項(xiàng)包括?Disabled、Per Texture?和 _Forced On_(即始終啟用)。

Particle Raycast Budget:設(shè)置用于模擬粒子系統(tǒng)碰撞的最大射線投射數(shù)

Billboards Face Camera Position:公告牌將面向攝像機(jī)位置而不是攝像機(jī)方向

Shadowmask Mode:ShadowMask和Distance ShadowMask,前者是默認(rèn)的陰影遮罩,后者Distance Shadowmask__是?Shadowmask(陰影遮罩)__光照模式的一個(gè)版本。該模式由場(chǎng)景中的所有混合光源共用,可提供從靜態(tài)游戲?qū)ο笸渡涞絼?dòng)態(tài)游戲?qū)ο蟮母哔|(zhì)量陰影,提供更高性能的平臺(tái)才能夠使用此選項(xiàng)

Asyne Asset Upload:

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

LOD(細(xì)節(jié)級(jí)別):

Lod Bias:設(shè)置細(xì)節(jié)級(jí)別 (LOD) 偏差。根據(jù)對(duì)象在屏幕上的大小選擇 LOD 級(jí)別。當(dāng)大小在兩個(gè) LOD 級(jí)別之間時(shí),可以偏向于兩個(gè)可用模型中細(xì)節(jié)級(jí)別更低或更高者。此屬性設(shè)置為 0 到 +無窮大之間的值。設(shè)置為 0 到 1 之間時(shí),表示傾向于更少細(xì)節(jié)。超過 1 的設(shè)置表示傾向于更多細(xì)節(jié)。例如,將 LOD Bias 設(shè)置為 2 并使其在 50% 距離處變化,LOD 實(shí)際上僅基于 25% 變化。

Maximum LOD Level:設(shè)置游戲使用的最高 LOD

Skin Weights:選擇在動(dòng)畫期間可以影響給定頂點(diǎn)的骨骼數(shù)量??捎眠x項(xiàng)包括?1 Bone2 Bones、4 Bones?和?Unlimited。

2:包體大小限定,加載方式

PC打包的包體大小一般沒有特定的限制,除非對(duì)于特定的安裝包有大小的限定或者發(fā)布平臺(tái)的限制,一般是追求最高畫質(zhì),但是需要提前預(yù)留好不同畫質(zhì)下的貼圖質(zhì)量以保證不同PC設(shè)備的流暢運(yùn)行


PC的加載方式和Web和安卓有些,一般都是提前打包好所有資源,這樣可以保證流暢加載

3:代碼的封裝問題

針對(duì)PC沒有特定的規(guī)范,只要耦合性好,擴(kuò)展性好,有邏輯層次,都沒有太大問題,但是當(dāng)你的PC項(xiàng)目需要轉(zhuǎn)化到Android的時(shí)候,就需要提前把適配不同平臺(tái)的代碼準(zhǔn)備和封裝好

4:PC測(cè)試、打包

一般情況PC的調(diào)試比較方便,可以使用Development Build,或者查看Log日志即可

二、Android

1:針對(duì)PlayerSetting、Quality

Android Player 設(shè)置 - Unity 手冊(cè)文章來源地址http://www.zghlxwxcb.cn/news/detail-811956.html

這里面的設(shè)置基本和我上面介紹的沒有什么差異,基本差別在于

ColorSpace、LightmapEncoding(硬性要求)、Texture Compression

安卓多了Minimum API Level、Target API Level,需要適配不同機(jī)型,基本上最低我會(huì)選擇到Android5.1,最高是Autimatic

2:包體大小限定,加載方式,測(cè)試

安卓項(xiàng)目對(duì)于包體大小有嚴(yán)格的限定,我一般選擇ASTC壓縮方式,包體大小會(huì)小很多

測(cè)試使用Development Build,Build and Run,Android Studio這三種進(jìn)行測(cè)試

3:輸入方式

我采用了EasyTouch插件,一般移動(dòng)端有比如單擊,雙擊,滑動(dòng)屏幕等操作,使用的代碼也不是很復(fù)雜

雙擊/長(zhǎng)按

 if (Input.GetMouseButton(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                #region 雙擊
                if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)//判斷幾個(gè)點(diǎn)擊位置而且是最開始點(diǎn)擊的屏幕,而不是滑動(dòng)屏幕
                {
                    if (Input.GetTouch(0).tapCount == 2)//tapcount是點(diǎn)擊次數(shù)
                    {
                        Destroy(hit.collider.gameObject);
                    }
                }
                #endregion


                #region 長(zhǎng)按
                if (Input.touchCount == 1)
                {
                    Touch touch = Input.GetTouch(0);
                    if (touch.phase == TouchPhase.Began)
                    {
                        newTouch = true;
                        touchTime = Time.time;
                    }
                    else if (touch.phase == TouchPhase.Stationary)//點(diǎn)擊沒有滑動(dòng)的時(shí)候會(huì)觸發(fā)Stationary
                    {
                        if (newTouch == true && Time.time - touchTime > 1f)
                        {
                            newTouch = false;

                            Destroy(hit.collider.gameObject);
                        }
                    }
                    else
                    {
                        newTouch = false;
                    }

                }
                #endregion

            }

滑動(dòng)屏幕

        if (Input.GetMouseButton(0))
        {
            if (Input.touchCount==1)
            {
                if (Input.GetTouch(0).phase==TouchPhase.Moved)//滑動(dòng)狀態(tài)
                {
                   transform.Rotate(Vector3.up * Input.GetAxis("Mouse X") * -xSpeed * Time.deltaTime,Space.World);
                }
            }
        }

雙指縮放等

    /// <summary>
    /// 判斷手勢(shì)
    /// </summary>
    /// <param name="op1">開始的第一個(gè)點(diǎn)</param>
    /// <param name="op2">開始的第二個(gè)點(diǎn)</param>
    /// <param name="np1">結(jié)束的第一個(gè)點(diǎn)</param>
    /// <param name="np2">結(jié)束的第二個(gè)點(diǎn)</param>
    /// <returns></returns>
    bool isEnlarge(Vector2 op1, Vector2 op2, Vector2 np1, Vector2 np2)
    {
        float startLength = Mathf.Sqrt((op1.x - op2.x) * (op1.x - op2.x)+ (op1.y - op2.y) * (op1.y - op2.y));

        float endLength = Mathf.Sqrt((np1.x - np2.x) * (np1.x - np2.x) + (np1.y - np2.y) * (np1.y - np2.y));

        if (startLength<endLength)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    Vector2 oldPos1;
    Vector2 oldPos2;
    void Update () {

        if (Input.touchCount==2)
        {
            if (Input.GetTouch(0).phase==TouchPhase.Moved||Input.GetTouch(1).phase==TouchPhase.Moved)
            {
                Vector2 temPosl = Input.GetTouch(0).position;
                Vector2 temPos2 = Input.GetTouch(1).position;
                if (isEnlarge(oldPos1,oldPos2,temPosl,temPos2))
                {
                    float oldScale = transform.localScale.x;
                    float newScale= oldScale*1.025f;
                    transform.localScale = new Vector3(newScale, newScale, newScale);
                }
                else
                {
                    float oldScale = transform.localScale.x;
                    float newScale = oldScale / 1.025f;
                    transform.localScale = new Vector3(newScale, newScale, newScale);
                }
                oldPos1 = temPosl;
                oldPos2 = temPos2;
            }
        }
    }

三、VR

VR也是基于Android平臺(tái),不同的是,它需要使用基于不同公司開發(fā)的SDK來接入項(xiàng)目

unity能跨平臺(tái)嗎,游戲開發(fā),C#,Unity引擎,unity,游戲引擎

對(duì)于如何配置一個(gè)VR項(xiàng)目,我之前的文章有介紹到

2023—Unity打包Pico4(3)全流程(Pico插件)-CSDN博客

1:PlayerSetting、Quality

VR對(duì)美術(shù)需求更高,比如如何制作很好的貼圖,能適應(yīng)性能的同時(shí)有很好的展現(xiàn)形式,燈光盡量也全部使用烘焙,需要多調(diào)試

2:包體大小,加載方式,測(cè)試

前面兩項(xiàng)基本相同,但是測(cè)試上,對(duì)于比較新的Pico SDK(2.1.3以上),可以使用Development Center+PICO Unity Live Preview Plugin進(jìn)行串流測(cè)試,但是實(shí)測(cè)效果并不理想

如果使用2.1.2/2.1.3可以兩端安裝Preview Tool進(jìn)行串流測(cè)試,效果比較穩(wěn)定

3:輸入方式

VR可以用如下腳本進(jìn)行監(jiān)聽,在其他腳本的OnEnable進(jìn)行監(jiān)聽即可

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

/// <summary>
/// 提供各種輸入事件
/// </summary>
public class InputEvent
{
    private static InputEvent _instance;
    private static object lockObj = new object();
    //提供一個(gè)鎖對(duì)象,以確保同時(shí)只有一個(gè)線程能夠執(zhí)行相關(guān)代碼塊
    public static InputEvent Instance
    {
        get
        {
            lock (lockObj)
            {
                if (_instance == null)
                {
                    _instance = new InputEvent();
                }
            }
            return _instance;
        }
    }

    private InputEvent()
    {
        Init();
    }

    //*************輸入設(shè)別**************************
    InputDevice leftHandController;
    InputDevice rightHandController;
    InputDevice headController;

    //**************對(duì)外提供公開事件******************
    #region public event

    public event Action onLeftTriggerEnter;
    public event Action onLeftTriggerDown;
    public event Action onLeftTriggerUp;

    public event Action onRightTriggerEnter;
    public event Action onRightTriggerDown;
    public event Action onRightTriggerUp;

    public event Action onLeftGripEnter;
    public event Action onLeftGripDown;
    public event Action onLeftGripUp;

    public event Action onRightGripEnter;
    public event Action onRightGripDown;
    public event Action onRightGripUp;

    public event Action onLeftAppButtonEnter;
    public event Action onLeftAppButtonDown;
    public event Action onLeftAppButtonUp;

    public event Action onRightAppButtonEnter;
    public event Action onRightAppButtonDown;
    public event Action onRightAppButtonUp;

    public event Action onLeftJoyStickEnter;
    public event Action onLeftJoyStickDown;
    public event Action onLeftJoyStickUp;

    public event Action onRightJoyStickEnter;
    public event Action onRightJoyStickDown;
    public event Action onRightJoyStickUp;

    public event Action<Vector2> onLeftJoyStickMove;
    public event Action<Vector2> onRightJoyStickMove;

    public event Action onLeftAXButtonEnter;
    public event Action onLeftAXButtonDown;
    public event Action onLeftAXButtonUp;

    public event Action onLeftBYButtonEnter;
    public event Action onLeftBYButtonDown;
    public event Action onLeftBYButonUp;

    public event Action onRightAXButtonEnter;
    public event Action onRightAXButtonDown;
    public event Action onRightAXButtonUp;

    public event Action onRightBYButtonEnter;
    public event Action onRightBYButtonDown;
    public event Action onRightBYButtonUp;

    #endregion

    //提供狀態(tài)字典獨(dú)立記錄各個(gè)feature的狀態(tài)
    Dictionary<string, bool> stateDic = new Dictionary<string, bool>();

    //單例模式提供的初始化函數(shù)
    // // 每個(gè)場(chǎng)景啟動(dòng)調(diào)用一次,不然保存的可能還是上一個(gè)場(chǎng)景的Controller
    public void Init()
    {
        leftHandController = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
        rightHandController = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
        headController = InputDevices.GetDeviceAtXRNode(XRNode.Head);
        //stateDic = new Dictionary<string, bool>();

    }
    //*******************事件源的觸發(fā)**************************

    /// <summary>
    /// 按鈕事件源觸發(fā)模板
    /// </summary>
    /// <param name="device">設(shè)備</param>
    /// <param name="usage">功能特征</param>
    /// <param name="btnEnter">開始按下按鈕事件</param>
    /// <param name="btnDown">按下按鈕事件</param>
    /// <param name="btnUp">抬起按鈕事件</param>
    private void ButtonDispatchModel(InputDevice device, InputFeatureUsage<bool> usage, Action btnEnter, Action btnDown, Action btnUp)
    {
        //Debug.Log("usage:" + usage.name);
        //為首次執(zhí)行的feature添加bool狀態(tài) -- 用以判斷Enter和Up狀態(tài)
        string featureKey = device.name + usage.name;
        if (!stateDic.ContainsKey(featureKey))
        {
            stateDic.Add(featureKey, false);
        }

        bool isDown;

        if (device.TryGetFeatureValue(usage, out isDown) && isDown)
        {
            if (!stateDic[featureKey])
            {
                stateDic[featureKey] = true;
                if (btnEnter != null)
                    btnEnter();
            }
            if (btnDown != null)
                btnDown();
        }
        else
        {
            if (stateDic[featureKey])
            {
                if (btnUp != null)
                    btnUp();
                stateDic[featureKey] = false;
            }
        }
    }

    /// <summary>
    /// 搖桿事件源觸發(fā)模板
    /// </summary>
    /// <param name="device">設(shè)備</param>
    /// <param name="usage">功能特征</param>
    /// <param name="joyStickMove">移動(dòng)搖桿事件</param>
    private void JoyStickDispatchModel(InputDevice device, InputFeatureUsage<Vector2> usage, Action<Vector2> joyStickMove)
    {
        Vector2 axis;
        if (device.TryGetFeatureValue(usage, out axis) && !axis.Equals(Vector2.zero))
        {
            //Debug.Log("move " + axis);
            if (joyStickMove != null)
                joyStickMove(axis);
        }
    }

    //******************每幀輪詢監(jiān)聽事件***********************
    public void onUpdate()
    {
        if (!rightHandController.isValid && !leftHandController.isValid)
        {
            Init();
        }
        ButtonDispatchModel(leftHandController, CommonUsages.triggerButton, onLeftTriggerEnter, onLeftTriggerDown, onLeftTriggerUp);
        ButtonDispatchModel(rightHandController, CommonUsages.triggerButton, onRightTriggerEnter, onRightTriggerDown, onRightTriggerUp);

        ButtonDispatchModel(leftHandController, CommonUsages.gripButton, onLeftGripEnter, onLeftGripDown, onLeftGripUp);
        ButtonDispatchModel(rightHandController, CommonUsages.gripButton, onRightGripEnter, onRightGripDown, onRightGripUp);

        ButtonDispatchModel(leftHandController, CommonUsages.primaryButton, onLeftAXButtonEnter, onLeftAXButtonDown, onLeftAXButtonUp);
        ButtonDispatchModel(rightHandController, CommonUsages.primaryButton, onRightAXButtonEnter, onRightAXButtonDown, onRightAXButtonUp);

        ButtonDispatchModel(leftHandController, CommonUsages.secondaryButton, onLeftBYButtonEnter, onLeftBYButtonDown, onLeftBYButonUp);
        ButtonDispatchModel(rightHandController, CommonUsages.secondaryButton, onRightBYButtonEnter, onRightBYButtonDown, onRightBYButtonUp);

        ButtonDispatchModel(leftHandController, CommonUsages.primary2DAxisClick, onLeftJoyStickEnter, onLeftJoyStickDown, onLeftJoyStickUp);
        ButtonDispatchModel(rightHandController, CommonUsages.primary2DAxisClick, onRightJoyStickEnter, onRightJoyStickDown, onRightJoyStickUp);

        ButtonDispatchModel(leftHandController, CommonUsages.menuButton, onLeftAppButtonEnter, onLeftAppButtonDown, onLeftAppButtonUp);
        ButtonDispatchModel(rightHandController, CommonUsages.menuButton, onRightAppButtonEnter, onRightAppButtonDown, onRightAppButtonUp);

        JoyStickDispatchModel(leftHandController, CommonUsages.primary2DAxis, onLeftJoyStickMove);
        JoyStickDispatchModel(rightHandController, CommonUsages.primary2DAxis, onRightJoyStickMove);
    }
}

四、WebGL

1:PlayerSetting、Quality

因?yàn)閃ebGL的特性,所以貼圖質(zhì)量和模型精度不能太高,不然包體會(huì)比較大,所以必須舍棄其中之一,要么是展現(xiàn),要么是速度

2:大小限定,加載方式,測(cè)試

WebGL的包體最好控制在200M以內(nèi),這樣上傳到服務(wù)器后,加載的壓力比較小

所以對(duì)于WebGL項(xiàng)目最好采用遠(yuǎn)程加載的方式,可以使用AB包或者Addressable加載方式,關(guān)于Addressable加載,可以參照林新發(fā)的文章【精選】【游戲開發(fā)探究】Unity Addressables資源管理方式用起來太爽了,資源打包、加載、熱更變得如此輕松(Addressable Asset System | 簡(jiǎn)稱AA)_player content must be built before entering play -CSDN博客

WebGL的測(cè)試也比較繁瑣,必須網(wǎng)站運(yùn)行出來才可以看到,所以采用Development的打包方式

3:Inputsystem系統(tǒng)和PC基本一樣

參考:

WebGL Player 設(shè)置 - Unity 手冊(cè)

Quality - Unity 手冊(cè)

Player - Unity 手冊(cè)(PC)

Android Player 設(shè)置 - Unity 手冊(cè)

到了這里,關(guān)于Unity跨平臺(tái)開發(fā)指南(PC/VR/Android/WebGL)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 開源、跨平臺(tái)安卓摸魚(投屏)軟件 Scrcpy 中文使用指南

    開源、跨平臺(tái)安卓摸魚(投屏)軟件 Scrcpy 中文使用指南

    廢話不說,先上鏈接:GitHub上的Scrcpy Scrcpy 可以將手機(jī)畫面投射到電腦上,讓你可以在電腦上對(duì)手機(jī)進(jìn)行操控。Scrcpy 通過 USB 或 Wi-Fi 與安卓手機(jī)相連,不需要在手機(jī)上安裝任何 app,也不需要取得 ROOT 權(quán)限。 簡(jiǎn)單地說,就是可以讓你在電腦上控制手機(jī)!它支持鼠標(biāo)控制、鍵盤

    2024年02月12日
    瀏覽(38)
  • 跨平臺(tái)指南:在 Windows 和 Linux 上安裝 OpenSSL 的完整流程

    跨平臺(tái)指南:在 Windows 和 Linux 上安裝 OpenSSL 的完整流程

    一:找到安裝包,雙擊即可 https://gitee.com/wake-up-again/installation-package.git 二:按照提示,一步一步來,就可以啦 三:此界面意思是,是否想向創(chuàng)作者捐款,自己視情況而定啦。 四:安裝完畢之后,接下來就是VS下的環(huán)境配置了。 在VS下創(chuàng)建一個(gè)新項(xiàng)目,點(diǎn)到屬性界面 五:找到

    2024年04月23日
    瀏覽(24)
  • 跨平臺(tái)開發(fā)技術(shù)

    跨平臺(tái)開發(fā)技術(shù)

    個(gè)人搜集資料并總結(jié)了一些跨平臺(tái)開發(fā)技術(shù),如有不足歡迎指正。 1.簡(jiǎn)介 QT是一個(gè)跨平臺(tái)的C++圖形用戶界面應(yīng)用程序框架。它為應(yīng)用程序開發(fā)者提供建立藝術(shù)級(jí)圖形所需的所有功能。它是完全面向?qū)ο蟮模菀讛U(kuò)展,并且允許真正的組件編程。 2.優(yōu)勢(shì) 使用Qt開發(fā)的程序可以運(yùn)

    2024年02月08日
    瀏覽(90)
  • C語(yǔ)言跨平臺(tái)游戲開發(fā)

    通常我們認(rèn)為, 純C (即不使用C艸)很難實(shí)現(xiàn)跨平臺(tái)的游戲。這是由于它支持的圖形庫(kù)非常少,一般需要調(diào)用系統(tǒng)句柄才能進(jìn)行圖形化。但是很顯然這是一個(gè)及其費(fèi)時(shí)費(fèi)力還容易出錯(cuò)的方式。所以,在這篇文章里,我希望給大家介紹一些 比較 輕松的制作C語(yǔ)言的跨平臺(tái)游戲的

    2023年04月15日
    瀏覽(19)
  • 跨平臺(tái)開發(fā)方案的三個(gè)時(shí)代

    跨平臺(tái)開發(fā)方案的三個(gè)時(shí)代

    跨平臺(tái)開發(fā)從本質(zhì)上講是為了增加業(yè)務(wù)代碼的復(fù)用率,減少因?yàn)橐m配多個(gè)平臺(tái)帶來的工作量,從而降低開發(fā)成本。在提高業(yè)務(wù)專注度的同時(shí),能夠?yàn)橛脩籼峁┮恢碌挠脩趔w驗(yàn),實(shí)現(xiàn)“多快好省”的效果。 跨平臺(tái)是跨哪些平臺(tái)?怎么樣的跨平臺(tái)邏輯?從當(dāng)前的實(shí)際情況來看,

    2024年02月09日
    瀏覽(20)
  • 前端移動(dòng)端開發(fā)分類及跨平臺(tái)開發(fā)框架簡(jiǎn)述

    前端移動(dòng)端開發(fā)分類及跨平臺(tái)開發(fā)框架簡(jiǎn)述

    前端移動(dòng)端主流分為以下三種:Native App ,Hybrid App ,Web App 優(yōu)點(diǎn): (1)用戶體驗(yàn)好 (2)性能穩(wěn)定 (3)操作速度快 (4)能夠訪問本地資源(通訊錄,相冊(cè)) (5)能夠設(shè)計(jì)出色的動(dòng)效,轉(zhuǎn)場(chǎng) (6)擁有系統(tǒng)級(jí)別的貼心通知或提醒 (7)用戶留存率高 缺點(diǎn): (1)開發(fā)成本高

    2024年02月04日
    瀏覽(98)
  • 我想開發(fā)一款跨平臺(tái)桌面軟件,請(qǐng)告訴我qt、electron、tauri、pyqt、flutter分別適合開發(fā)哪些跨平臺(tái)桌面

    我想開發(fā)一款跨平臺(tái)桌面軟件,請(qǐng)告訴我qt、electron、tauri、pyqt、flutter分別適合開發(fā)哪些跨平臺(tái)桌面

    不同的跨平臺(tái)桌面開發(fā)工具適用于不同的應(yīng)用場(chǎng)景和開發(fā)者需求。以下是關(guān)于 Qt、Electron、Tauri、PyQt、Flutter 的簡(jiǎn)要說明,以幫助你更好地選擇適合你項(xiàng)目的工具: Qt: 適用場(chǎng)景: Qt 是一個(gè)強(qiáng)大的 C++ 框架,適用于開發(fā)需要高性能和原生外觀的桌面應(yīng)用。它具有廣泛的平臺(tái)支持

    2024年02月22日
    瀏覽(94)
  • C#使用xamarin進(jìn)行跨平臺(tái)開發(fā)

    使用 Xamarin 進(jìn)行跨平臺(tái)開發(fā)可以使用 C# 和 .NET 平臺(tái)來開發(fā)移動(dòng)應(yīng)用程序,同時(shí)將代碼在多個(gè)主要移動(dòng)操作系統(tǒng)上運(yùn)行,包括 Android 和 iOS。以下是在 C# 中使用 Xamarin 進(jìn)行跨平臺(tái)開發(fā)的一般步驟: 安裝 Xamarin : 在開始之前,你需要安裝 Xamarin 開發(fā)環(huán)境。你可以選擇安裝 Visual

    2024年02月11日
    瀏覽(96)
  • C++庫(kù)封裝mongodb(跨平臺(tái)開發(fā))

    目錄 1.開發(fā)環(huán)境準(zhǔn)備 2.編譯mongo-c-driver (linux環(huán)境) ?3.編譯mongo-c-driver (windows環(huán)境)

    2024年02月11日
    瀏覽(27)
  • 滾動(dòng)條詳解:跨平臺(tái)iOS、Android、小程序滾動(dòng)條隱藏及自定義樣式綜合指南

    滾動(dòng)條詳解:跨平臺(tái)iOS、Android、小程序滾動(dòng)條隱藏及自定義樣式綜合指南

    滾動(dòng)條是用戶界面中的圖形化組件,用于指示和控制內(nèi)容區(qū)域的可滾動(dòng)范圍。當(dāng)元素內(nèi)容超出其視窗邊界時(shí),滾動(dòng)條提供可視化線索,并允許用戶通過鼠標(biāo)滾輪、觸屏滑動(dòng)或直接拖動(dòng)滑塊來瀏覽未顯示部分,實(shí)現(xiàn)內(nèi)容的上下或左右滾動(dòng)。它在保持界面整潔、避免內(nèi)容溢出的同

    2024年04月27日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包