這是第137篇UWA技術知識分享的推送。今天我們繼續為大家精選了若干和開發、最佳化相關的問題,建議閱讀時間10分鐘,認真讀完必有收穫。

UWA 問答社群:answer。uwa4d。com

UWA QQ群2:793972859(原群已滿員)

渲染

Q:想問下大家,我們的專案中,黑色的特效用渲染到紋理的方式會被濾掉,這個是什麼原因呢?或者有什麼材質可以解決這樣的問題呢?

如何避免特效渲染出錯?

A1:

渲染攝像機有背景色的問題,要用RenderTexture正確地以UI為背景繪製Additive類的材質,需要很特殊的方法。 大致思路是RenderTexture使用者,用一個Blend為 One OneMinusSrcAlpha的材質。 攝像機背景色用RGB黑色,Alpha為0。 Additive和不透明的直接畫就可以(Additive Alpha為0直接疊加,不透明為1直接覆蓋)。原先AlphaBlend的材質,混色也改為One OneMinusSrcAlpha,然後RGB自己乘以Alpha(Alpha為自身Alpha,所以RenderTexture那邊正確衰減Dst的顏色)。 感謝歐月松@UWA問答社群提供了回答

A2:

檢視下是不是粒子特效使用的Shader裡使用了ColorMask RGB,導致沒有寫入Alpha通道的資訊。

補充:

之前的專案遇到過同樣的問題,題主沒有繼續回覆,我猜應該是Additive材質的問題,我記錄下我們專案遇到的問題和解決方案,給遇到類似問題的人參考。

1)用了Additive材質,效果跟題主相同,被過濾了。

2)我們的部分特效製作採用了粒子貼圖採用不透明的貼圖,要顯示的透明部分採用黑色,跟背景疊加呈現出半透的效果,這個渲染到RenderTexture顯示的結果是呈現方塊,貼圖黑色的部分呈現背景的顏色。

其實這兩種情況,都是RenderTexture的透明通道資訊出了問題,第一種情況是內建的Additive裡面採用ColorMask RGB,對Alpha通道資訊進行了過濾,一般背景是RGB黑色,Alpha為0,所以RenderTexture的Alpha通道資訊為0,再和背景混合時就被過濾了,第二種情況沒有透明度資訊。

碰到渲染到RenderTexture效果不對的資訊,可以先在Editor下透過Alpha通道模式檢視RenderTexture的Alpha通道資訊,確認是否是因為Alpha資訊寫入錯誤。

知道是Alpha資訊寫入錯誤,那麼如何修改呢?

1)特效用自己的定製的Shader,將Alpha通道資訊寫進去,如果只有一層特別並且背景是RGB黑色Alpha0的話沒問題,但是如果有多層特效,那麼RenderTexture最後記錄是最後一個渲染的特別混合出來的Alpha值,再拿這個值跟UI混合結果是錯誤的。小米超神最佳化裡關於特效渲染到紋理對這個問題進行了比較詳細的描述。

https://

blog。uwa4d。com/archives

/Severe_MOBA。html

2)就是樓上月松同學講的方法,RenderTexture跟UI混合的時候,Blend One OneMinusSrcAlpha, 這樣RenderTexture渲染出來的東西其實是疊加到UI背景上,而背景也可以進行一定程度的混合,這個方法也存計算上的差別,跟我們正常渲染特效的混合方式不同,所以要調整貼圖顏色正確的顯示。

3)在要渲染的特效後面加個面片,把UI背景貼上去,這樣,特效可以和背景正確的混合顯示,渲染出來的RenderTexture覆蓋UI背景。 這也是我前一個專案最後採用的方案。

感謝趙林@UWA問答社群提供了回答

該回答由UWA提供,歡迎大家轉至社群交流:

https://

answer。uwa4d。com/questi

on/5bec285228a16f55acc394b0

邏輯程式碼

Q:框架C# + Lua。我們的Unity遊戲在安卓手機上會出現越來越卡的情況,想問幾個問題:

1)我們建立了Texture物件,只要不引用,但是沒呼叫Destroy函式。GC能回收呼叫嗎?

2)AssetBundle裡生成的紋理物件,可以使用Resources.unLoad清理成功嗎?

3)編輯器模式。為什麼我在程式碼裡迴圈生成1000個new Texture物件。並且存在list,卻沒看到Profiler有任何變化(編輯器的Mono是會一直在增加的,但是我生成的時候依舊沒有加的很快,還是在慢慢增加)

4)卡頓感覺並不是記憶體太高的原因,好像是有很多東西沒有被銷燬,還存在Unity裡面,一直在執行導致的?

A1:

回答如下:

Texture不走GC,必須手動銷燬

請用AssetBundle。Unload

https://

docs。unity3d。com/Manual

/AssetBundles-Native。html

憑感覺可還行,很多東西沒銷燬佔用的也是記憶體。

感謝凱奧斯@UWA問答社群提供了回答

A2:

回答如下:

資源類的東西都不走GC

AssetBundle。Unload

Mono是會一直在增加,是因為Profile記錄的資料是在Mono裡面的

卡頓可以在Profiler中看一下是哪個函式執行時間過長來修復

感謝蕭小俊@UWA問答社群提供了回答

該回答來自UWA問答社群,歡迎大家轉至社群交流:

https://

answer。uwa4d。com/questi

on/5bee4d69a1dae055a7c051cd

渲染

Q:根據T4M的Shader寫了一個專案的版本出來,但是原Shader沒問題,我自己寫的Shader出現了Lightmap不正確的問題。

在XCode上真機Profile發現我新寫的Shader的texcoord0和texcoord1在bind VBO的offset相同,也就是傳進來的UV和LightmapUV資料來源是一樣的。感覺影響這個的只有appdata,但是我自己寫的appdata也很簡單:

struct appdata_t4m

{

float4 vertex : POSITION;

float3 normal : NORMAL;

float2 texcoord : TEXCOORD0;

float2 lightmapUV : TEXCOORD1;

};

而且發現stride也不對,按我這個appdata傳的資料stride應該是40(pos+normal+uv0+uv1=4x3+4x3+4x2+4x2=40),但是看到stride只有32。

只要換回原本的Surface版本的T4M就沒問題,所以感覺不是動態載入或者Mesh上面的問題,實在找不到什麼原因了。

A1:

看了下T4M的Shader應該是Surface Shader,如果你是自己寫Surface Shader,Lightmap是Unity自動處理的。如果你是要寫VF Shader,建議你把T4M的Shader生成VF Shader,看一下生成出來的程式碼,應該就能找到原因了。Unity 預設靜態Lightmap是存在TEXCOORD1,動態Lightmap是存在TEXCOORD2。

一天到頭困來的@UWA問答社群分享了該回答

A2:

直接抄Unity原生Shader的話,

#ifndef LIGHTMAP_OFF o。lmap。xy = v。texcoord1。xy * unity_LightmapST。xy + unity_LightmapST。zw; #ifndef DYNAMICLIGHTMAP_OFF o。lmap。zw = v。texcoord2。xy * unity_DynamicLightmapST。xy + unity_DynamicLightmapST。zw; #endif #endif

可能是unity_LightmapST 和 unity_DynamicLightmapST之類的引數沒有用上導致的。 感謝歐月松@UWA問答社群分享了該回答

該回答來自UWA問答社群,歡迎大家轉至社群交流:

https://

answer。uwa4d。com/questi

on/5be3e75df13b5823887f4ee7

渲染

Q:我想實現逆水寒莊園的網格線,如下圖。用LineRenderer繪製一條線一個GameObject,感覺開銷很大,改用自建立Mesh並用Shader來繪製網格線,但這兩種方案都有一個很嚴重的效果問題,就是視野稍遠處的線都會變花,攝像機視角轉動的時候更是明顯。請問Unity中要實現如下的網格效果,用什麼方式效果好開銷小呢?

如何避免特效渲染出錯?

A:

可以嘗試在MeshRenderer新增第二個材質。材質使用一個Repeat取樣的方塊溝邊貼圖,然後調整UV縮放率來解決。

歐月松@UWA問答社群提供了回答,歡迎大家轉至社群交流:

https://

answer。uwa4d。com/questi

on/5bed107ca1dae055a7c051ba

邏輯程式碼

Q:我們以前的專案是簡單異或加密,後續新專案打算統一下這塊,網上搜到的多數做法是通用的網路通訊加密方案設計,沒有針對於網路遊戲的特定定製的,所以看看大家是怎麼實現的。這裡的加密只涉及網路訊息傳遞這層,不涉及客戶端和伺服器本身的安全(也就是假設它們是安全的),我的問題如下:

1)大家有沒有做加密?為什麼?

我們做了加密,抱的心態是“多少加點密,明文還是不太妥 - 即使是probuffer等2進位制序列化方案也是可以解析出value的”。加密之外更多遵循“客戶端不可信”的原則,在具體的業務通訊協議設計上保證無論客戶端發來怎樣的訊息,伺服器都不受騙(我們無損失,對方無受益)。

2)在機密性這層,用的是“自研加密演算法”,還是公開的標準演算法?為什麼?

我們是簡單異或

3)在完整性這層,是否有做保證?用的什麼方案? - 我們沒做

4)在防重放這層,是否有做保證?用的什麼方案?- 我們沒做

現代加密體系常用套路如下圖,大家是按這個套路來的嗎?選了其中哪些元件?做了哪些定製?為什麼?

如何避免特效渲染出錯?

參考:

TLS 1.2/1.3

很棒的文章:

https://

blog。helong。info/blog/2

015/09/07/tls-protocol-analysis-and-crypto-protocol-design

https://

zhuanlan。zhihu。com/p/28

850798

微信mmtls:

https://github。com/WeMobileDev/article/blob/master/基於TLS1。3的微信安全通訊協議mmtls介紹。md

A1:

我覺得題主你的功課已經做得挺足了~稍微聊聊我們專案,但因為我主要還是做客戶端,協議加密這塊不是特別熟悉,所以只提供一些資訊供參考。

1)當然要做加密……“客戶端不可信”原則是業務層遵守的東西,而這層東西首先因為人的原因會導致一些極限情況考慮不周,另外就是有些情況下從設計上就不太能做到萬無一失。而且我個人認為協議加密是為了提高做外掛的難度——不加密裸奔,協議被人看個精光,豈不是很容易看出來漏洞,另外即使沒有邏輯漏洞,也方便做一些並不是直接獲得收益的輔助外掛。所以做協議加密我覺得是基本的職業素養,否則會被同行嘲笑,很沒有面子(玩笑)。

2)推薦公開標準演算法。自研的哪有論文+行業驗證過的標準演算法好。

3)至於完整性和防重這塊做不做,做多深,我覺得是看專案時間和精力,有時間和精力肯定做一下更好。

協議加密和客戶端防破解的功能類似,都是在給破解者提高門檻。因為可以抓包,所以協議資料對於破解者來說跟客戶端資源一樣,都是可以輕鬆拿到的內容,所以做一定程度的加密我覺得是完全有必要的。而做到什麼程度,其實是一個性價比的事情。比如做基本的AES加密,其實就可以過濾掉70-80%的小白破解者,而當破解你的遊戲的商業利益夠大的時候,自然就有更多的高階破解者入局,這時候可能基本的加密就不夠用了(參考吃雞)。

我們都不願面對破解者,但是有人在破解你的遊戲的時候,也可能意味著你的遊戲在掙錢。

感謝賈偉昊UWA問答社群提供了該回答

A2:

邏輯跑在遊戲伺服器,無BUG,是不需要做加密的。而且讓別人開發輔助工具去為遊戲服務,是被推薦或允許的,又或者自帶輔助工具。

比如:我們公司的MMO,戰鬥部分是跑在伺服器,其它的功能更不用說,所以基本沒什麼問題,也已經上線執行中。重要的是伺服器要驗證!

感謝Robot。Huang@UWA問答社群分享了該經驗

該回答來自UWA問答社群,歡迎大家轉至社群交流:

https://

answer。uwa4d。com/questi

on/5bebe503a1dae055a7c051af

今天的分享就到這裡。當然,生有涯而知無涯。在漫漫的開發週期中,您看到的這些問題也許都只是冰山一角,我們早已在UWA問答網站上準備了更多的技術話題等你一起來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官網:www。uwa4d。com

官方技術部落格:blog。uwa4d。com

官方問答社群:answer。uwa4d。com

官方技術QQ群:793972859(原群已滿員)