نظرة عامة
إنشاء {itemType}
يحول إلى مصدر ربح

إنشاء الأفاتار في التجربة

*This content is translated using AI (Beta) and may contain errors. To view this page in English, click here.

يمكنك نشر تجربة تسمح للاعبين بإنشاء وتخصيص وشراء أجساد الأفاتار في الوقت الفعلي. عند الشراء، يتم حفظ هذه الأجساد المخصصة مباشرة في مخزون اللاعب عبر Roblox، مما يسمح للاعبين بتجهيز وإرتداء الأفاتار المخصصة في تجارب أخرى.

يستفيد مالكو التجارب الذين يقومون بتطبيق إنشاء الأفاتار أثناء التجربة من عمولات السوق كـ مبدع عنصر الأفاتار ومالك التجربة. إذا تم فحص أحد الأصول التي تم إنشاؤها خلال التجربة، توفر العنصر رابطًا للتجربة الأصلية التي تم إنشاؤه فيها.

يمكنك اختبار إنشاء الأفاتار خلال التجربة في محرر الأفاتار من Roblox.

كيفية تطبيق إنشاء الأفاتار أثناء التجربة

استخدم التعليمات التالية ومراجع الكود لإنشاء مشروع إنشاء الأفاتار في تجاربك. التعليمات التالية تستخدم جسمًا أساسيًا Model يمكن للاعبين تعديله وتخصيصه قبل النشر.

قبل البدء، تعرف على ما يلي:

  • نماذج الأفاتار — يتطلب تنفيذ التالي استيراد جسم أساسي يلتقي بمواصفات أجزاء Roblox المكونة من 15 جزءًا. هذا Model يعمل كأساس للتخصيص والتعديل الإضافي من قبل المستخدمين.
    • يجب أن يلبي الجسم الأساسي إرشادات جسم الأفاتار من Roblox، بما في ذلك العدد الأدنى من عناصر التحكم FACS لتجهيز الوجه.
  • رموز إنشاء الأفاتار — تتطلب التجارب التي تقوم بتطبيق إنشاء الأفاتار على الأقل رمزًا واحدًا لإنشاء. تتطلب هذه الرموز روبيز لشرائها وتسمح لك بتعيين الأسعار والإعدادات الأخرى للمبيعات التي تتم خلال التجربة.
  • فئات API

استيراد جسم أساسي

يعمل الجسم الأساسي كأساس أولي يمكن للمستخدمين تخصيصه وتعديله. يمكنك استخدام Model الخاص بك، أو استيراد أصول مخصصة باستخدام المستورد وإعدادها من خلال إعداد الأفاتار.

يجب أن تلتزم الأجسام الأساسية بمواصفات الأفاتار من Roblox، ويجب أن تتضمن مكونات مثل 15 من مثيلات MeshPart التي تشكل 6 أجزاء من الجسم: الرأس، الجذع، الذراع اليسرى، الساق اليسرى، الذراع اليمنى، والساق اليمنى، بالإضافة إلى مكونات الأفاتار الأخرى الأجزاء.

للحصول على المراجع والعينات للأجساد المهيأة بشكل صحيح، انظر مراجع الأفاتار.

تنفيذ واجهات برمجة التطبيقات للتعديل

لتطوير نظام حيث يمكن للمستخدمين تعديل MeshPart على الأفاتار في تجربتك لإنشائها، استخدم EditableImage لتعديل القوام، وEditableMesh لتحرير الشبكة، وWrapDeformer للحفاظ على بيانات الوزن وFACS أثناء تعديلات الشبكة.

  1. بعد استيراد جسمك الأساسي، استخدم البرنامج النصي التالي لإعداد EditableImages وEditableMeshes وWrapDeformers.


    local AssetService = game:GetService("AssetService")
    local function setupBodyPart(meshPart, wrapTarget)
    -- إنشاء وإرفاق WrapDeformer إلى MeshPart
    local wrapDeformer = Instance.new("WrapDeformer")
    wrapDeformer.Parent = meshPart
    -- إنشاء شبكة قابلة للتعديل لجسم القفص للهدف المعني
    local cageEditableMesh: EditableMesh =
    AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {
    FixedSize = true,
    })
    -- تعيين الشبكة القفصية إلى WrapDeformer
    wrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))
    end
    local function setupRigidMesh(meshPart)
    -- إنشاء شبكة قابلة للتعديل من MeshPart الأصلي
    local editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {
    FixedSize = true,
    })
    -- توليد MeshPart جديدة من الشبكة القابلة للتعديل
    local newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))
    -- نسخ الحجم والموقع والقوام من MeshPart الأصلي
    newMeshPart.Size = meshPart.Size
    newMeshPart.CFrame = meshPart.CFrame
    newMeshPart.TextureContent = meshPart.TextureContent
    -- تطبيق MeshPart الجديدة مرة أخرى إلى الأصل
    meshPart:ApplyMesh(newMeshPart)
    end
    local function setupMeshTexture(meshPart, textureIdToEditableImageMap)
    -- إذا كان EditableImage موجودًا بالفعل لهذا TextureID، استخدمه بدلاً من إنشاء جديد
    if textureIdToEditableImageMap[meshPart.TextureID] then
    meshPart.TextureContent =
    Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])
    return
    end
    -- إنشاء EditableImage جديدة وتطبيقها كقيمة قوام
    local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))
    textureIdToEditableImageMap[meshPart.TextureID] = editableImage
    meshPart.TextureContent = Content.fromObject(editableImage)
    end
    local function setupModel(model)
    -- خريطة لإعادة استخدام مثيلات EditableImage بواسطة معرف القوام
    local textureIdToEditableImageMap = {}
    for _, descendant in model:GetDescendants() do
    if not descendant:IsA("MeshPart") then
    continue
    end
    -- تكوين MeshPart بناءً على وجود WrapTarget
    -- إذا كان WrapTarget موجودًا، أضف ابن WrapDeformer مع EditableMesh
    -- بخلاف ذلك، طبق EditableMesh مباشرة على MeshPart
    local wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")
    if wrapTarget then
    setupBodyPart(descendant, wrapTarget)
    else
    setupRigidMesh(descendant)
    end
    -- تكوين EditableImage لـ MeshPart
    setupMeshTexture(descendant, textureIdToEditableImageMap)
    end
    end
  2. أنشئ أدوات EditableImage التي تسمح للاعبين بتغيير الألوان، والرسم، أو إضافة ملصقات إلى جسمك الأساسي. يمكنك الاستفادة من واجهات برمجة التطبيقات مثل DrawImage() وDrawRectangle() وWritePixelsBuffer().

    • من أجل التحويلات المتقدمة، تتيح لك DrawImageTransformed() تحديد الموضع والدوران والنطاق عند رسم EditableImage واحدة على أخرى. وبالمثل، تعمل DrawImageProjected() بشكل مشابه لـ DrawImage() ولكن تسقط الصورة المرسومة بشكل صحيح إذا تم استخدام مثيل EditableImage مع MeshPart.


      local function recolorTexture(
      meshPart: MeshPart,
      color: Color3
      )
      local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)
      meshPart.TextureContent = Content.fromObject(bodyPartTexture)
      bodyPartTexture:DrawRectangle(
      Vector2.new(0, 0),
      bodyPartTexture.Size,
      color,
      0,
      Enum.ImageCombineType.Overwrite
      )
      end
      local function applySticker(
      meshPart: MeshPart,
      textureCoordinate: Vector2,
      stickerId: TextureId
      )
      local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)
      meshPart.TextureContent = Content.fromObject(bodyPartTexture)
      local stickerTexture = AssetService:CreateEditableImageAsync(stickerId)
      bodyPartTexture:DrawImage(textureCoordinate, stickerTexture, Enum.ImageCombineType.BlendSourceOver)
      end
      local function applyStickerProjected(
      meshPart: MeshPart,
      targetMesh: EditableMesh,
      stickerId: TextureId,
      raycastHitPos: Vector3
      )
      local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)
      local relativePos = meshPart.CFrame:PointToWorldSpace(raycastHitPos)
      local direction = (workspace.CurrentCamera.CFrame.Position - relativePos).Unit
      local projectionParams: ProjectionParams = {
      Direction = meshPart.CFrame:VectorToObjectSpace(direction),
      Position = meshPart.CFrame:PointToObjectSpace(relativePos),
      Size = Vector3.new(1, 1, 1),
      Up = meshPart.CFrame:VectorToObjectSpace(Vector3.new(0, 1, 0)),
      }
      local stickerTexture = AssetService:CreateEditableImageAsync(stickerId)
      local localBrushConfig: BrushConfig = {
      Decal = stickerTexture,
      ColorBlendType = Enum.ImageCombineType.BlendSourceOver,
      AlphaBlendType = Enum.ImageAlphaType.Default,
      BlendIntensity = 1,
      FadeAngle = 90.0
      }
      bodyPartTexture:DrawImageProjected(targetMesh, projectionParams, localBrushConfig)
      end
  3. باستخدام WrapDeformer وEditableMesh، أنشئ أدوات لتعديل تشوهات الشبكة على جسمك.

    1. يتولى WrapDeformer تشوهات الشبكة الحية لهندسة MeshPart مع الحفاظ على بيانات الوزن وFACS الأساسية.

    2. يسمح لك EditableMesh بتعديل شبكة القفص التي تستجيب لها WrapDeformer.

      1. استخدم WrapDeformer:SetCageMeshContent() لتطبيق مثيل EditableMesh الذي يمثل الشبكة القفصية المعنية على WrapDeformer.
      2. استخدم EditableMesh، مثل SetPosition(), لتشويه الرؤوس وتعديل شكل MeshPart.

      local function deformBodyPart(
      meshPart: MeshPart,
      controlPointCenter: Vector3,
      controlPointRadius: number,
      controlPointDeformation: Vector3
      )
      local wrapTarget = meshPart:FindFirstChildWhichIsA("WrapTarget")
      local cageMeshId = wrapTarget.CageMeshId
      local wrapDeformer = Instance.new("WrapDeformer")
      wrapDeformer.Parent = meshPart
      local cageEditableMesh = AssetService:CreateEditableMeshAsync(cageMeshId)
      local verticesWithinSphere =
      cageEditableMesh:FindVerticesWithinSphere(controlPointCenter, controlPointRadius)
      for _, vertexId in verticesWithinSphere do
      local vertexPosition = cageEditableMesh:GetPosition(vertexId)
      cageEditableMesh:SetPosition(vertexId, vertexPosition + controlPointDeformation)
      end
      wrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))
      end

إنشاء موجه لإنشاء الأفاتار

بعد إعداد جسمك الأساسي وواجهات برمجة التطبيقات للتعديل، أنشئ موجهًا للمستخدمين لإنشاء وشراء من التجربة باستخدام AvatarCreationService:PromptCreateAvatarAsync().


export type BodyPartInfo = {
bodyPart: Enum.BodyPart,
instance: Instance --المجلد مع MeshParts التي تم إنشاؤها
}
export type BodyPartList = {BodyPartInfo}
local function publishAvatar(bodyPartInstances: BodyPartList, player: Player, tokenId: string)
local humanoidDescription = Instance.new("HumanoidDescription")
for _, bodyPartInfo in bodyPartInstances do
local bodyPartDescription = Instance.new("BodyPartDescription")
bodyPartDescription.Instance = bodyPartInfo.instance
bodyPartDescription.BodyPart = bodyPartInfo.bodyPart
bodyPartDescription.Parent = humanoidDescription
end
local success, result, bundleIdOrErrorMessage, outfitId = pcall(function()
return AvatarCreationService:PromptCreateAvatarAsync(tokenId, player, humanoidDescription)
end)
if success then
if result == Enum.PromptCreateAvatarResult.Success then
print("تم رفعه بنجاح مع BundleId: ", bundleIdOrErrorMessage)
print("تم رفعه بنجاح مع OutfitId: ", outfitId)
else
print("لم يتم رفعه بنجاح مع رسالة الخطأ:", bundleIdOrErrorMessage)
end
else
print("إنشاء الأفاتار لم يكن ناجحًا")
end
end

AvatarCreationService:PromptCreateAvatarAsync() تأخذ معلمة HumanoidDescription لتمثيل الأفاتار المراد شراؤه أو إنشاؤه. لإنشاء الأفاتار، يجب أن تتضمن HumanoidDescription الخاصة بالشخصية أصول جديدة يجب إنشاؤها لكل جزء من الأجزاء الستة (Head, Torso, RightLeg, LeftLeg, RightArm, LeftArm). اختيارياً، يمكن أن تتضمن أيضًا إكسسوارًا Hair جديدًا.

لدعم ذلك، يجب أن تتضمن HumanoidDescription 6 أطفال من BodyPartDescription. يجب أن تشير خاصية BodyPartDescription.Instance إلى Folder التي تتضمن جميع مثيلات MeshPart التي تشكل جزء الجسم. على سبيل المثال، يحتوي مجلد LeftArm على LeftHand وLeftUpperArm وLeftLowerArm MeshParts. يجب أيضًا تعيين خاصية BodyPartDescription.BodyPart إلى Enum.BodyPart المعني.

يجب أن تتضمن كل من 15 جزءًا من MeshPart ما يلي:

يجب ألا تتضمن HumanoidDescription المقدمة أي معرفات أصول موجودة مسبقًا لتمثيل أجزاء الجسم أو الإكسسوارات على الإنشاء المقصود. من ناحية أخرى، قد تتضمن HumanoidDescription مقاييس humanoid الخاصة بـ BodyTypeScale, HeadScale, HeightScale, WidthScale، و ProportionScale. يجب الانتباه إلى المقاييس التي تم استيراد جسم أساسي بها بحيث تتطابق مع المقاييس المقدمة إلى HumanoidDescription.

تضمين الإكسسوارات

إذا كنت تتضمن إكسسوارًا، مثل الشعر، يجب أن تتضمن HumanoidDescription طفل AccessoryDescription حيث:

توليد رمز إنشاء الأفاتار

AvatarCreationService:PromptCreateAvatarAsync() تأخذ معلمة رمز إنشاء الأفاتار. هذا الرمز هو المفتاح لإنشاء من عالمك، وهو ما يمكنك استخدامه لتعيين سعر إنشاء الأفاتار من تجربتك. للحصول على التعليمات والتفاصيل الإضافية حول توليد الرموز، انظر رموز إنشاء الأفاتار.

بعد شراء وتوليد الرمز الخاص بك، يمكنك فحصه في مركز المبدعين للعثور على المعرف الذي يمكنك استخدامه بعد ذلك لـ AvatarCreationService:PromptCreateAvatarAsync() API.

الرد على انضمام اللاعبين بواسطة التخصيص

تشمل حزم الأفاتار التي تم إنشاؤها خلال التجربة رابط تخصيص للتجربة الأصلية التي تم إنشاء الأفاتار فيها. إذا تم فحص الأفاتار من قبل لاعب آخر، تظهر موجهة تقدم خيار زيارة التجربة حيث تم إنشاء الأفاتار.

للتعامل مع دخول اللاعبين إلى تجربتك باستخدام رابط التخصيص هذا، استخدم Player:GetJoinData() وحلل الجدول الذي تم إرجاعه للحصول على GameJoinContext.

يتضمن GameJoinContext قيم جدول التالية:

©2026 شركة Roblox Corporation. تُعد منصّة Roblox، وشعار Roblox وشعار "توسيع حدود المخيلة"، من ضمن علاماتنا التجارية المسجّلة وغير المسجّلة في الولايات المتحدة وبلدان أخرى.