實(shí)戰(zhàn):基于 Terraria 繪制系統(tǒng)的顯示人偶與玩家預(yù)覽對齊方案)
游戲開發(fā)桌面應(yīng)用【免費(fèi)下載鏈接】Terraria-Map-EditorTEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also lets you change world settings (time, bosses downed etc), edit chests and change sign, make epic dungeons, castles, cities, and add rewards for your adventurers!項目地址https://gitcode.com/gh_mirrors/te/Terraria-Map-Editor點(diǎn)擊查看免費(fèi)下載本篇技術(shù)指南圍繞 TEditTerraria 地圖編輯器中配飾Accessory與翅膀Wings在顯示人偶Display Doll / Mannequin與玩家編輯預(yù)覽中的渲染修復(fù)展開以倉庫文檔 accessory-wings-rendering-fix.md 為核心骨架并結(jié)合 WorldRenderXna.xaml.cs、PlayerPreviewRenderer.cs、PlayerEditorViewModel.cs 等源碼實(shí)現(xiàn)進(jìn)行縱深講解。讀完本文你將掌握TEdit 中配飾渲染被禁用的兩處調(diào)用點(diǎn)、Terraria 官方的玩家繪制分層與翅膀幀計數(shù)規(guī)則、面向顯示人偶的五步修復(fù)策略含可復(fù)制的 C# 代碼以及這些修復(fù)在代碼庫中的落地位置與優(yōu)先級。問題背景配飾渲染在 TEdit 中被禁用的兩處TEdit 的顯示人偶Display Doll即泰拉瑞亞 1.4 中的展示人偶兼容舊版 Mannequin/Womannequin和玩家編輯器預(yù)覽都需要渲染人形 盔甲 配飾的完整形象但當(dāng)前實(shí)現(xiàn)中配飾渲染被注釋禁用表現(xiàn)為兩個明確的調(diào)用點(diǎn)世界渲染器WorldRenderXna.xaml.csDrawDollBody()與DrawDollAccessory()方法已有完整實(shí)現(xiàn)但調(diào)用處被注釋掉。源碼中顯示人偶渲染塊的配飾循環(huán)仍處于注釋狀態(tài)// TODO: Accessory rendering disabled — needs frame offset work // for (int accIdx 3; accIdx 7 accIdx te.Items.Count; accIdx) // { // var accItem te.Items[accIdx]; // if (accItem null || accItem.Id 0 || accItem.StackSize 0) continue; // if (!WorldConfiguration.ItemLookupTable.TryGetValue(accItem.Id, out var accProps)) continue; // DrawDollAccessory(x, y, accProps, dollEffect); // }玩家編輯器預(yù)覽PlayerEditorViewModel.csRegeneratePreview()只解析了頭/身/腿三個盔甲槽位并調(diào)用RenderPreview從未解析或傳遞配飾槽位參數(shù)且代碼中同樣留有// TODO: Accessory rendering disabled — needs frame offset work to render correctly標(biāo)記。關(guān)鍵在于輔助方法本身存在、紋理加載管線可用真正的阻塞點(diǎn)有三個姿勢感知的幀偏移Pose-aware frame offsets盔甲疊加層固定使用幀行 0而身體部件按姿勢渲染在對應(yīng)幀偏移處導(dǎo)致錯位配飾紋理尺寸DrawDollAccessory使用GetDollBodyDest()它假設(shè) 40×56 的身體幀但配飾尤其翅膀尺寸不同需要按類型單獨(dú)定位翅膀幀數(shù)不統(tǒng)一幀數(shù)必須按翅膀 ID 查表4、6、7、8、11 或 14 幀不存在統(tǒng)一公式。參考基準(zhǔn)Terraria 實(shí)際的玩家繪制系統(tǒng)修復(fù)的正確性必須對齊 Terraria 官方的繪制邏輯。文檔給出了來自terraria-server-dasm反編譯服務(wù)端源碼的LegacyPlayerRenderer.DrawPlayer_UseNormalLayers繪制順序與Main.cs中的逐幀偏移數(shù)組。從后往前的繪制順序Draw OrderTEdit 渲染人形時以畫家算法back to front疊加圖層與游戲內(nèi)一致Layer 08 — 背包player.backpack Layer 08_1 — 尾巴player.tail Layer 09 — 翅膀在所有可見元素之后 Layer 10 — 背部配飾披風(fēng)等 Layer 11 — 氣球 Layer 12 — 皮膚身體幀 Layer 13 — 護(hù)腿 盔甲腿部 Layer 14 — 鞋子 Layer 17 — 軀干復(fù)合系統(tǒng) Layer 18 — 副手配飾 Layer 19 — 腰部配飾 Layer 20 — 頸部配飾 Layer 21 — 頭部 頭盔 Layer 22 — 面部配飾 Layer 25 — 盾牌 Layer 29 — 主手配飾 Layer 32 — 前部配飾這一順序直接決定了 TEdit 中配飾的 Z 深度取值見 Fix 3。身體幀尺寸與索引標(biāo)準(zhǔn)身體幀為40×56 像素每動畫幀幀索引 bodyFrame.Y / 560–19對應(yīng) 20 個動畫幀顯示人偶使用皮膚變體10男性與11女性——這與 WorldRenderXna.xaml.cs 中skinVariant isWomannequin ? 11 : 10的取值一致。標(biāo)準(zhǔn)身體位置公式游戲內(nèi)大多數(shù)圖層使用如下定位公式Vector2 position new Vector2( (int)(Position.X - screenPosition.X - bodyFrame.Width / 2 player.width / 2), (int)(Position.Y - screenPosition.Y player.height - bodyFrame.Height 4) ) player.bodyPosition; // origin new Vector2(legFrame.Width * 0.5f, legFrame.Height * 0.5f)逐幀附件偏移數(shù)組以下數(shù)組按bodyFrame.Y / 56索引來自Main.cs是翅膀等附件逐幀定位的依據(jù)// 頭飾 Y 偏移部分翅膀類型也使用 OffsetsPlayerHeadgear[20] { (0,2), (0,2), (0,2), (0,2), (0,2), (0,2), (0,2), (0,0), (0,0), (0,0), (0,2), (0,2), (0,2), (0,2), (0,0), (0,0), (0,0), (0,2), (0,2), (0,2) }; // 副手掛點(diǎn) OffsetsPlayerOffhand[20] { (14,20), (14,20), (14,20), (14,18), (14,20), (16, 4), (16,16), (18,14), (18,14), (18,14), (16,16), (16,16), (16,16), (16,16), (14,14), (14,14), (12,14), (14,16), (16,16), (16,16) }; // 主手掛點(diǎn) OffsetsPlayerOnhand[20] { (6,19), (5,10), (12,10), (13,17), (12,19), (5,10), (7,17), (6,16), (6,16), (6,16), (6,17), (7,17), (7,17), (7,17), (8,17), (9,16), (9,12), (8,17), (7,17), (7,17) };翅膀渲染細(xì)節(jié)翅膀繪制參考DataStructures/PlayerDrawLayers.cs的DrawPlayer_09_Wings方法?;鶞?zhǔn)位置Vector2 commonWingPos drawinfo.Position - Main.screenPosition new Vector2(player.width / 2, player.height - player.bodyFrame.Height / 2) new Vector2(0, 7f); // 相對中心下移 7px默認(rèn)翅膀繪制大多數(shù)翅膀 ID// 按翅膀的偏移默認(rèn) num80, num70, num94 幀 Vector2 position Floor(commonWingPos new Vector2(num8 - 9, num7 2) * directions); // 從精靈圖sprite sheet中取源矩形 Rectangle source new Rectangle( 0, texture.Height / frameCount * player.wingFrame, texture.Width, texture.Height / frameCount ); // 原點(diǎn) 單幀中心 Vector2 origin new Vector2(texture.Width / 2, texture.Height / frameCount / 2);其中directions new Vector2(-player.direction, 1)player.direction為 -1朝左或 1朝右。各翅膀 ID 的專屬偏移覆蓋Wing ID名稱X 偏移Y 偏移幀數(shù)備注默認(rèn)大多數(shù)翅膀004—5Butterfly4-44—12Steampunk/Leaf-1-14—22Hoverboard0247AlwaysAnimated尾焰27Mothron304—28LazureBarrier0174AlwaysAnimated34Jims特殊特殊6AlwaysAnimated自定義位置39Leinfor-6-76AlwaysAnimated40Ghostar-4014AlwaysAnimated落地/飛行分裂41Safeman-104—43GroxTheGreat-5-77—44Rainbow007AlwaysAnimated45LongTrailRainbow0206AlwaysAnimated47ChickenBones特殊特殊11使用OffsetsPlayerHeadgear48Chippys特殊特殊8AlwaysAnimated49Heroicis特殊特殊11使用OffsetsPlayerHeadgear50Kazzymodus特殊特殊11自定義中心位置51Lunas特殊特殊8—AlwaysAnimated 翅膀ID 為 22、28、34、39、40、44、45、48。這些翅膀在玩家靜止時也會持續(xù)動畫。靜態(tài)顯示人偶應(yīng)顯示第 0 幀。翅膀幀數(shù)查表幀數(shù)沒有公式必須按 ID 硬編碼查表在DrawPlayer_09_Wings中寫死4 幀 ID 1-4, 6-11, 13-21, 23-28, 29-33, 35-38, 41-42, 46 6 幀 ID 34, 39, 45 7 幀 ID 22, 43, 44 8 幀 ID 48, 51 11 幀ID 47, 49, 50 14 幀ID 40配飾渲染細(xì)節(jié)除翅膀外每種配飾都使用同一身體幀坐標(biāo)系但各自擁有獨(dú)立紋理圖集。TEdit 中配飾槽位元數(shù)據(jù)定義于 ItemProperty.csWingSlot、BackSlot、BalloonSlot、ShoeSlot、WaistSlot、NeckSlot、FaceSlot、ShieldSlot、HandOnSlot、HandOffSlot、FrontSlot均為可空 int紋理緩存接口在 Textures.cs如GetAccWings(num)按Images\\Wings_{0}路徑加載。槽位類型紋理路徑繪制層位置參考翅膀Images/Wings_{id}09身體后專用公式見上文背部Images/Acc_Back_{id}10身體后身體位置 bodyVect 原點(diǎn)氣球Images/Acc_Balloon_{id}11身體后身體位置 bodyVect 原點(diǎn)鞋子Images/Acc_Shoes_{id}14腿部上腿位置 legVect 原點(diǎn)副手Images/Acc_HandsOff_{id}18軀干中身體位置 bodyVect 原點(diǎn)腰部Images/Acc_Waist_{id}19軀干中身體位置 bodyVect 原點(diǎn)頸部Images/Acc_Neck_{id}20軀干中身體位置 bodyVect 原點(diǎn)面部Images/Acc_Face_{id}22頭部上頭位置 headVect 原點(diǎn)盾牌Images/Acc_Shield_{id}25前中部身體位置 bodyVect 原點(diǎn)主手Images/Acc_HandsOn_{id}29前面身體位置 bodyVect 原點(diǎn)前部Images/Acc_Front_{id}32最前身體位置 bodyVect 原點(diǎn)除翅膀外大多數(shù)配飾使用標(biāo)準(zhǔn)身體幀矩形第一幀 (0, 0, 40, 56)源矩形 Y 為bodyFrame.Y與身體同動畫幀原點(diǎn)bodyVect (width * 0.5, height * 0.5)。修復(fù)策略五步落地Fix 1世界渲染器 —— 啟用DrawDollBody并引入姿勢感知的盔甲幀問題盔甲疊加層使用source.Y 0站立幀而DrawDollBody按姿勢渲染在姿勢對應(yīng)的幀 Y 偏移上二者錯位。當(dāng)前盔甲繪制塊的源矩形固定為var headSrc new Rectangle(2, 0, 36, 36); // 永遠(yuǎn)幀 0 var bodySrc new Rectangle(2, 0, 36, 54); // 永遠(yuǎn)幀 0 var legsSrc new Rectangle(2, 42, 36, 12); // 永遠(yuǎn)幀 0解決把姿勢的bodyFrameY、legFrameY傳入盔甲渲染代碼var (bodyFrameY, legFrameY, yPixelOffset) GetDollPoseFrames(te.Pose); // 頭 —— 使用 bodyFrameY頭部跟隨身體動畫 var headSrc new Rectangle(0, bodyFrameY, DollFrameWidth, DollFrameHeight); // 身體 —— 使用 bodyFrameY var bodySrc new Rectangle(0, bodyFrameY, DollFrameWidth, DollFrameHeight); // 腿 —— 使用 legFrameY腿有獨(dú)立動畫 var legsSrc new Rectangle(0, legFrameY, DollFrameWidth, DollFrameHeight);隨后目標(biāo)矩形需應(yīng)用yPixelOffset通過GetDollBodyDest。步驟取消DrawDollBody()調(diào)用的注釋在盔甲后繪制皮膚重構(gòu)盔甲疊加代碼用GetDollPoseFrames()決定源矩形 Y盔甲目標(biāo)矩形改用GetDollBodyDest()替換手寫矩形運(yùn)算調(diào)整深度值保證皮膚在最底層、盔甲居中、配飾最上層。當(dāng)前源碼中的姿勢映射已存在于 GetDollPoseFramesprivate static (int bodyFrameY, int legFrameY, int yPixelOffset) GetDollPoseFrames(byte pose) { return (DisplayDollPoseID)pose switch { DisplayDollPoseID.Standing (0, 0, 0), DisplayDollPoseID.Sitting (0, 0, 10), DisplayDollPoseID.Jumping (5 * DollFrameHeight, 5 * DollFrameHeight, 0), DisplayDollPoseID.Walking (9 * DollFrameHeight, 9 * DollFrameHeight, 0), _ (0, 0, 0), // Use1-5 回退為站立 }; }其中DollFrameWidth 40、DollFrameHeight 56與官方身體幀尺寸一致。目標(biāo)矩形計算 GetDollBodyDest 會把 40px 身體幀居中到 32px2 格足跡內(nèi)X 左移 4px、Y 上移 12 游戲像素并對齊到瓦片原點(diǎn)再疊加姿勢 Y 偏移。Fix 2世界渲染器 —— 啟用配飾渲染按類型分流翅膀走專用公式問題DrawDollAccessory把所有配飾當(dāng)作 40×56 身體幀疊加層而翅膀尺寸不同、定位公式不同。解決按類型分流。非翅膀配飾走身體幀定位翅膀走 Terraria 翅膀公式并換算到瓦片坐標(biāo)private void DrawDollAccessory(int tileX, int tileY, ItemProperty props, byte pose, SpriteEffects effect, int drawOrder) { var (bodyFrameY, legFrameY, yPixelOffset) GetDollPoseFrames(pose); if (props.WingSlot.HasValue) { DrawDollWings(tileX, tileY, props.WingSlot.Value, effect, drawOrder); return; } // 其余配飾在當(dāng)前姿勢下使用身體幀源矩形 Texture2D tex ResolveAccessoryTexture(props); if (tex null) return; int frameY bodyFrameY; // 鞋子使用腿部幀 if (props.ShoeSlot.HasValue) frameY legFrameY; var source new Rectangle(0, frameY, Math.Min(tex.Width, DollFrameWidth), Math.Min(tex.Height - frameY, DollFrameHeight)); var dest GetDollBodyDest(tileX, tileY, source.Width, source.Height, yPixelOffset); float depth ComputeAccessoryDepth(props, drawOrder); _spriteBatch.Draw(tex, dest, source, Color.White, 0f, default, effect, depth); }翅膀的專用繪制private void DrawDollWings(int tileX, int tileY, int wingId, SpriteEffects effect, int drawOrder) { var tex _textureDictionary.GetAccWings(wingId); if (tex null || tex _textureDictionary.DefaultTexture) return; int frameCount GetWingFrameCount(wingId); var (xOff, yOff) GetWingOffset(wingId); // 靜態(tài)顯示始終幀 0 int frameHeight tex.Height / frameCount; var source new Rectangle(0, 0, tex.Width, frameHeight); // 翅膀位置以人偶中心為基準(zhǔn)疊加 Terraria 偏移并按瓦片坐標(biāo)縮放 float wingX tileX 1f; // 2 格寬人偶的中心 float wingY tileY 1.5f; // 豎直方向近似中心 // 應(yīng)用 Terraria 像素偏移除以 16 換算為瓦片坐標(biāo) wingX (xOff - 9f) / 16f; wingY (yOff 2f 7f) / 16f; // 7 為 Terraria 翅膀基礎(chǔ)下移量 var dest new Rectangle( 1 (int)((_scrollPosition.X wingX - tex.Width / 32f) * _zoom), 1 (int)((_scrollPosition.Y wingY - frameHeight / 32f) * _zoom), (int)(_zoom * tex.Width / 16f), (int)(_zoom * frameHeight / 16f)); float depth LayerDollBody - drawOrder * 0.00001f; _spriteBatch.Draw(tex, dest, source, Color.White, 0f, default, effect, depth); }需要新增的數(shù)據(jù)表以靜態(tài)字典/數(shù)組形式落地private static int GetWingFrameCount(int wingId) wingId switch { 22 or 43 or 44 7, 34 or 39 or 45 6, 48 or 51 8, 47 or 49 or 50 11, 40 14, _ 4 }; private static (int x, int y) GetWingOffset(int wingId) wingId switch { 5 (4, -4), 12 (-1, -1), 22 (0, 24), 27 (3, 0), 28 (0, 17), 39 (-6, -7), 40 (-4, 0), 41 (-1, 0), 43 (-5, -7), 45 (0, 20), _ (0, 0) };Fix 3世界渲染器 —— 配飾繪制順序Z 深度配飾必須相對身體與盔甲處于正確的 Z 序。將 Terraria 圖層號映射為深度值TEdit 使用 XNASpriteBatch.Draw的 depth 參數(shù)值越大越靠后// 翅膀?qū)?09—— 身體后 private const float LayerDollWings LayerDollBody - 0.001f; // 背部配飾層 10—— 身體后、翅膀前 private const float LayerDollBackAcc LayerDollBody - 0.0009f; // 氣球?qū)?11—— 身體后 private const float LayerDollBalloon LayerDollBody - 0.0008f; // 身體/盔甲層使用 LayerDollBody // 鞋子層 14—— 腿部上使用 LayerDollBody 小偏移 // ……其余各層依此類推或直接從 Terraria 圖層號計算float depth LayerDollBody (layerNumber - 12) * 0.0001f;當(dāng)前源碼中LayerDollBody 1 - 0.048fWorldRenderXna.xaml.cs身體部件通過LayerDollBody - drawOrder * 0.00001f實(shí)現(xiàn)部件間的相對排序而配飾當(dāng)前誤用了LayerTileTrack1 - 0.05f這正是需要修正的地方。Fix 4玩家編輯器預(yù)覽 —— 接通配飾槽位問題PlayerEditorViewModel.RegeneratePreview()解析頭/身/腿槽位后從未解析或傳遞配飾槽位。解決在現(xiàn)有盔甲槽位解析約 L590-L630 區(qū)域之后追加配飾槽位解析int? wingSlot null, backSlot null, balloonSlot null; int? shoeSlot null, waistSlot null, neckSlot null; int? faceSlot null, shieldSlot null; int? handOnSlot null, handOffSlot null, frontSlot null; // 解析可見配飾槽位 3-9 為生效13-19 為時裝時裝優(yōu)先于生效對齊 Terraria UpdateVisibleAccessories for (int i 0; i 7; i) { // 先查時裝槽位 13-19 → AccessorySlots 索引 7i var vanitySlot GetAccessorySlotAt(i 7); var activeSlot GetAccessorySlotAt(i); var itemId vanitySlot?.Item?.Id 0 ? vanitySlot.Item.Id : activeSlot?.Item?.Id 0 ? activeSlot.Item.Id : 0; if (itemId 0) continue; if (!WorldConfiguration.ItemLookupTable.TryGetValue(itemId, out var props)) continue; // 檢查隱藏標(biāo)記 bool hidden Player.HideVisibleAccessory.Length i Player.HideVisibleAccessory[i]; if (hidden) continue; if (props.WingSlot.HasValue) wingSlot ?? props.WingSlot; if (props.BackSlot.HasValue) backSlot ?? props.BackSlot; if (props.BalloonSlot.HasValue) balloonSlot ?? props.BalloonSlot; if (props.ShoeSlot.HasValue) shoeSlot ?? props.ShoeSlot; if (props.WaistSlot.HasValue) waistSlot ?? props.WaistSlot; if (props.NeckSlot.HasValue) neckSlot ?? props.NeckSlot; if (props.FaceSlot.HasValue) faceSlot ?? props.FaceSlot; if (props.ShieldSlot.HasValue) shieldSlot ?? props.ShieldSlot; if (props.HandOnSlot.HasValue) handOnSlot ?? props.HandOnSlot; if (props.HandOffSlot.HasValue) handOffSlot ?? props.HandOffSlot; if (props.FrontSlot.HasValue) frontSlot ?? props.FrontSlot; }隨后把全部槽位傳給RenderPreviewPlayerPreview PlayerPreviewRenderer.RenderPreview(Player, textures, 4, headSlot, bodySlot, legsSlot, dyeHead, dyeBody, dyeLegs, showHairWithHelmet, wingSlot, backSlot, balloonSlot, shoeSlot, waistSlot, neckSlot, faceSlot, shieldSlot, handOnSlot, handOffSlot, frontSlot);從源碼看RenderPreview的方法簽名PlayerPreviewRenderer.cs已經(jīng)完整支持全部 11 個配飾槽位且渲染體內(nèi)部L213-L221、L240-L241、L273-L276、L290-L291、L298-L299、L305-L308已在對應(yīng)層級調(diào)用BlendArmorPart混合各配飾紋理——缺的只是 ViewModel 側(cè)的上游接線。因此 Fix 4 是最低風(fēng)險、最高可見度的改動。Fix 5PlayerPreviewRenderer—— 翅膀幀選擇PlayerPreviewRenderer.BlendArmorPart目前讀取整張紋理的左上角 40×56 區(qū)域幀 0。而翅膀是多幀縱向堆疊、幀數(shù)各異的精靈圖必須知道幀數(shù)才能取到正確源矩形if (wingSlot.HasValue) { var wingTex textures.GetAccWings(wingSlot.Value); int frameCount GetWingFrameCount(wingSlot.Value); int frameHeight wingTex.Height / frameCount; // 靜態(tài)預(yù)覽使用幀 0 BlendArmorPart(composite, textures, wingTex, sourceRect: new Rectangle(0, 0, wingTex.Width, frameHeight)); }這要求BlendArmorPart增加可選的sourceRect參數(shù)當(dāng)前它直接按 40×56 讀全紋理。GetWingFrameCount數(shù)據(jù)表與 Fix 2 中所述一致可提取為共享工具。實(shí)施優(yōu)先級玩家預(yù)覽配飾Fix 4 5—— 風(fēng)險最低、收益最直觀。RenderPreview已支持全部槽位只需接線 ViewModel 并處理翅膀幀數(shù)。世界人偶身體 姿勢感知盔甲Fix 1—— 啟用正確姿勢渲染方法已存在只需更新源矩形運(yùn)算。世界人偶非翅膀配飾Fix 2 部分—— 在現(xiàn)有盔甲渲染基礎(chǔ)上用身體幀源矩形擴(kuò)展即可。世界人偶翅膀Fix 2 3—— 需要翅膀偏移/幀數(shù)數(shù)據(jù)表與新的位置公式工作量最大。關(guān)鍵源文件一覽TEdit地圖編輯器側(cè)文件角色src/TEdit/View/WorldRenderXna.xaml.cs世界渲染器 ——DrawDollBody、DrawDollAccessory、DrawDollBodyPart、GetDollPoseFrames、GetDollBodyDest、LayerDollBodysrc/TEdit/Render/PlayerPreviewRenderer.csWPF 位圖預(yù)覽 ——RenderPreview、BlendArmorPart、BlendBodyPartsrc/TEdit/Render/Textures.cs紋理緩存 ——GetAccWings、GetAccBack等配飾紋理入口src/TEdit/ViewModel/PlayerEditorViewModel.cs玩家編輯器 ——RegeneratePreview()含配飾禁用的 TODO 標(biāo)記TEdit.Terraria數(shù)據(jù)模型側(cè)文件角色src/TEdit.Terraria/Objects/ItemProperty.cs物品元數(shù)據(jù) ——WingSlot?、BackSlot?、BalloonSlot?、ShoeSlot?、WaistSlot?、NeckSlot?、FaceSlot?、ShieldSlot?、HandOnSlot?、HandOffSlot?、FrontSlot?src/TEdit.Terraria/TileEntity.csDisplayDoll 數(shù)據(jù)模型 ——Items[9]、Dyes[9]、Misc[1]、Pose兼容 Mannequin/Womannequin Legacy 及 HatRack 等實(shí)體總結(jié)與驗(yàn)證路徑配飾與翅膀渲染修復(fù)的本質(zhì)是把已存在但未接線的能力DrawDollBody、DrawDollAccessory、RenderPreview的完整簽名、紋理緩存GetAccWings系列與缺失的元數(shù)據(jù)姿勢幀偏移、翅膀幀數(shù)表、翅膀偏移表、Z 深度映射補(bǔ)齊并以 Terraria 官方的DrawPlayer_UseNormalLayers繪制順序?yàn)槲ㄒ徽_性基準(zhǔn)。驗(yàn)證時可以沿著以下調(diào)用鏈逐層核對玩家編輯器PlayerEditorViewModel.RegeneratePreview()→PlayerPreviewRenderer.RenderPreview()→BlendArmorPart/BlendBodyPart對應(yīng)文檔 PlayerEditorViewModel.cs 與 PlayerPreviewRenderer.cs世界渲染器DisplayDoll分支 →DrawDollBody→DrawDollBodyPart/DrawDollHair→啟用后DrawDollAccessory/DrawDollWings對應(yīng) WorldRenderXna.xaml.cs 與 L3666-L3820。修復(fù)完成的標(biāo)準(zhǔn)顯示人偶與玩家預(yù)覽中的翅膀幀數(shù)、偏移、深度順序與游戲內(nèi)表現(xiàn)一致且靜止姿態(tài)下 AlwaysAnimated 翅膀顯示幀 0。贊分享游戲開發(fā)桌面應(yīng)用【免費(fèi)下載鏈接】Terraria-Map-EditorTEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also lets you change world settings (time, bosses downed etc), edit chests and change sign, make epic dungeons, castles, cities, and add rewards for your adventurers!項目地址https://gitcode.com/gh_mirrors/te/Terraria-Map-Editor點(diǎn)擊查看免費(fèi)下載相關(guān)推薦TEdit 玩家角色預(yù)覽渲染器深度解析基于 Terraria 1.4 復(fù)合幀系統(tǒng)的貼圖合成實(shí)現(xiàn)TEdit 玩家角色預(yù)覽渲染器深度解析基于 Terraria 1.4 復(fù)合幀系統(tǒng)的貼圖合成實(shí)現(xiàn) 導(dǎo)讀 本文基于 Terraria 1.4.5.4 的角色渲染游戲開發(fā)桌面應(yīng)用TEdit 剪貼板預(yù)覽渲染架構(gòu)基于 RenderTarget2D 的預(yù)渲染位圖方案TEdit 剪貼板預(yù)覽渲染架構(gòu)基于 RenderTarget2D 的預(yù)渲染位圖方案 本文是 TEdit 地圖編輯器剪貼板預(yù)覽渲染系列設(shè)計文檔之一講解如何將剪游戲開發(fā)桌面應(yīng)用SnapDrawing 跨平臺繪制與 UI 系統(tǒng)Valdi 底層基于 Skia 的渲染架構(gòu)與 CLI 實(shí)戰(zhàn)SnapDrawing 跨平臺繪制與 UI 系統(tǒng)Valdi 底層基于 Skia 的渲染架構(gòu)與 CLI 實(shí)戰(zhàn) 導(dǎo)讀 SnapDrawing 是 Valdi 開源跨平臺UI組件前端移動開發(fā)上一篇Onekey提升游戲資源管理效率10倍的Steam清單下載工具下一篇OnekeySteam清單高效管理的智能工具創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考