Tóm lại

Một câu hỏi liên tục quay lại trên r/Unity3D: nhập PSD thành từng lớp riêng mà mỗi Sprite vẫn giữ kích thước tài liệu và độ lệch ban đầu. Bài đăng đó dừng lại ở hai đề xuất: tự xuất từng lớp từ Photoshop, hoặc coi phần trong suốt dư ra là vấn đề của thiết kế. Cơ chế nằm sau hành vi này thì không được nói rõ.

PSD Importer không có tùy chọn giữ kích thước canvas cho từng Sprite. Vị trí được giữ ở một chỗ khác: Prefab được tạo ra lúc nhập. Lần nhập thứ hai, SpriteRect không cập nhật khi canvas hoặc lớp đổi kích thước. Muốn khớp lại thì sửa rect trong Sprite Editor, hoặc áp dụng Automatic Reslice — cái sau bỏ hết các sửa tay.

Individual Sprites (Mosaic) thực sự cho ra cái gì

Đặt Texture Type (loại texture) là Sprite (2D and UI), Sprite Mode (chế độ Sprite) là Multiple, Import Mode (chế độ nhập) là Individual Sprites (Mosaic). Các lớp vào thành một Texture đã đóng gói, mỗi lớp có một SpriteRect, và mỗi SpriteRect chạy theo đúng phần hình của lớp đó. Một hình tròn 32 pixel trên canvas 2048 pixel sẽ thành một Sprite 32 pixel.

Cạnh tùy chọn đó có hai thiết lập padding, và không cái nào trả canvas về. Mosaic Padding quy định khoảng cách giữa các lớp trong Texture đã đóng gói. Sprite Padding được thêm ở PSD Importer 8.0.0 cho Unity 2022.2, nới rộng rect của từng Sprite trong Texture. Cả hai đều chỉ điều chỉnh khoảng cách, còn điểm bắt đầu của rect vẫn là phần hình của lớp. Trim (bó sát) trong Sprite Editor đi cùng hướng đó, thu rect về sát mép các pixel không trong suốt; muốn nới rect ra thì phải sửa tay, từng Sprite một.

Vị trí được giữ trong Prefab, không phải trong Sprite

Character Rig → Use as Rig (dùng làm rig) tạo một Prefab từ tệp nguồn. Thứ bậc và vị trí của các Sprite lấy từ thứ bậc lớp và từ chỗ các lớp nằm trong PSD; mỗi Sprite còn nhận một giá trị Order in Layer theo thứ tự lớp, nên Prefab dựng lại đúng cách sắp xếp của tệp nguồn. Bật Use Layer Grouping (giữ nhóm lớp) thì các nhóm trong Photoshop được giữ làm node cha.

Phần này trong Inspector chỉ hiện khi Sprite Mode là Multiple, Import Mode là Individual Sprites (Mosaic), và gói 2D Animation đã được cài. Unity viết cùng bộ công tắc đó ở mục chuẩn bị art cho animation, nơi kết quả mong đợi là một actor nhân vật đã gắn rig, kèm asset .skeleton và Skinning Editor. Đọc theo cách nào thì vị trí cũng trở lại. Chỉ có điều một màn UI nhập theo đường này sẽ ra một actor cho animation, còn thứ bậc Canvas thì phải dựng riêng.

Bên trái là Texture đã đóng gói, bên phải là Prefab đã trả các lớp về vị trí

Vậy là bài đăng đó có sẵn một câu trả lời: tỉ lệ và vị trí tương đối đã được xử lý, và kích thước canvas của từng Sprite không phải là núm điều chỉnh mang lại hai thứ đó.

Cái giá của định dạng tệp và những thuộc tính lớp bị bỏ qua

Tệp .psd theo mặc định đi qua Texture Importer thường và bị gộp phẳng. Muốn đi đường phân lớp thì chọn tệp rồi đổi dropdown Importer sang UnityEditor.U2D.PSD.PSDImporter, hoặc làm việc với .psb — định dạng mà PSD Importer nhắm tới trực tiếp, hỗ trợ tới 300.000 pixel mỗi chiều. Khi lưu thì bật Maximize Compatibility (tối đa tương thích).

Có bốn thuộc tính lớp của Photoshop bị bỏ khi Sprite và Prefab được tạo: Channels (kênh), Blend Modes (chế độ hòa trộn), Layer Opacity (độ mờ của lớp), Effects (hiệu ứng lớp). Một tấm art dựa vào lớp multiply hay bóng đổ độ mờ 40% sẽ vào với những thứ đó đã gộp phẳng, và việc khớp lại với bản gốc trở thành công việc viết shader và chỉnh material bên trong Unity.

Lần nhập thứ hai

Dữ liệu SpriteRect được lưu theo Layer ID, nhờ vậy các sửa tay còn lại sau khi nhập lại. Cùng cơ chế đó có nghĩa: đổi lớp hay đổi kích thước canvas trong tệp nguồn thì kích thước và vị trí của SpriteRect không đổi theo. Muốn khớp lại thì sửa rect trong Sprite Editor, hoặc áp dụng Automatic Reslice (tự động chia lại) — cái sau tạo lại toàn bộ rect từ tệp nguồn hiện tại và bỏ hết các thay đổi thủ công của bộ đó.

Với một tệp nhân vật thì đây là cái giá đã biết. Với một màn sẽ được sinh lại, hay cả một thư mục PSD đang chờ cùng một cách xử lý, đó mới là lý do chữ batch xuất hiện trong câu tìm kiếm. PSD sang Unity đi đường khác: chạy bước tách lớp ở ngoài Editor, rồi một lần xuất ghi ra Assets/Prefabs và Assets/Textures, để tên và cấu trúc thư mục về cùng với tệp.

Thư mục Assets sau khi giải nén, bên trong có Prefabs và Textures

Kết luận

Kích thước tài liệu không phải là núm cần xoay cho vấn đề này. Với một tệp, vị trí đã được hoàn lại nhờ Use as Rig. Một màn được sinh lại, hay cả một thư mục PSD, thì mỗi lần nhập lại SpriteRect vẫn giữ kích thước cũ, nên mỗi tệp đều phải làm lại cùng một lượt chỉnh rect.