動態

詳情 返回 返回

Text Mesh Pro圖文混排如何對任何圖片都能實現 - 動態 詳情

1)Text Mesh Pro圖文混排如何對任何圖片都能實現
2)PlayerSettings.WebGL.emscriptenArgs設置無效的問題
3)Prefab對DLL中腳本的引用丟失
4)如何在第三人稱藍圖模板中獲得當前相機SpringArm的Target Arm Length


這是第386篇UWA技術知識分享的推送,精選了UWA社區的熱門話題,涵蓋了UWA問答、社區帖子等技術知識點,助力大家更全面地掌握和學習。

UWA社區主頁:community.uwa4d.com
UWA QQ羣:793972859

UI

Q:目前Text Mesh Pro圖文混排需要把圖片打入圖集並放入TMP的Resources文件夾中。項目中想在任務UI面板展示很多裝備或物品的icon,這些icon都是打好了的圖集,很多別的系統也要用,不可能都放入TMP的這個資源文件夾裏,但這樣就無法進行圖文混排,請問有什麼解決辦法嗎?

A1:把TMP裏面所有的Resources.Load接口,都替換成項目自身的Bundle加載接口,應該就可以解決了。

感謝王燦光@UWA問答社區提供了回答

A2:可以註冊以下回調:TextMeshProUGUI.OnFontAssetRequest,這樣就可以自定義一個加載方法。

如果加載成功了,TMP就不會Resources.Load。

感謝程一峯@UWA問答社區提供了回答

WebGL

Q:遊戲裏用了C++的第三方庫集成到xLua裏面,端版是用CMake構建,可以配置宏、Include路徑等,很方便。

我現在用Unity 2021.3發佈的WebGL版本,xLua是把所有Lua代碼放在了“工程目錄/WebGLPlugins”下面,在引擎裏去#include這裏的C代碼,也沒問題。

但是自己的C/C++代碼比較多,也不能全部扔在同一個目錄下,如果加了目錄,就有跨目錄Include的問題(主要是lua.h,lauxlib.h)。從實際表現來看,include .c或.cpp時,用到的.h文件如果是在同目錄就沒問題,如果跨目錄了就會找不到。

我用PlayerSettings.WebGL.emscriptenArgs = "-Imy_file_folder_path";這樣設置搜索路徑,但是沒用;然後定義宏-Dxx也沒用,不知道為什麼。(參數中沒有自己定義的路徑和宏,都是Unity自己的,雖然ProjectSettings.asset已經生效了。)

請問有解決方案嗎?

A:在Unity 2021.2之後更新Emscripten,emscriptenArgs屬性失效了,可以把Lua代碼和C/C++代碼都放到一個層級,然後改引用。

還有一個方式:找到你Unity安裝目錄\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\emcc2.py,如果沒有emcc2.py就找emcc.py,在裏面找到get_clang_command方法,這個方法就是拼接執行編譯C/C++代碼語句的,在[src_file]後面增加+ ['-IAssets/XXX/XXX'],注意-I和Assets之間沒空格,大概這樣子:

def get_clang_command(src_file):
    return get_compiler(use_cxx(src_file)) + get_cflags(options, state.orig_args) + compile_args + [src_file] + ['-IAssets/XXX/XXX']

注意py文件縮進問題,多個文件夾就添加多個“-I”,我猜因為它自己有“-I.”參數,所以可以使用相對目錄(對clang++編譯不太熟,我在Windows的Unity 2021.3.38f1上使用可行。)

compile_args變量是記錄傳進來的參數的,有精力也可以找找調用emcc2.py的地方傳進來更合適,我這邊沒找到。

其它需要改C/C++編譯參數的地方我也在這裏改了,如果有其它更簡便有效的方法,歡迎分享。

感謝高鬆@UWA問答社區提供了回答

Script

Q:開發時,不希望策劃看到源碼,於是將源碼替換成DLL,但是這樣掛在Prefab上的腳本引用會丟失,請問怎麼解決?

A1:是原有的預製掛了CS,後面想打成DLL重新掛?如果是這樣,遍歷預製,去批量修改GUID和FileID。可參考文章《Unity將C#腳本轉換為DLL,Prefab等文件不丟失引用的方法(轉)》,文章裏面用了DLLSwitcher插件,也可以自己理解Prefab GUID fileID和DLL,CS文件對應的關係就行了。

感謝c8K2SVRRcz1P@UWA問答社區提供了回答

A2:代碼要分成底層和邏輯層。底層用DLL+Obfuscator,邏輯層就不能了,因為如果也加密,開發驗收查bug都會費勁。

如果要防止策劃帶走代碼,按照我説的底層DLL就行,即使他帶出去,只有邏輯層的開發,後面也會一大堆問題,除非自己寫底層,就要調試,時間還不如自己重新寫,這樣的博弈論一旦開始,這個代碼庫重要性就不高了。

同時也要防止策劃帶走服務端代碼,做到服務端拿不到客户端,客户端拿不到服務端,這樣即使有一方代碼,也是無用代碼。

感謝夏霖鋭@UWA問答社區提供了回答

Rendering

Q:使用SpringArm組件會讓相機在發生碰撞時拉近,但是為什麼獲得到的Target Arm Length值卻一直不變?

A:在代碼中,Target Arm Length永遠是不變的,但是它下面有RelativeSocket,在藍圖中可以使用GetSocketTransform來獲取,並且使用RTS_Component參數,取Location然後用VectorLength來計算:

FTransform USpringArmComponent::GetSocketTransform(FName InSocketName, ERelativeTransformSpace TransformSpace) const
{
    FTransform RelativeTransform(RelativeSocketRotation, RelativeSocketLocation);

    switch(TransformSpace)
    {
        case RTS_World:
        {
            return RelativeTransform * ComponentToWorld;
            break;
        }
        case RTS_Actor:
        {
            if( const AActor* Actor = GetOwner() )
            {
                FTransform SocketTransform = RelativeTransform * ComponentToWorld;
                return SocketTransform.GetRelativeTransform(Actor->GetTransform());
            }
            break;
        }
        case RTS_Component:
        {
            return RelativeTransform;
        }
    }
    return RelativeTransform;
}

https://www.youku.com/video/XNjM5ODYyMjMwMA==

還可以用SpringArm與Camera的位置相減來計算,分別GetWorldLocation再Sub和VectorLength:

https://www.youku.com/video/XNjM5ODYyMzg1Ng==

可以發現兩種方式得到的數據似乎有些小區別,這是因為該案例中還有一個相機跟隨鼠標位置移動的功能,它會對Camera進行SetRelativeLocation,偏移其Y和Z值。方式一是從SpringArm中取,與Camera無關,所以不受偏移量影響;方式二用到了Camera的RelativeLocation,因此將偏移量也算了進去。

另外還有一種方式,無法計算距離,而是直接檢測相機是否與世界發生了碰撞,發生碰撞時就會進行縮放。

歡迎有經驗的朋友轉至社區交流:
https://answer.uwa4d.com/question/66417ac15ce8a46b00fc4d2b

封面圖來源於網絡


今天的分享就到這裏。生有涯而知無涯,在漫漫的開發週期中,我們遇到的問題只是冰山一角,UWA社區願伴你同行,一起探索分享。歡迎更多的開發者加入UWA社區。

UWA官網:www.uwa4d.com
UWA社區:community.uwa4d.com
UWA學堂:edu.uwa4d.com
官方技術QQ羣:793972859

user avatar soroqer 頭像 u_15878077 頭像 wxp686 頭像
點贊 3 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.