EasyTeleport
[AI-generated] Vanilla-styled world-map buttons: teleport back to your bed, or click anywhere on the map to teleport there. Hold Ctrl to drag the buttons anywhere; position is saved. Safe landing: no
模組介紹 作者原文
EasyTeleport
大地圖上的傳送按鈕。 打開地圖(M),畫面左上角出現兩個按鈕 ——
外觀默認與遊戲原生控件同化(運行時繼承原版面板底圖),不會顯得像外掛的貼紙。
| 按鈕 | 做什麼 |
| --- | --- |
| 傳送回牀 | 傳送到你記錄過的牀(在牀上睡過覺設下的出生點)。 |
| 任意傳送 | 按一下 → 按鈕變綠進入待選 → 再點地圖上任意位置,就傳送到那裏。
再按一次按鈕可取消。 |
挪位置:按住 Ctrl 用左鍵拖拽按鈕組,可以放到畫面任意位置,鬆手自動保存。
按住 Ctrl 時按鈕文字會變成淡黃色,表示"現在可以拖"。
傳送落地是安全的:陸地自動落到地面上方、點水面會浮在水上游泳、永遠不會摔死。
傳送在任何狀態下都能用 —— 游泳、奔跑、跳躍、在船上、在水裏都行。
AI 生成聲明:本模組由 AI 智能體(WorkBuddy)在用戶的明確需求與逐項驗收下編寫;
需求描述、交互設計與發佈決定均由用戶主導。
用法
傳送回牀
- 先在牀邊上按 E 睡一覺(這一步會在角色檔案裏記下出生點;不睡就點按鈕會提示"還沒有記錄過牀")。
- 按 M 打開大地圖 → 右下角點 「傳送回牀」 → 黑屏淡入淡出 → 人已經在牀邊。
任意傳送(地圖上點哪去哪)
- 按 M 打開大地圖。
- 點 「任意傳送」 —— 按鈕變成綠色並顯示「取消 · 點地圖選點」,同時左上角彈一條提示。
- 在地圖上點任意位置 → 直接傳送過去。
- 點偏了?再點一次地圖就行(待選狀態會保留到你成功傳送或主動取消)。
- 不想傳了?再點一次按鈕取消,或者按 M 關掉地圖(也會自動取消)。
⚠️ 遊戲對傳送有 2 秒冷卻(原版傳送門同款)。剛傳送完立刻再傳會被拒絕,
屏幕上會提示"傳送被遊戲拒絕 —— 通常是因爲剛傳送過"。此時待選狀態不會丟,等一兩秒直接再點地圖即可。
落點是怎麼保證安全的
這一塊沒有自己寫地形算法 —— 而是利用了原版 Player.UpdateTeleport 裏本就有的一套落地校正流程,
再餵給它一個"在什麼地形上都成立"的高度值。所有結論都來自對 assembly_valheim.dll 的反彙編。
原版的流程(Player.UpdateTeleport,distantTeleport = true 時)
① player.position = 我們給的 (x, Y, z) ← 這裏 Y 是我們唯一能控制的
② 等 ZNetScene.IsAreaReady(target) ← 遠處傳送就是在這裏等區域加載
③ if (ZoneSystem.FindFloor(target, out floor)) ← Raycast(target + up×1, down, 1000 m)
return; ← ★ 命中就結束,玩家高度 = 我們給的 Y(不再校正)
④ else(沒命中)
player.y = ZoneSystem.GetSolidHeight(target) + 0.5
← Raycast(target + up×1000, down, 2000 m)
同時,在搬運玩家的那一刻原版會執行 Character.m_maxAirAltitude = transform.position.y;
摔落傷害 = 當前高度 − 歷史最高滯空高度,所以傳送落地時該差值恆爲 0 ⇒ 不會摔傷。
我們取的 Y = ZoneSystem.c_WaterLevel
ZoneSystem.c_WaterLevel 是一個 public const,從 DLL 的 Constant 表裏讀出來是 30.0f(Valheim 海平面)。
取這個值,兩條分支在地形上的表現是:
| 地形 | ③ FindFloor | 最終落點 |
| --- | --- | --- |
| 陸地(地面高於水面) | 射線從水面上方往下打夠不到地面 → 未命中 | 走 ④ → 精確落到地面 +0.5 米 |
| 海洋 / 湖泊(水底低於水面) | 射線命中水底 → 命中 | 高度保持水面 → 玩家浮在水面游泳 |
離線場景矩陣驗證(scripts/verify_landing.py,12 個場景)全部通過:
高山(Deep North 峯) 地面 420.0 → GetSolidHeight 校正 → 落點 420.5 OK 落在地面 +0.5 米
山地 地面 180.0 → GetSolidHeight 校正 → 落點 180.5 OK 落在地面 +0.5 米
平原 / 草原 地面 50.0 → GetSolidHeight 校正 → 落點 50.5 OK 落在地面 +0.5 米
略高於水面的海岸 地面 32.5 → GetSolidHeight 校正 → 落點 33.0 OK 落在地面 +0.5 米
剛好在水面 地面 30.0 → FindFloor 命中 → 落點 30.0 OK
淺灘(水下 5 米) 地面 25.0 → FindFloor 命中 → 落點 30.0 OK 落在水面(可游泳)
沼澤低地(水下 12 米) 地面 18.0 → FindFloor 命中 → 落點 30.0 OK 落在水面(可游泳)
淺湖底(水下 25 米) 地面 5.0 → FindFloor 命中 → 落點 30.0 OK 落在水面(可游泳)
深海海牀 地面 -55.0 → FindFloor 命中 → 落點 30.0 OK 落在水面(可游泳)
最深海牀 地面 -95.0 → FindFloor 命中 → 落點 30.0 OK 落在水面(可游泳)
世界最高峯(極端假設) 地面 900.0 → GetSolidHeight 校正 → 落點 900.5 OK 落在地面 +0.5 米
超出校正範圍的極端高 地面1100.0 → 兩條都失敗 → 落點1030.0 FAIL(Valheim 無此地形)
⚠️ 這也解釋了爲什麼 UseDistantTeleport 必須保持 true:
只有遠距離傳送模式纔會在 FindFloor 未命中時執行第 ④ 步校正。
把它關掉,跨半張地圖傳送就可能"人到了但地面還沒來",或者停在未校正的高度上。
位置與外觀
位置:按住 Ctrl 拖拽就行
按住 Ctrl + 左鍵拖動按鈕組 → 放到畫面任意位置 → 鬆手自動保存到
easyteleport.client.only.cfg 的 LeftAnchor / TopAnchor,不必手動改配置。
- 按住 Ctrl 時按鈕文字變淡黃,表示"現在可以拖"。
- 拖拽跟手:從按鈕組的哪一點起拖,那一點就一直跟着鼠標(不會跳到鼠標中心)。
- 拖到屏幕外面會被夾在邊界內,不會把按鈕甩丟。
- 拖拽期間、以及鬆手後 0.25 秒內按鈕功能被抑制 —— 不會"想挪位置卻把自己傳走了"。
- 不想要這個功能就把 AllowDrag 設爲 false。
座標用比例錨點(畫面寬的 LeftAnchor、高的 TopAnchor),默認 0.084 / 0.392
= 1920×1080 下大約 (162, 423)。用比例而不是像素邊距,是爲了換分辨率時位置不會跑偏。
外觀:繼承遊戲原生 UI
UseGameStyle = true(默認)時,模組會在運行時從大地圖已有的控件裏翻一個"面板/按鈕底圖" sprite 過來復用:
| 優先級 | 來源 |
| --- | --- |
| ① | 名字裏帶 button / panel / background / _bg / frame 的 Image |
| ② | 有九宮格邊界(Sprite.border!= 0)的 Image —— 這種纔是可拉伸的面板底圖 |
| ③ | 任意帶圖的 Image |
| ④ | 都沒有 → 退回純色半透明深灰 |
拿到之後就按九宮格(Image.Type.Sliced)鋪滿按鈕,所以圓角、漸變、描邊都跟原版控件一致。
文字用米白色 + 1 像素黑描邊,和原版 UI 的文字處理方式一致。
⚠️ 開着 Verbose 可以在日誌裏看到底圖具體取自哪個控件(按鈕底圖取自 … sprite=… 九宮格=True)。
萬一某次更新後取到的圖不合適(比如拿到一個小圖標鋪開變形),把 UseGameStyle 改成 false
即可退回乾淨的純色底 —— 這時按鈕的長相由 ArmedColor 等配置控制。
爲什麼中文字體不能跟着遊戲走
遊戲內置字體 AveriaSansLibre 不含 CJK 字形,用它畫中文會是一排方塊。
所以字體默認走系統字體(微軟雅黑),並從系統字體清單裏按名字找。
觀感上和原版 UI 已經很接近(都是無襯線體),但確實不是同一個字體 —— 這是中文環境下的必然取捨。
配置
BepInEx/config/easyteleport.client.only.cfg
| 分區 | 鍵 | 默認 | 說明 |
| --- | --- | --- | --- |
| 1 - General | Enabled | true | 總開關 |
| 2 - Buttons | BackToBedText | 傳送回牀 | 按鈕文字 |
| | AnywhereText | 任意傳送 | 按鈕平時顯示的文字 |
| | ArmedText | 取消 · 點地圖選點 | 待選狀態顯示的文字 |
| | ArmedColor | 深綠 | 待選狀態下按鈕的綠色調(UseGameStyle = fal
安裝與使用 安裝:BepInEx 外掛
- 本站下載的壓縮包就是模組本體,通常是 BepInEx 外掛(解壓後得到 .dll 或外掛資料夾)。
- 建議流程:用社群模組管理器(如 r2modman)選中本遊戲後匯入該模組,管理器會自動裝好 BepInEx 前置並處理依賴。
- 手動流程:先在遊戲目錄裝好 BepInEx 載入器,再把解壓出的 .dll 或外掛資料夾放進 BepInEx/plugins/。
- 啟動遊戲,BepInEx 控制台會列印載入日誌;確認這個模組出現在日誌裡即為安裝成功。
帶「前置依賴」的模組需要一併安裝,否則不會載入。功能開關通常在遊戲內或外掛自帶的設定檔裡調整。 多人連線時,主機與所有用戶端需要安裝一致的模組。
下面這些內容需要先安裝,否則該模組不會生效: