Genel bakış
| Alan | Ne sağlar |
|---|---|
| Katalog | Kategori ağacı, 669 parça, 209 renk/doku varyantı, GLB adresleri ve gövde maskeleri. |
| Avatarlar | Kullanıcının varsayılan avatarı, sürüm geçmişi, önizleme fotoğrafı; herkese açık profil okuma. |
| Varlık yönetimi | Çekirdek parça/varyant düzenleme, GLB ve doku yükleme, kategori yönetimi (yalnızca yönetici). |
| Stüdyo | Tarayıcıda avatar oluşturma: parça seçimi, rastgele görünüm, tek GLB dışa aktarma; GET /avatars/random ile API üzerinden rastgele görünüm. |
Taban adres: {site}/api/v1. Tüm yanıtlar JSON; hata gövdesi {"success":0,"message":"…"} ve uygun HTTP kodu.
Kimlik doğrulama
Üç yol vardır; hepsi aynı uçları kullanır.
| Yol | Başlık | Kim için |
|---|---|---|
| API anahtarı | X-Api-Key + X-External-User-Id | Sunucudan sunucuya (ör. uygulamanın arka ucu, kullanıcıyı kendi kimliğiyle temsil eder) |
| Bearer | Authorization: Bearer <Supabase access token> | Mobil/Unity doğrudan girişleri |
| Çerez | Tarayıcı oturumu | Bu site |
Katalog uçları açıktır, kimlik istemez. Varlık (/studio/*) ve yönetici (/admin/*) uçları yönetici rolü ister (profiles.role = admin ya da STUDIO_ADMIN_EMAILS).
Hızlı başlangıç
# erkek üst giyim parçaları
curl "{site}/api/v1/catalog/items?bodyType=male&slot=OutfitTop"
# bir parçanın ayrıntısı (GLB adresi, varyantlar, gövde maskesi)
curl "{site}/api/v1/catalog/items/top_male_12?bodyType=male"
# avatar kaydet (API anahtarı ile, uygulama kullanıcısı 1234 adına)
curl -X PUT "{site}/api/v1/avatars/me" \
-H "X-Api-Key: $KEY" -H "X-External-User-Id: 1234" \
-H "Content-Type: application/json" \
-d '{"avatar":"{\"bodyType\":1,\"equippedItems\":[{\"slotType\":32,\"itemId\":\"male_hair_0\",\"materialId\":\"male_hairColor0\"}]}"}'Katalog API
| Uç | Açıklama |
|---|---|
GET /catalog?bodyType=female|male | Kategori ağacı; her düğümde parça ve varyant listeleri. db=full ile uygulama dışı parçalar da gelir; masks=1 her parçanın gövde maskesini ekler. |
GET /catalog/items | Düz liste. Süzgeçler: bodyType, slot (ad ya da sayı), q, category (yol), inApp=1. |
GET /catalog/items/{itemId} | Parça ayrıntısı: glbUrl, meshName, dokular, materials (varyantlar), categories, bodyMask. |
GET /catalog/materials | Varyantlar (bodyType, slot, itemId süzgeçleri). |
Parça nesnesi: itemId, name, slot/slotType (AvatarSlotType bayrağı), bodyTypes,preview, glbUrl, glbSize, glbSha1, meshName, textureCount, inApp,tags, bodyMask. Dosya adresleri mutlak URL'dir; GLB'ler Wolf3D iskeletine bağlı (skinned) tek mesh içerir.
Avatar API
| Uç | Açıklama |
|---|---|
GET /avatars/me | Varsayılan avatar (avatar: Unity JSON string, data: nesne, imgUrl). |
PUT /avatars/me | Kaydet/değiştir. Gövde: avatar (string ya da nesne), isteğe bağlı avatarImage (base64 PNG/JPEG), name. |
GET /avatars/me/versions | Kayıt geçmişi (en yeni önce, limit). |
GET /avatars/{profileId} | Başka bir profilin avatarı (açık; oda içindeki diğer oyuncuları çizmek için). |
POST /updateAvatar | Uygulamanın mevcut isteğiyle birebir aynı gövde ve yanıt. |
Veri sözleşmesi
Avatar verisi Unity'deki Metaverse.Avatar.AvatarSaveData ile aynıdır; JsonUtility çıktısı olduğu gibi kabul edilir.
{
"bodyType": 1, // 0 Female, 1 Male
"equippedItems": [
{ "slotType": 32, "itemId": "male_hair_0", "materialId": "male_hairColor0" },
{ "slotType": 256, "itemId": "top_male_12", "materialId": "" }
]
}| slotType | Slot | slotType | Slot |
|---|---|---|---|
| 1 | EyeRight | 128 | Facewear |
| 2 | EyeLeft | 256 | OutfitTop |
| 4 | Head | 512 | OutfitBottom |
| 8 | Glasses | 1024 | OutfitFootwear |
| 16 | Headwear | 2048 | Body |
| 32 | Hair | 4096 | Eyebrow |
| 64 | Beard |
Gövde maskeleri
Ready Player Me her kıyafetle kesilmiş bir gövde gönderir; bu platform ise tam gövde üzerine üst, alt ve ayakkabıyı ayrı ayrı giydirir. Tenin kumaştan taşmaması için her kıyafetin bodyMask alanı, gövde mesh'inin hangi köşelerinin o kıyafetin altında kaldığını söyler.
- Biçim: gövde köşe sayısı kadar bit (kadın ve erkek gövdesi 3310 köşe),
numpy.packbitssırası (en anlamlı bit önce), base64. - Uygulama: giyili üst + alt + ayakkabı maskelerinin birleşimi alınır; üç köşesi de maskeli olan gövde üçgenleri çizilmez (Unity:
Manager.ApplyBodyMask). - Maske bind pozunda hesaplanır; kumaşın açık kenarlarına 1,5 cm'den yakın ten korunur, bu yüzden manşet ve yakalarda boşluk oluşmaz.
Unity entegrasyonu
| Uygulama (bugün) | Avatar Manager |
|---|---|
POST updateAvatar | POST /api/v1/updateAvatar (aynı gövde ve yanıt) ya da PUT /api/v1/avatars/me |
readyPlayerMe.avatar | GET /api/v1/avatars/me → avatar.avatar |
readyPlayerMe.photo | avatar.imgUrl |
Yerel AvatarItemDatabase | GET /api/v1/catalog (aynı kategori ağacı, aynı kimlikler) + glbUrl ile çalışma anında yükleme (glTFast) |
AvatarItem.bodyMask | GET /api/v1/catalog/items/{itemId} → bodyMask |
Önerilen ilk adım: uygulamanın arka ucu X-Api-Key ile Avatar Manager'a yazar/okur; Unity tarafı değişmez. İkinci adım: Unity kataloğu ve GLB'leri doğrudan API'den çeker.
Varlık API (yönetici)
Çekirdek kataloğun düzenlendiği uçlar; site üzerinde karşılığı Varlık yönetimi.
| Uç | Açıklama |
|---|---|
POST /studio/items | Yeni parça: itemId, bodyType, name, slot, categoryPath, tags. |
PATCH /studio/items/{itemId}?bodyType= | Ad, açıklama, etiket, slot, kategori, GLB/önizleme adresi, maske, inApp, active. |
POST /studio/upload | multipart/form-data: kind (glb | texture | preview) + file. İçerik özetine göre saklanır, herkese açık URL döner; GLB için mesh/materyal/doku özeti. |
PUT /studio/materials/{materialId} | Renk ya da doku varyantı (slot geneli ya da bir parçaya özel). |
GET /studio/changes | Son değişiklikler (kim, ne, ne zaman). |
GET /avatars/random?bodyType=&project=&inApp=1 | Rastgele ama tutarlı bir görünüm (avatar AvatarSaveData, avatarJson Unity dizesi, parts önizleme ve GLB adresleri). Stüdyo sayfası aynı kuralı tarayıcıda uygular ve seçilen parçaları tek GLB olarak dışa aktarır. |
Hesaplar ve projeler
İki rol vardır: yönetici çekirdek kataloğu stüdyodan düzenler ve bütün projeleri görür; hesap (müşteri) kendi projelerini açar. Hesap açma herkese kapalıdır; hesaplar yönetici tarafından açılır.
Bir proje bir uygulamadır (ör. Lagomya, VRSocial): çekirdek katalogdaki parçalardan istemediklerini kapatır, kendi API anahtarlarını üretir ve kullanıcılarının avatarları o projede saklanır. Çekirdeğe eklenen yeni parçalar her projede otomatik açık gelir.
| Uç | Açıklama |
|---|---|
GET /projects · POST /projects | Hesabın projeleri; yeni proje (name, description). Oturum çerezi ya da Bearer belirteci ile. |
GET/PATCH/DELETE /projects/{id} | Proje ayrıntısı (istatistik + kapalı parçalar), ad/açıklama güncelleme, silme. |
GET/PUT /projects/{id}/items | Kapalı parçalar; {"items":[{"itemId":"…","bodyType":1,"enabled":false}]} ile kapat/aç. |
GET/POST /projects/{id}/keys · DELETE …/keys/{keyId} | Projeye bağlı API anahtarları; anahtar yalnızca oluşturma yanıtında görünür. |
GET/POST /projects/{id}/assets | Projenin kendi parçaları. POST ile yeni parça (name, slot, bodyType), bir çekirdek parçanın kopyası (fromItemId) ya da projede onun yerine geçen kendi sürümü (fromItemId + override: true). |
GET/PATCH/DELETE /projects/{id}/assets/{itemId}?bodyType= | Projenin parçasını düzenle (ad, etiket, kategori, GLB, önizleme, mesh, maske, açık/kapalı) ya da sil; silinen kendi sürümün yerine çekirdek sürüm döner. |
POST /projects/{id}/upload · PUT/DELETE /projects/{id}/materials/{materialId} | GLB / doku / önizleme yükleme ve projeye ait renk-doku varyantları (çekirdek parçalar için de). |
POST /projects/{id}/import · PATCH /projects/{id}/assets/bulk | ZIP ile toplu parça (her .glb bir parça, aynı adlı .png önizleme, isteğe bağlı manifest.csv) ve seçili parçalara toplu etiket/kategori. |
GET /projects/{id}/changes · POST …/changes/{changeId}/undo | Değişiklik geçmişi (kim, ne zaman, ne) ve geri alma: güncellemeler eski değere döner, oluşturulanlar kaldırılır, silinenler kopyasından gelir, kapatılan parçalar açılır. |
PATCH /projects/{id}/keys/{keyId} | Anahtar kapsamı (read yalnız okur, readwrite avatar da kaydeder) ve geçerlilik süresi. Her anahtar dakikada 600 istekle sınırlıdır (429). |
POST /projects/{id}/assets/transfer | {"items":[{"itemId":"…","bodyType":1}],"targetProjectId":"…","move":false}: projeye ait parçaları (varyantlarıyla) hesabın başka bir projesine kopyalar ya da taşır; hedefte aynı kimlik varsa atlanır. |
POST /projects/{id}/webhook/test | Ayarlar'daki webhook adresine imzalı test olayı. Katalog değişince {"event":"catalog.changed"} gönderilir; X-Avatar-Manager-Signature HMAC-SHA256. |
Katalog yanıtları ETag taşır; If-None-Match ile tekrar istenince değişmemişse 304 döner ve gövde indirilmez. Servis durumu: /status ve GET /api/v1/status.
Katalog uçları project=<kısa-ad> parametresiyle o projenin görünümünü döner (ör. /catalog?project=lagomya&bodyType=1&db=full&masks=1); projeye bağlı bir X-Api-Key ile çağrıldığında parametre gerekmez. Bu anahtarla kaydedilen avatarlar projenin "Avatarlar" sekmesinde listelenir.
Hesap ve yönetici uçları
| Uç | Açıklama |
|---|---|
GET /account · PATCH /account | Oturum sahibinin özeti (e-posta, rol, proje ve anahtar sayısı); görünen ad güncelleme. |
POST /account/password · POST /account/email | Mevcut şifre doğrulanarak şifre ya da e-posta değişikliği. |
GET /admin/accounts · POST /admin/accounts | Yönetici: bütün hesaplar (rol, son giriş, proje/anahtar/avatar sayıları); yeni hesap açma (email, displayName, role; şifre verilmezse geçici şifre bir kez döner). |
PATCH/POST/DELETE /admin/accounts/{profileId} | Rol, ad, e-posta, kapatma (banned); POST yeni geçici şifre üretir; DELETE hesabı ve bağlı her şeyi siler. |
GET /admin/stats | Panel verisi: hesap/proje/avatar/anahtar sayıları, 30 günlük kayıt serisi, proje başına avatar, en çok giyilen parçalar. |
OpenAPI / Swagger
Makine okunur şema: /api/v1/openapi.json. Aşağıda etkileşimli Swagger arayüzü; Try it out ile canlı çağrı yapabilirsiniz.
Sorular için: Avatar Manager · Metaverse Software