??????dnf手游于5月21號正式上線,作為一個dnf端游老玩家,并且偶爾上線ppk,自然下載了手游版,且玩了幾天。
??????不得不說dnf手游的優化做到了極好的程度。
??????就玩法系統這塊,因為dnf屬于城鎮+地下城模式,相比現在的開放世界或者半開放世界3d手游,屬于比較好優化的一類。
??????比如城鎮模塊的切換進出口,做好加載卸載就能用時間換空間,通過加載進度頁面掩蓋卸載當前城鎮加載下個城鎮的目的。城鎮中的各個區域的切換就不必考慮加載卸載了,一股腦都在場景里,通過坐標的移動和漸變黑屏的切換手法完成。
??????再比如地下成的進入,同樣使用加載卸載和進度頁面,做到和城鎮的互相切換。至于地下城不同房間,也是黑屏漸變切換+坐標移動即可。
??????UI界面這塊,dnf手游用到了動靜分離和分幀加載。因為UI的繪制調用是以Canvas為單位的。所以當UI策劃和UI設計師完成UI模塊的設計后,UI程序根據實際的UI界面業務功能,將一個UI模塊劃分為永遠不動的靜態元素(如各個背景)+一直在動的活動元素(如動態生成的物品),配合UI對象池的使用。特別注意,此時的UI對象池設計上要考慮分幀生成的概念,比如要生成100個裝備圖標,不要在一幀內生成,此時如果一幀生成一個(或可配置個數)再緩存使用,則大大降低了單幀負載壓力,可以讓UI界面的響應速度加快。當然已經生成生成好的復雜UI界面,在退出時也可根據UI管理器的調度策略,并不銷毀,而是移動坐標到視口外,再次使用則可快速加載。
??????當然分幀加載的方案在需要高響應速度的地方都可以使用。
??????地下城戰斗系統這塊,則是我的知識盲區了,雖然我做過卡牌戰斗系統,但是和dnf這種手感的格斗游戲比起來,簡直小巫見大巫,我一直覺得就手感這一塊,沒有超越dnf的格斗游戲。
??????同時dnf手游有一點讓我靈光一閃,很小的一個地方,就是子UI界面彈出,背景虛化這一塊,如下:
??????我已經好長時間沒怎么做UI界面了,在我印象中,做子UI界面彈出的時候,為了怕和背景UI界面產生視覺上的融合,都會給一個黑色半透明背景,如下:
??????感覺dnf手游這種高斯模糊挺好,雖然以前都用于3D和UI視覺分離這一塊,但是移植到UI與UI之間也挺不錯,這里順便實現一下:
Shader "UIWindowPKG/UIBlurUnlitShader"
{Properties{_GaussSize("Guass Size",Range(0,10)) = 1}SubShader{Tags { "RenderType"="Opaque" }LOD 100GrabPass{"_GrabTexture"}Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv[9] : TEXCOORD0;float4 vertex : SV_POSITION;};int _GaussSize;sampler2D _GrabTexture;float4 _GrabTexture_TexelSize;static float gaussMatrix[9] = {0.05854983,0.09653235,0.05854983,0.09653235,0.1591549,0.09653235,0.05854983,0.09653235,0.05854983};v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);float4 gpos = ComputeGrabScreenPos(o.vertex);float2 guv = float2(gpos.x/gpos.w,gpos.y/gpos.w);int c = 1;for (int x = 0; x < 3; x++){for (int y = 0; y < 3; y++){o.uv[x * 3 + y] = guv + _GrabTexture_TexelSize.xy*float2((y - c)*_GaussSize, (c - x)*_GaussSize); }}return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = fixed4(0,0,0,0);for(int k=0;k<9;k++){col += tex2D(_GrabTexture, i.uv[k])*gaussMatrix[k];}return col;}ENDCG}}
}
??????原理就是GrabPass+一次高斯濾波,效果如下:
??????我對比了一下dnf手游和一些3A游戲的做法,感覺dnf手游的實現屬于效率低下且效果不好,dnf手游用了實時的_GrabPass采樣,而不是像3A游戲一樣用一次性的截圖采樣,好處是實時顯示背景畫面。同時dnf手游的濾波只用了一次,可能是為了性能考慮,雖然平衡了實時采樣的損耗,但是效果卻比較差。而3A游戲用了多次迭代濾波,對比效果則更加強烈,當然畫面是“靜止”的。
??????繼續打dnf手游,以后把這個功能美化優化一下。