ใครเคยเจอปัญหานี้บ้าง

The referenced script on this Behavior is missing! ที่เป็นแบบนี้เพราะว่า

  1. ดันทำสคริปต์หายจากจุดเดิมที่เคยมีไฟล์ .meta อยู่ ไหวตัวทันเอาสคริปต์กลับมา แต่ Compile ไม่ผ่าน ถ้าทำให้ผ่านมันก็จะมาใหม่เอง
  2. ดันไปย้ายไฟล์สคริปต์นอก Unity พอกดกลับมาใน Unity มันเลยลบ .meta เก่าทิ้งไปเพราะไม่เห็นว่ามีสคริปต์อยู่ พร้อมสร้าง .meta ใหม่ขึ้นมาเพราะคิดว่าสคริปต์ที่ย้ายที่เป็นอันใหม่ ทีนี้ component ที่จำ .meta เก่าไว้เลยหาไม่เจอ ต่อให้แก้ให้ compile ผ่านก็ไม่กลับมาอยู่ดีเพราะมันไม่รู้จัก script ใหม่แล้ว

ในกรณี 2 ถ้าเกิดขึ้นแล้ว ถึงเราจะรู้ว่าสคริปต์ที่หายไปคืออะไร แต่ถ้าลากไปใส่ใหม่ มันจะทำให้ค่าที่เคยเซ็ตไว้ใน inspector หายหมดเลย! แล้วสคริปต์ที่ว่านี้ใช้หลาย scene ด้วย ชิบหายแล้ว

ของผมโดนกรณีที่ 2 เพราะสคริปต์ที่ว่าเป็น git submodule แล้วทางต้นตอมีการย้ายของในโฟลเดอร์ โปรเจคที่เอามาใช้เลยโดนไปด้วย แถมไม่มีการเก็บ meta file ไว้บน submodule เพราะเราไม่ควรอัพของส่วนตัวขึ้นไป meta file ก็เลยโดน Unity ลบหายไปเลยเอากลับมาไม่ได้

แต่! โชคดีที่ในไฟล์ .unity (ไฟล์ scene) ยังจำข้อมูลเก่าไว้อยู่ถ้าเรายังไม่ได้ลากสคริปต์ใหม่ไปทับ ดังนั้นเรามาศัลยกรรมไฟล์ scene ให้กลับเป็นเหมือนเดิมกันดีกว่าโดยการบอก .meta ใหม่ให้มัน

ค้นหาเบาะแส

ก่อนอื่นเปิดไฟล์ .unity ด้วย text editor เพราะจริงๆมันเป็นแค่ text YAML มันทำมาให้คนพออ่านออก ถ้าใช้ VSCode แล้วหาไม่เจอ ไปเอายกเว้นออกในไฟล์ตั้งค่าก่อน

จากภาพที่เห็นเราควรเริ่มเซิจว่า GameplayEnder จนกว่าจะเจอแบบนี้

เอาอันที่อยู่ต่อจาก m_Name นะ เพราะมันแปลว่าชื่อของ game object ถ้าอันอื่น อาจจะเป็นแค่ public variable ของ game object อื่นๆ

เมื่อเจอแล้วเลื่อนลงมาดูข้างล่างช้าๆจะพบว่าเป็น component ต่างๆของ game object นี้ เราก็สามารถแกะเทียบกับในโปรเจคได้ว่าไอ้ที่ missing น่าจะเป็นอันไหน

ถ้าคิดว่าน่าจะเป็นอันนี้ จะเห็นว่ามี GUID อยู่คือ 618623419bd01427f8314e0979ac22bb อันนี้คือของ meta เก่าที่โดน Unity ลบไปเพราะเราดันไปย้ายสคริปต์โดยพละการ

หา GUID ใหม่

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

เมื่อรู้แล้วก็แค่ไปดูใน meta file ใหม่ของสคริปต์นั้น

ถ้าอ่านไฟล์ไม่ออกตั้งอันนี้ก่อน

Replace All

ใช้เครื่องมือ Replace All ข้ามไฟล์ แก้ให้หมดทุก scene ในครั้งเดียว ถ้ามันเซิจเจอหลายๆอันก็แปลว่าเราน่าจะเดามาถูกทาง ดูชื่อ scene แล้วคุ้นๆว่าเคยใช้จริงให้แน่ใจ

Crisis Averted!

จะเห็นว่ากลับมาแล้ว และเป็น UIDisabler ตามที่เดาไว้จริงๆ (จำได้ต่างหาก ไม่ได้เดา) ส่วนพวกที่ตั้งค่าไว้มันก็ยังอยู่ ต่อจากนี้ก็ไปไล่ทำทุกสคริปต์ที่มีปัญหาก็เป็นอันเสร็จ (คราวหลังจะย้ายไฟล์ย้ายใน Unity ล่ะมันจะได้ก๊อป meta ตามไปให้เรา)