{itemType} erstellen
Monetarisieren
Grundsätze und Richtlinien

Avatar-Erstellung innerhalb der Erfahrung

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Sie können eine Erfahrung veröffentlichen, die es den Spielern ermöglicht, Avatar-Körper in Echtzeit zu erstellen, anzupassen und zu kaufen. Wenn diese benutzerdefinierten Körper gekauft werden, werden sie direkt im Roblox-Inventar des Spielers gespeichert, sodass die Spieler die benutzerdefinierten Avatare in anderen Erfahrungen ausrüsten und tragen können.

Erfahrungsinhaber, die die Avatar-Erstellung innerhalb der Erfahrung implementieren, profitieren von Marktplatzprovisionen sowohl als Ersteller des Avatar-Artikels als auch als Erfahrungsinhaber. Wenn ein in der Erfahrung erstelltes Asset inspiziert wird, bietet der Artikel einen Link zur ursprünglichen Erfahrung, in der es erstellt wurde.

Sie können die Erstellung innerhalb der Erfahrung in der Roblox Avatar Creator Demo testen.

So implementieren Sie die Erstellung innerhalb der Erfahrung

Verwenden Sie die folgenden Anweisungen und Codebeispiele, um Ihr erstes Projekt zur Avatar-Erstellung innerhalb der Erfahrung zu erstellen. Die folgenden Anweisungen verwenden einen Basis-Körper Model, den die Spieler modifizieren und anpassen können, bevor sie ihn veröffentlichen.

Bevor Sie beginnen, machen Sie sich mit Folgendem vertraut:

  • Avatar-Modelle — Die folgende Implementierung erfordert den Import eines Basis-Körpers, der den 15 Teile-Spezifikationen von Roblox entspricht. Dieses Model dient als Basis für zusätzliche Benutzeranpassungen und -modifikationen.
    • Der Basis-Körper muss den Avatar-Körperrichtlinien von Roblox entsprechen, einschließlich der Mindestanzahl von FACS-Steuerungen für die gesichtliche Rigging.
  • Tokens zur Avatar-Erstellung — Erfahrungen, die die Avatar-Erstellung implementieren, benötigen mindestens ein Erstellungstoken. Diese Tokens erfordern Robux für den Kauf und ermöglichen es Ihnen, Preise und andere Verkaufseinstellungen für Käufe innerhalb der Erfahrung festzulegen.
  • API-Klassen
    • AvatarCreationService — Verwaltet die Aufforderung zur Avatar-Erstellung und die Validierung.
    • EditableImage — Verwaltet die runtime Erstellung und Manipulation von Texturen.
    • EditableMesh — Verwaltet die runtime Manipulation der Geometrie von Meshes.
    • WrapDeformer — Verwaltet die runtime Manipulation der unsichtbaren äußeren Käfiggeometrie, die Avatar-Charaktere die Ausrüstung von 3D-Kleidung ermöglicht.

Importieren eines Basis-Körpers

Der Basis-Körper dient als anfängliche Grundlage, die Benutzer anpassen und bearbeiten können. Sie können Ihr eigenes Model verwenden oder ein benutzerdefiniertes Asset mit dem Importer importieren und über Avatar Setup einrichten.

Basis-Körper müssen den Avatar-Spezifikationen von Roblox entsprechen und Komponenten wie die 15 MeshPart Instanzen enthalten, die aus 6 Körperteilen bestehen: Kopf, Torso, linker Arm, linkes Bein, rechter Arm und rechtes Bein, sowie andere Avatar-Komponenten.

Für Referenzen und Beispiele von korrekt konfigurierten Avatar-Körpern siehe Avatar-Referenzen.

Implementierung von Bearbeitungs-APIs

Um ein System zu entwickeln, in dem Benutzer die MeshPart Instanzen eines Avatars in Ihrer Erfahrung für die Erstellung bearbeiten können, verwenden Sie EditableImage für die Textur-Bearbeitung, EditableMesh für die Mesh-Bearbeitung und WrapDeformer zur Aufrechterhaltung der Skinning- und FACS-Daten während Mesh-Bearbeitungen.

  1. Nachdem Sie Ihren Basis-Körper importiert haben, verwenden Sie das folgende Skript, um Ihre EditableImages, EditableMeshes und WrapDeformers einzurichten.


    local AssetService = game:GetService("AssetService")
    local function setupBodyPart(meshPart, wrapTarget)
    -- Erstellen und Anfügen eines WrapDeformers an das MeshPart
    local wrapDeformer = Instance.new("WrapDeformer")
    wrapDeformer.Parent = meshPart
    -- Erstellen eines editierbaren Meshs für das Käfig-Mesh des Wrap-Ziels
    local cageEditableMesh: EditableMesh =
    AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {
    FixedSize = true,
    })
    -- Weisen Sie das Käfig-Mesh dem WrapDeformer zu
    wrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))
    end
    local function setupRigidMesh(meshPart)
    -- Erstellen eines editierbaren Meshs aus dem ursprünglichen MeshPart
    local editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {
    FixedSize = true,
    })
    -- Generieren eines neuen MeshParts aus dem editierbaren Mesh
    local newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))
    -- Größe, Position und Textur vom ursprünglichen MeshPart kopieren
    newMeshPart.Size = meshPart.Size
    newMeshPart.CFrame = meshPart.CFrame
    newMeshPart.TextureContent = meshPart.TextureContent
    -- Wenden Sie das neue MeshPart auf das ursprüngliche an
    meshPart:ApplyMesh(newMeshPart)
    end
    local function setupMeshTexture(meshPart, textureIdToEditableImageMap)
    -- Wenn EditableImage bereits für diese TextureID vorhanden ist, verwenden Sie es erneut, anstatt ein neues zu erstellen
    if textureIdToEditableImageMap[meshPart.TextureID] then
    meshPart.TextureContent =
    Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])
    return
    end
    -- Erstellen Sie ein neues EditableImage und wenden Sie es als Texturinhalt an
    local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))
    textureIdToEditableImageMap[meshPart.TextureID] = editableImage
    meshPart.TextureContent = Content.fromObject(editableImage)
    end
    local function setupModel(model)
    -- Karte zum Wiederverwenden von EditableImage-Instanzen nach Textur-ID
    local textureIdToEditableImageMap = {}
    for _, descendant in model:GetDescendants() do
    if not descendant:IsA("MeshPart") then
    continue
    end
    -- Konfigurieren Sie das MeshPart basierend auf dem Vorhandensein von WrapTarget
    -- Wenn WrapTarget vorhanden ist, fügen Sie ein WrapDeformer-Kind mit einem EditableMesh hinzu
    -- Andernfalls wenden Sie EditableMesh direkt auf das MeshPart an
    local wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")
    if wrapTarget then
    setupBodyPart(descendant, wrapTarget)
    else
    setupRigidMesh(descendant)
    end
    -- Konfigurieren Sie das EditableImage für das MeshPart
    setupMeshTexture(descendant, textureIdToEditableImageMap)
    end
    end
  2. Erstellen Sie EditableImage-Tools, die es den Spielern ermöglichen, Ihren Basis-Körper neu zu färben, zu zeichnen oder Aufkleber hinzuzufügen. Sie können APIs wie DrawImage(), DrawRectangle(), WritePixelsBuffer() nutzen.

    • Für fortgeschrittene Transformationen ermöglicht DrawImageTransformed() Ihnen, Position, Rotation und Skalierung beim Zeichnen eines EditableImage auf ein anderes anzugeben. Ähnlich funktioniert DrawImageProjected() wie DrawImage(), projiziert jedoch das gezeichnete Bild korrekt, wenn die EditableImage-Instanz mit einem MeshPart verwendet wird.


      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. Verwenden Sie WrapDeformer und EditableMesh, um Tools zur Bearbeitung von Mesh-Deformationen an Ihrem Körper zu erstellen.

    1. WrapDeformer verwaltet die Live-Deformationen der gerenderten MeshPart-Geometrie und bewahrt die zugrunde liegenden Skinning- und FACS-Daten.

    2. EditableMesh ermöglicht es Ihnen, das Käfig-Mesh zu modifizieren, auf das der WrapDeformer reagiert.

      1. Verwenden Sie WrapDeformer:SetCageMeshContent(), um die EditableMesh-Instanz anzuwenden, die das relevante Käfig-Mesh für den WrapDeformer darstellt.
      2. Verwenden Sie EditableMesh, wie SetPosition(), um die Scheitelpunkte zu deformieren und die Form des MeshPart zu bearbeiten.

      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

Erstellungsprompt erstellen

Nachdem Sie Ihren Basis-Körper und die Bearbeitungs-APIs eingerichtet haben, erstellen Sie eine Aufforderung für Benutzer, um aus der Erfahrung zu erstellen und zu kaufen, indem Sie AvatarCreationService:PromptCreateAvatarAsync() verwenden.


export type BodyPartInfo = {
bodyPart: Enum.BodyPart,
instance: Instance --Ordner mit Erstellten 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("Erfolgreich hochgeladen mit BundleId: ", bundleIdOrErrorMessage)
print("Erfolgreich hochgeladen mit OutfitId: ", outfitId)
else
print("Nicht erfolgreich hochgeladen mit Fehlermeldung:", bundleIdOrErrorMessage)
end
else
print("Avatar-Erstellung nicht erfolgreich")
end
end

AvatarCreationService:PromptCreateAvatarAsync() nimmt einen HumanoidDescription Parameter, um den Avatar, der zum Kauf oder zur Erstellung vorgesehen ist, darzustellen. Für die Avatar-Erstellung muss die HumanoidDescription des Charakters neue Assets enthalten, die für jedes der 6 Körperteile erstellt werden (Head, Torso, RightLeg, LeftLeg, RightArm, LeftArm). Optional kann es auch ein neues Hair-Zubehör enthalten.

Um dies zu unterstützen, sollte die HumanoidDescription 6 BodyPartDescription-Kinder enthalten. Jede BodyPartDescription.Instance-Eigenschaft verweist auf einen Folder, der alle MeshPart-Instanzen enthält, die das Körperteil ausmachen. Zum Beispiel enthält der LeftArm-Ordner LeftHand, LeftUpperArm und LeftLowerArm MeshParts. Die BodyPartDescription.BodyPart-Eigenschaft sollte ebenfalls auf das relevante Enum.BodyPart gesetzt werden.

Jedes der 15 MeshPart Körperteile muss Folgendes enthalten:

Die bereitgestellte HumanoidDescription sollte keine bestehenden Asset-IDs enthalten, um Körperteile oder Zubehör für die beabsichtigte Kreation darzustellen. Andererseits kann die HumanoidDescription die humanoiden Skalen von BodyTypeScale, HeadScale, HeightScale, WidthScale, und ProportionScale enthalten. Achten Sie darauf, dass die Skalen, mit denen ein Basis-Körper importiert wird, übereinstimmen mit den Skalen, die der HumanoidDescription bereitgestellt werden.

Zubehör einbeziehen

Wenn ein Zubehör, wie z.B. Haare, einbezogen wird, sollte die HumanoidDescription ein Kind AccessoryDescription enthalten, wo:

Generieren eines Tokens für die Avatar-Erstellung

AvatarCreationService:PromptCreateAvatarAsync() nimmt einen Token-ID für die Avatar-Erstellung Parameter. Dieser Token ist der Schlüssel für Kreationen aus Ihrem Universum und es ist das, was Sie verwenden können, um den Preis der Avatar-Erstellung aus Ihrer Erfahrung festzulegen. Für Anweisungen und zusätzliche Details zur Generierung von Tokens siehe Tokens zur Avatar-Erstellung.

Nachdem Sie Ihren Token gekauft und generiert haben, können Sie den Token im Creator Hub inspizieren, um die ID zu finden, die Sie dann für die AvatarCreationService:PromptCreateAvatarAsync() API verwenden können.

Auf Spieler reagieren, die durch Attribution beitreten

Avatar-Bundles, die innerhalb der Erfahrung erstellt wurden, enthalten einen Attributionslink zur ursprünglichen Erfahrung, in der der Avatar erstellt wurde. Wenn der Avatar von einem anderen Spieler inspiziert wird, wird eine Aufforderung angezeigt, die eine Option bietet, die Erfahrung zu besuchen, in der der Avatar erstellt wurde.

Um Spieler zu handhaben, die über diesen Attributionslink Ihrer Erfahrung beitreten, verwenden Sie Player:GetJoinData() und analysieren Sie die zurückgegebene Tabelle nach GameJoinContext.

GameJoinContext enthält die folgenden Tabellenwerte:

©2026 Roblox Corporation. Roblox, das Roblox-Logo und "Powering Imagination" gehören zu unseren eingetragenen und nicht eingetragenen Markenzeichen in den USA und anderen Ländern.