【厚積薄發】Lua與C#之間的穿梭問題
來自專欄 UWA:簡單優化、優化簡單
這是第111篇UWA技術知識分享的推送。今天我們繼續為大家精選了若干和開發、優化相關的問題,建議閱讀時間15分鐘,認真讀完必有收穫。
UWA 問答社區:answer.uwa4d.com
UWA QQ群:465082844(僅限技術交流)
腳本
Q:Lua與C#之間的調用頻率是影響Lua性能很重要的因素,最近我們的項目也在分析這類問題。如何統計Lua與C#之間調用的次數呢?我感覺要注入的代碼有點多,我們寫了大量的warp代碼,每個都添加有點不現實,而且warp代碼都是自動生成的。大家有什麼好建議嗎?
我們項目用的是ToLua,Unity版本是5.6.1p1。
A1:Lua調用C#用debug.sethook。
雲風有一個基於這個方法寫的工具cloudwu/luaprofiler,不過不能直接拿來用,需要自己編庫。除了這個以外,直接在Lua裡面掛上也是可以的,比較影響性能。
C#調用Lua看LuaFunction。感謝凱奧斯@UWA問答社區提供了回答。
A2:Lua和C#之間的調用次數統計的工具,只需要修改一下ToLua導出warp介面的地方就好了,重新生成一次代碼,加上宏或者條件編譯的控制,就可以很方便地做到即可以在編輯器模式下做次數統計,又可以不影響發布到設備上的過程。
生成的代碼可以自己添加tag,用於統計,比如我們的一個調用代碼:
UWA在UWA Day上展示的過程就更簡單,直接封裝成函數,通過[Conditional(「XXX」)]來控制就好了。
如果要統計C#反向調用Lua的地方,LuaFunction的幾個Call函數是一個切入點。
感謝賈偉昊@UWA問答社區提供了回答
歡迎大家轉至社區進行進一步交流:
LUA調用次數統計 - UWA問答: 侑虎科技官方問答社區動畫
Q:為了動畫重用減少資源重複的問題,我們採用人性形動畫格式來製作。因為有第一人稱,手掌手腕是處於特寫狀態下的,所以任何瑕疵都會暴露無遺。為了避免手腕扭曲變形的瑕疵,我們添加了附加骨骼來解決問題,骨骼的位置和結構關係如下圖:
Unity中沒有添加附加骨骼的手腕旋轉效果:
Unity中添加了前臂附加骨骼的手腕旋轉效果
問題1:手腕和手臂交界處有錯位現象Max中添加了前臂附加骨骼的手腕旋轉效果(可以看出手腕扭曲完美解決,但是在Unity中效果不理想)
問題2:人形動畫格式大拇指的動畫就是沒辦法還原,總是敲著的,我們檢查過骨骼匹配問題,如下圖都是正常的,就是大拇指沒辦法彎曲。
A:Unity的人形骨骼這裡在使用的時候有不少小坑,而官方文檔很多地方寫得很隱晦,我們項目在用人形骨骼,在用Retargeting的時候也是各種動作有小問題。
先說一下我們自己得出的一些結論吧:
1)角色自己的動畫,使用自己的Avatar,人形骨骼應該是可以做到和Max以及Generic的方式的動畫完全一樣的效果;
2)如果是別的骨骼,有體型上的差異,比如身高、肩寬等,經過Retargeting的效果之後,可以做到整體效果是正確的,但是因為累積誤差的原因,距離根骨骼比較遠的骨骼,比如腳、手指等位置,會有微小的差異,比如腳不夠貼地、idle動作腳部有微小的抖動現象等等。
Retargeting的原理我之前寫過一篇文章《動畫重定向技術分析及其在Unity中的應用》,有興趣可以看看。這裡補充一些後來我們自己在使用的時候發現的點。Unity中有幾個文件,他們記錄的信息分別有:
1)Avatar文件,就是所謂的骨骼文件,這裡記錄了用於Retargeting的基本的T-pos信息,Unity中定義的是一個大T的姿勢,而Max里常用的可能是一個小T姿勢,所以這裡要做一些調整,細節後面來說;
2)動畫文件,記錄動畫差異信息。導入的動畫文件在使用人形骨骼的情況下會需要指認Avtar的引用到所對應的文件上,如果Avatar有修改,動畫文件需要進行Update操作,這個過程是重新計算差異的過程。我們觀察到,這個動畫文件的內容,和導入動畫文件的Max文件里的T-pos姿勢有很強的相關性。
如果你看了之前的文章,那這裡就比較好理解了。我們有兩套骨架,A、B,需要把B的動作應用到A上,那需要四個數據:
- A的T-pos信息;
- B的T-pos信息;
- B的動畫信息;
- A的動畫信息 = B的動畫信息 - B的T-pos信息 + A的T-pos信息。
所以前面說的動畫文件里的信息,其實應當理解為B的動畫文件和B的T-pos的差異。(這裡說得有點繞,先埋個坑吧,等我有時間了詳細整一篇博客好了。)
所以我們項目給到美術的建議是:導出Avatar的T-pos和導齣動畫的Max文件里的T-pos信息要一致,這樣才能做到動作盡量的還原。(所以你可以測試下,使用同一個Max文件導出的動畫和Avatar,在Unity里應當和Max里是完全一致的才對。)
說了半天原理,也是說上述的一些問題可能需要題主自己來根據原理推測並解決。
當然還是要說下我對於這兩個問題的想法。第一個手腕扭曲的問題,說實話我貌似遇到過,但是時間有點久遠,具體的細節不太清楚了,建議題主查看下幾個方向:
- 是否非人形骨骼也有這個問題?
- 是否可能是蒙皮的問題,或者通過修改蒙皮來解決?
- 是否是人形骨骼Avatar里的手腕的骨骼映射關係存在問題,通過調整Avatar的姿勢是否可能緩解這個問題?
第二個手指不動的問題,可能需要確認下Avatar里的姿勢手指是否和預期不一樣,這種情況可以通過給動作中的手指一個很誇張的姿勢來查看,如果真的是完全沒有動作的話,查看下動作中是否mask的設置有遺漏?
動作這塊是需要程序和動作美術一起不斷測試,才能找到一個好的平衡點。我自己是Max不夠熟悉,所以看問題的時候還要拉著美術一起。
感謝賈偉昊@UWA問答社區提供了回答,歡迎大家轉至社區進行進一步交流:
unity人形動畫手腕翻轉的製作問題 - UWA問答: 侑虎科技官方問答社區動畫
Q:動畫片段的數量對性能開銷是否有影響?若有,對同一個動畫片段,不同層級的多處復用是否也是有影響?(動畫控制器遊戲過程中沒有激活和隱藏操作,不清楚動畫片段數據的採樣和讀取消耗為何會偏高)
A1:動畫說白了就是變換而已,平移、旋轉和縮放。每一幀將變換矩陣乘到各個頂點上,而這部分是純CPU計算。
那麼與性能開銷相關的就是:頂點數量、骨骼數量、層的數量。
另外一個就是BoneWeight了,weight(n)的非零個數越多,每一幀頂點的變換計算也就越多。
所以可以優化的點:
1)減面2)減少骨骼3)精簡層
4)減少骨骼blend數量另外對於動畫所佔內存的優化,可以參考文章:Unity動畫文件優化探究感謝凱奧斯@UWA問答社區提供了回答。
UWA:除了process animation, 動畫片段數量也會對animatorcontorller的維護帶來開銷(反映在writejob上):"when using the Animator, all the properties of all the clips currently connected are written, whether the clips are playing or not. "
歡迎大家轉至社區進行進一步交流:
動畫片段的數量對性能開銷是否有影響? - UWA問答: 侑虎科技官方問答社區粒子系統
Q:當場景中有大量的環境粒子系統,針對粒子系統做過裁剪優化,請問粒子系統在遠離相機後怎麼正確的進行休眠,把粒子系統進行stop就行了嗎?會對渲染或CPU還有沒有多餘的開銷?還是只能把粒子系統根節點的gameobject的active設置為False?
UWA:建議通過Active和Deactive來進行控制,未Deactive的Particle System一樣會參與計算,比如渲染模塊中的Culling等等。同時,Active/Deactive對於粒子系統對於粒子系統的處理一般都不耗時。
該回答由UWA提供,歡迎大家轉至社區進行進一步交流:
粒子系統particlesystem如何正確休眠 - UWA問答: 侑虎科技官方問答社區
代碼
Q:我在使用Deep Profile查找代碼性能時,發現一個列表查找每次Find()都會產生2.5KB GC Alloc,然後我改變了一下寫法,不用Find(),直接for循環遍歷,發現GC Alloc沒了,耗時幾乎一樣。然後我去查找了Find()的IL,也沒覺得哪裡會產生GC,請大家指教。
A:
我猜測題主的代碼里是類似下面的這種邏輯:在一個循環里,多次執行了Find操作,Find的參數(閉包函數)使用了每次循環都會變化的non-local變數,因此產生了較多的GC。這種方式產生GC的原因是,每次循環會new一個委託對象。
感謝Walker@UWA問答社區提供了回答,大家可轉至社區進行進一步交流:
用Find()查找元素時產生GC - UWA問答: 侑虎科技官方問答社區今天的分享就到這裡。當然,生有涯而知無涯。在漫漫的開發周期中,您看到的這些問題也許都只是冰山一角,我們早已在UWA問答網站(http://answer.uwa4d.com)上準備了更多的技術話題等你一起來探索和分享。歡迎熱愛進步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之「石」,也能攻你之「玉」。
官網:www.uwa4d.com
官方技術博客:blog.uwa4d.com官方問答社區:answer.uwa4d.com官方技術QQ群:465082844(僅限技術交流)
推薦閱讀:
※lua-protobuf 使用說明
※Lua和C#調用探秘
※xmake-vscode插件開發過程記錄
※Lua5.2和5.1有哪些不同?相對與5.1有什麼進步?Lua5.2能用5.1的庫嗎?如果不能,有哪些可用的庫?
※Unity3D熱更新LuaFramework入門實戰(5)——UI