เอนจินคู่มือคำถามที่พบบ่อยPatreonDiscordดาวน์โหลด
เข้าสู่ระบบ
RuneTranslate · แปลเกมญี่ปุ่นครบวงจร
เอนจินคู่มือเปรียบเทียบข้อความในภาพตัวแก้ไขเซฟโหมดโกงคำถามที่พบบ่อยดาวน์โหลดPatreonDiscordYouTubeความเป็นส่วนตัวข้อกำหนดติดต่อ
โพสต์ทั้งหมด
unity · textmeshpro · fonts · troubleshooting

ทำไมข้อความที่แปลแล้วขึ้นเป็นสี่เหลี่ยม

18 ส.ค. 2569·9 นาทีในการอ่าน

คุณแปลเกมเสร็จ ส่งออกผ่านฉลุย แล้วกล่องบทสนทนาเต็มไปด้วย □□□ นั่นแทบไม่เคยเป็นปัญหาของการแปล — มันคือปัญหาฟอนต์ และวิธีแก้ต่างจากอีกสองอาการที่คนมักสับสน นี่คือวิธีแยกกลิฟที่หายไป ออกจากอักขระที่ถูกตัดทิ้ง และออกจาก mojibake พร้อมวิธีแก้แต่ละแบบใน Unity, TextMeshPro, Ren'Py และเครื่องมือตอนรันไทม์

การส่งออกเสร็จเรียบร้อย เกมเปิดขึ้นมา แล้วบทสนทนาทุกบรรทัดกลายเป็นแถวของสี่เหลี่ยมว่างเปล่าที่เหมือนกันหมด ไม่มีอะไรผิดเกี่ยวกับคำแปลเลย ข้อความในไฟล์คือสิ่งที่ผู้ให้บริการคืนมาทุกประการ และถ้าคุณเปิดไฟล์นั้นในโปรแกรมแก้ไขข้อความ มันอ่านได้ถูกต้อง สิ่งที่ล้มเหลวคือขั้นสุดท้ายของสายงาน: ฟอนต์ที่เกมส่งให้ตัวเรนเดอร์ไม่มีรูปวาดสำหรับอักขระเหล่านั้น

กล่องเต้าหู้คืออะไรกันแน่

ฟอนต์คือตารางค้นหาจากโค้ดพอยต์ Unicode ไปยังรูปร่าง เมื่อตัวเรนเดอร์ถูกสั่งให้วาดโค้ดพอยต์ที่ฟอนต์ไม่มี มันจะแทนด้วย กลิฟที่หายไป ของฟอนต์นั้น — มักเป็นสี่เหลี่ยมว่างหรือสี่เหลี่ยมกากบาท ชื่อทางการคือ .notdef และที่อื่น ๆ เรียกกันว่า กล่องเต้าหู้ (tofu box) หนึ่งกล่องเท่ากับหนึ่งอักขระที่ฟอนต์วาดไม่ได้ กลไกมีเท่านั้นทั้งหมด

ผลตามมาสองข้อ และทั้งสองข้อมีประโยชน์ในการวินิจฉัย ข้อแรก จำนวนกล่องตรงกับจำนวนอักขระ: อักขระไทยห้าตัวให้กล่องห้ากล่อง ไม่ใช่ข้อความเพี้ยนที่สั้นลง ข้อสอง สตริงในหน่วยความจำยังสมบูรณ์ — เกมยังวัดขนาด เปรียบเทียบ บันทึก และโหลดกลับมาได้ หายไปแค่พิกเซลเท่านั้น นี่คือเหตุผลที่เมนูที่แปลแล้วอาจอ่านไม่ออกเลยแต่ยังกดใช้งานได้ถูกต้อง

สามอาการ สามปัญหาที่ต่างกัน

ความสับสนส่วนใหญ่รอบ ๆ "คำแปลของฉันพัง" คือคนเอาวิธีแก้ของอาการหนึ่งไปใช้กับอีกอาการหนึ่ง ดูรูปทรงของความเสียหายก่อนจะแก้อะไร

  • กล่อง □□□ — อักขระถูกต้อง แต่ฟอนต์วาดมันไม่ได้ ให้แก้ที่ฟอนต์
  • ???? — อักขระหายไปแล้ว มีบางอย่างเข้ารหัสสตริงใหม่ลงชุดอักขระที่แคบกว่า แล้วแทนทุกตัวที่แทนไม่ได้ ไม่มีฟอนต์ไหนเรียกมันกลับมาได้ ให้แก้ที่การเข้ารหัส หรือเลือกภาษาปลายทางที่รูปแบบไฟล์รองรับได้
  • อักษรละตินเพี้ยน อย่าง テキスト หรือ テキスト ที่แสดงเป็น テキスト — mojibake ไบต์ถูกต้อง แต่ตัวถอดรหัสผิด: ข้อความที่เขียนด้วยการเข้ารหัสหนึ่งกำลังถูกอ่านด้วยอีกการเข้ารหัสหนึ่ง ให้แก้ว่ากำลังอ่านด้วยการเข้ารหัสใด

ตัวแยกเร็ว ๆ: ทั้งกล่องและ mojibake ต่างทิ้งจำนวนไบต์ไว้ใกล้เคียงสัดส่วนกับต้นฉบับ แต่ mojibake สร้างอักขระขยะที่ มองเห็นได้และหลากหลาย ในขณะที่กล่องเต้าหู้ให้สี่เหลี่ยมที่ เหมือนกันและสม่ำเสมอ สม่ำเสมอแปลว่า "ฟอนต์" หลากหลายแปลว่า "การเข้ารหัส"

กล่อง: กลิฟที่หายไป

เกมส่งมาพร้อมฟอนต์ที่ครอบคลุมเท่าที่มันต้องใช้ ไม่มีอะไรในสายงานพัง — คุณขอโค้ดพอยต์ที่ศิลปินไม่เคยใส่มา วิธีแก้คือให้ฟอนต์ที่มีกลิฟนั้นกับตัวเรนเดอร์เสมอ ไม่ว่าจะด้วยการแทนที่ฟอนต์ หรือด้วยการเพิ่มฟอนต์สำรองที่ตัวเรนเดอร์จะไปดูเมื่อฟอนต์หลักหากลิฟไม่เจอ

เครื่องหมายคำถาม: อักขระถูกตัดทิ้ง

เมื่อสตริงต้องถูกเขียนกลับลงในรูปแบบที่เก็บข้อความด้วยการเข้ารหัสแบบไบต์เดียวหรือสองไบต์รุ่นเก่า อักขระทุกตัวที่อยู่นอกการเข้ารหัสนั้นต้องกลายเป็นอะไรสักอย่าง ตามธรรมเนียมสิ่งนั้นคือ ? Shift-JIS และ cp932 เก็บภาษาญี่ปุ่น ASCII และอื่น ๆ ได้น้อยมาก ส่วนฟิลด์ ASCII แบบเข้มงวดเก็บกรีก ซีริลลิก ไทย หรือ CJK ไม่ได้เลย นี่เป็นคุณสมบัติของรูปแบบไฟล์ ไม่ใช่ของฟอนต์ และมันเกิดขึ้นตอนส่งออก — พอเกมอ่านไฟล์ ข้อมูลก็หายไปแล้ว

RuneTranslate มีเอนจินหนึ่งที่ข้อจำกัดนี้เกิดขึ้นจริง และเราระบุไว้ตรง ๆ แทนที่จะซ่อนมัน: YU-RIS เข้ารหัสสตริงกลับเป็น cp932 ซึ่งเป็นมิตรกับผลลัพธ์ภาษาอังกฤษและภาษาละตินอื่น ๆ แต่ส่งภาษาไทยออกมาเป็น ? ปลายทางที่ไม่ใช่ cp932 บนเอนจินนั้นต้องใช้ font hack ซึ่งยังไม่ได้ทำ

อักษรละตินเพี้ยน: mojibake

ข้อความญี่ปุ่นที่เขียนเป็น Shift-JIS แล้วถูกอ่านเป็น UTF-8 (หรือกลับกัน) ให้อักษรละตินที่มีเครื่องหมายกำกับและอักขระวาดกรอบยาวเป็นพืด อาการนี้โผล่มาเมื่อเครื่องมือเขียนไฟล์ด้วยการเข้ารหัสผิด หรือเมื่อตัวโหลดของเกมเองสมมติการเข้ารหัสที่การส่งออกของคุณไม่ได้ใช้ วิธีแก้คือเขียนไฟล์ด้วยการเข้ารหัสที่เอนจินคาดหวัง — ไม่ใช่การเปลี่ยนฟอนต์ ซึ่งไม่ทำให้อะไรเปลี่ยนเลย

ทำไม CJK และภาษาไทยจึงโดนหนักที่สุด

ภาษาละตินต้องการกลิฟราวหนึ่งร้อยตัว ภาษาญี่ปุ่นต้องการหลายพัน ภาษาจีนมากกว่านั้น ไฟล์ฟอนต์มีขนาดใหญ่ และเกมส่งฟอนต์ที่เล็กที่สุดเท่าที่ครอบคลุมสคริปต์ของตัวเองมา ความครอบคลุมที่คุณได้รับสืบทอดมาจึงขึ้นอยู่กับว่าเกมถูกสร้างมาเพื่อภาษาใดล้วน ๆ

  • เกมที่สร้างมาเพื่อ ภาษาญี่ปุ่น มักมีคานะ คันจิที่ใช้บ่อย และ ASCII แปลเป็นรัสเซีย กรีก ไทย หรือเกาหลี แล้วอักขระที่ไม่ใช่ ASCII ทุกตัวจะหลุดออกไปหมด
  • เกมที่สร้างมาเพื่อ ภาษาอังกฤษ มักมีแค่ละติน — ญี่ปุ่น จีน เกาหลี ไทย กรีก และซีริลลิกจึงพังพร้อมกันทั้งหมด
  • ภาษาไทย เป็นกรณีที่แย่ที่สุดในทางปฏิบัติ: มันอยู่นอกฟอนต์เกมทั่วไปทุกตัว และยังต้องการสระและวรรณยุกต์ที่วางประกอบอยู่เหนือและใต้อักษรฐาน ฟอนต์ที่มีโค้ดพอยต์ครบในทางเทคนิคจึงยังเรนเดอร์ออกมาไม่ดีได้
  • ภาษาละตินไม่ได้ปลอดภัยโดยอัตโนมัติ โปแลนด์ เช็ก ฮังการี ตุรกี เวียดนาม และโรมาเนียใช้อักขระ Latin-Extended ที่ฟอนต์ซึ่งสร้างมาเพื่ออังกฤษหรือญี่ปุ่นมักไม่มี RuneTranslate จึงรวมฟอนต์ที่กว้างกว่ามาให้สำหรับปลายทางเหล่านั้นบน Ren'Py เพราะ "ละตินไม่มีปัญหา" กลายเป็นเรื่องไม่จริง

เจาะจงที่ Unity และ TextMeshPro

Unity มีระบบข้อความสองระบบ และมันล้มเหลวคนละแบบ uGUI Text รุ่นเก่าใช้อ็อบเจกต์ Font ส่วน TextMeshPro — ซึ่งเกมสมัยใหม่ส่วนใหญ่ใช้ — ไม่ได้ใช้ไฟล์ฟอนต์ตอนรันไทม์เลย มันใช้ TMP font asset: แอตลาสเท็กซ์เจอร์ของภาพกลิฟที่เรนเดอร์ไว้ล่วงหน้า บวกตารางที่แมปโค้ดพอยต์ไปยังตำแหน่งในแอตลาสนั้น

นั่นคือเหตุผลที่ TMP font asset มี ชุดอักขระตายตัว ตอนที่นักพัฒนาสร้างมันขึ้นมา เขาเลือกช่วงอักขระไว้ — มักเป็นแค่ภาษาที่เขากำลังจะวางขาย — แล้ว TMP อบเฉพาะกลิฟเหล่านั้นลงแอตลาส font asset แบบ static ไม่มีทางเรนเดอร์อะไรที่อยู่นอกชุดนั้นได้เลย ไม่ว่าคุณจะป้อนอะไรให้มัน ส่วน font asset แบบ dynamic เก็บการอ้างอิงไปยังไฟล์ฟอนต์ต้นทางไว้และแรสเตอร์ไรซ์กลิฟใหม่ตามต้องการได้ ซึ่งเป็นโหมดเดียวที่ขยายไปครอบคลุมภาษาที่นักพัฒนาไม่เคยคิดถึงได้

ทางออกของ TMP คือ รายการฟอนต์สำรอง font asset แต่ละตัวมีรายการ m_fallbackFontAssets และ TMP Settings มีรายการสำรองระดับโกลบอล เมื่อแอสเซ็ตหลักไม่มีกลิฟสำหรับโค้ดพอยต์หนึ่ง TMP จะไล่ดูรายการเหล่านั้นเพื่อหาตัวที่มี นี่คือจุดที่ถูกต้องสำหรับการเข้าไปแทรก เพราะมันปล่อยให้ฟอนต์ของเกมเองคุมทุกอย่างที่มันวาดได้อยู่แล้ว — UI จึงคงหน้าตาตามที่ตั้งใจไว้ และมีเฉพาะอักขระที่มันรับมือไม่ได้เท่านั้นที่มาจากที่อื่น

แก้ด้วยเครื่องมือตอนรันไทม์

XUnity.AutoTranslator hook เกมขณะที่มันทำงานและสลับฟอนต์ได้จากไฟล์คอนฟิกของมัน การตั้งค่าที่เกี่ยวข้องอยู่ใต้ [Behaviour]:

  • OverrideFont — แทนที่ฟอนต์ที่คอมโพเนนต์ Text ของ Unity UI รุ่นเก่าใช้ รับชื่อฟอนต์ที่เกมหรือระบบปฏิบัติการหาเจอ
  • OverrideFontTextMeshPro — แทนที่ TMP font asset ทั้งตัว ชี้ไปที่ไฟล์ TMP font AssetBundle หรือชื่อแอสเซ็ตที่เกมมีอยู่แล้ว
  • FallbackFontTextMeshPro — ตัวที่ปลอดภัยกว่าในสองตัวนี้: เพิ่มฟอนต์ที่ TMP จะไปดูเฉพาะกลิฟที่แอสเซ็ตของเกมเองไม่มี โดยคงแบบอักษรเดิมไว้ทุกที่ที่เหลือ
  • tmp_font_assetbundles — คอลเลกชันที่ชุมชนดูแล ซึ่งรวม TMP font AssetBundle สำเร็จรูปไว้ และเป็นสิ่งที่ OverrideFontTextMeshPro กับ FallbackFontTextMeshPro มักถูกชี้ไปหา บันเดิลเหล่านี้ถูกสร้างแยกตามเวอร์ชัน Unity และบันเดิลที่สร้างมาสำหรับ Unity คนละเวอร์ชันกับเกมจะโหลดไม่ขึ้น — การจับคู่เวอร์ชันคือขั้นที่คนมักพลาด

เครื่องมือตอนรันไทม์ผูกกับเครื่องและคอนฟิก: มันแก้เกมบนพีซีที่มันถูกติดตั้งไว้ และใครก็ตามที่รันบิลด์นั้นต้องตั้งค่าแบบเดียวกันเอง RuneTranslate อ่านและเขียนไฟล์ _AutoGeneratedTranslations.txt ของปลั๊กอินได้ โปรเจกต์ที่ใช้มันอยู่แล้วจึงไม่ใช่ทางตัน — ดู การเปรียบเทียบ ว่าแต่ละแนวทางเหมาะกับตรงไหน

แก้ที่ระดับไฟล์

RuneTranslate ใช้เส้นทางฟอนต์สำรองโดยตรงในข้อมูลของเกม ตอนส่งออก Unity มันหาตำแหน่ง TMP Settings ของเกม หา font asset ที่ใช้เป็นแม่แบบได้ และหาฟอนต์ แล้วสร้าง TMP font asset ตัวใหม่ในโหมด Dynamic รอบ ๆ ฟอนต์ที่รวมมาซึ่งครอบคลุมสคริปต์ปลายทาง จากนั้นต่อท้ายมันเข้าไปในรายการสำรอง รายการสำรองเดิมไม่ถูกแตะต้อง และฟอนต์ของเกมเองยังเป็นตัวหลัก — เกมญี่ปุ่นที่แปลเป็นไทยจึงคงสไตล์เดิมไว้สำหรับทุกอย่างที่เป็นละติน และดึงกลิฟไทยมาจากแอสเซ็ตที่ถูกฉีดเข้าไป

ข้อควรรู้ตามตรงสองข้อ มันต้องมี TMP Settings, แม่แบบ font asset ที่ใช้ได้ และ Font อยู่ในคอนเทนเนอร์เดียวกันของแอสเซ็ตเกม เกมที่จัดวางสิ่งเหล่านั้นต่างออกไปอาจอยู่นอกขอบเขต และเมื่อการฉีดถูกข้าม การส่งออกจะ บอกคุณ ในคำเตือน แทนที่จะจบแบบเขียวสวยงาม — การส่งออกที่ออกมาเป็นกล่องต้องไม่ดูเหมือนการส่งออกที่สำเร็จ ถ้าคุณเห็นคำเตือนนั้น เส้นทางเครื่องมือตอนรันไทม์ข้างบนคือแผนสำรอง

Ren'Py ได้ผลลัพธ์เดียวกันด้วยกลไกที่ต่างออกไป เพราะ Ren'Py ไม่มี TMP: RuneTranslate รวมฟอนต์ CJK หรือฟอนต์ที่ไม่ใช่ละตินเข้าไปในบิลด์ที่ส่งออกได้ แล้วลงทะเบียนผ่าน config.font_replacement_map ของ Ren'Py เอง เอนจินจึงแทนที่ฟอนต์ให้ทุกที่ที่ฟอนต์ของเกมจะเอาไม่อยู่

เช็กลิสต์สำหรับใช้งานจริง

  1. ดูความเสียหายก่อน สี่เหลี่ยมที่เหมือนกันหมด อักขระ ? หรือตัวอักษรเพี้ยน — ตัดสินให้ได้ว่าคุณเจอแบบไหนในสามแบบก่อนจะแตะอะไร
  2. ถ้าเป็น ? ให้เปิดไฟล์ที่ส่งออก ถ้าเครื่องหมายคำถามอยู่ในไฟล์แล้ว อักขระหายไปตั้งแต่ตอนเขียนและไม่มีฟอนต์ไหนช่วยได้ ให้ตรวจว่าการเข้ารหัสสตริงของเอนจินรองรับภาษาปลายทางของคุณหรือไม่
  3. ถ้าเป็นตัวอักษรเพี้ยน ให้ตรวจการเข้ารหัสที่เอนจินคาดหวังสำหรับไฟล์นั้น แทนที่จะไปตรวจฟอนต์
  4. ถ้าเป็นกล่อง ให้ยืนยันว่าเนื้อหาในไฟล์ถูกต้อง — ซึ่งเกือบทุกครั้งก็ถูกอยู่แล้ว — แล้วจัดการมันในฐานะงานฟอนต์
  5. บน Unity ให้เลือกเพิ่มฟอนต์สำรองมากกว่าการแทนที่ฟอนต์ของเกม การแทนที่เปลี่ยนหน้าตาของทุกสตริง รวมถึงตัวที่เรนเดอร์ดีอยู่แล้ว
  6. ถ้าคุณใช้ TMP font AssetBundle ให้จับคู่มันกับเวอร์ชัน Unity ของเกม
  7. ส่งออกใหม่แล้วตรวจอักขระ ตัวที่มีปัญหาโดยเฉพาะ ไม่ใช่แค่บทสนทนาบรรทัดแรก อักขระ Latin-Extended และวรรณยุกต์ไทยมักผ่านการสุ่มตรวจแต่ไปพังที่อื่น

ไปต่อที่ไหน

สำหรับเวิร์กโฟลว์ Unity ฉบับเต็ม — ว่า Unity เปิดเผยข้อความอะไรบ้าง และอะไรที่ยังเอื้อมไม่ถึง — อ่าน วิธีแปลเกม Unity และ หน้าเอนจิน Unity ข้อความที่ถูกอบลงในงานศิลป์แทนที่จะอยู่ในข้อมูลเป็นคนละปัญหาและใช้คนละเครื่องมือ: ดู การแปลรูปภาพ ส่วน คำถามที่พบบ่อย ครอบคลุมเรื่องน่าประหลาดใจอื่น ๆ ในการใช้งานครั้งแรก

RuneTranslate ใช้ฟรีโดยปลดล็อกทุกเอนจินและทุกผู้ให้บริการ รวมถึงสามรายที่ไม่ต้องใช้คีย์ API เลย มันแยกวิเคราะห์ไฟล์ของเกมเองแล้วส่งออกบิลด์ที่แปลแล้วซึ่งเล่นได้และเป็นของคุณ ดาวน์โหลดเลย หรือดู เอนจินที่รองรับ

อ่านที่เกี่ยวข้อง
01

XUnity.AutoTranslator ไม่ยอมแปลข้อความ

unityxunity-autotranslatortroubleshooting18 ส.ค. 2569 · 9 นาที
อ่าน →
02

วิธีแปลเกม Unity เป็นภาษาอังกฤษ

unitytutorialengine9 มิ.ย. 2569 · 6 นาที
อ่าน →
03

วิธีแปลเกม RPG Maker

rpg-makerhow-toenginecontrol-codes18 ส.ค. 2569 · 10 นาที
อ่าน →

พร้อมลอง RuneTranslate ไหม

ระดับฟรีปลดล็อกทุกเอนจิน + ทุกผู้ให้บริการแปล Supporter ($3/mo) ปลดล็อกความเร็วเต็ม

ดาวน์โหลดสำหรับ Windows