{itemType} erstellen
Monetarisieren
Grundsätze und Richtlinien

Erstellung von Avataren im Erlebnis

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

Sie können ein Erlebnis veröffentlichen, das es Spielern ermöglicht, Avatarkörper in Echtzeit zu erstellen, anzupassen und zu kaufen. Wenn diese benutzerdefinierten Körper gekauft werden, werden sie direkt im Roblox-Inventory des Spielers gespeichert, so dass die Spieler die benutzerdefinierten Avatare in anderen Erlebnissen ausrüsten und tragen können.

Erlebnisbesitzer, die die Erstellung von Avataren im Erlebnis umsetzen, profitieren sowohl als Ersteller des Avatar-Elements als auch als Erlebnisbesitzer von Marktplatzprovisionen. Wenn ein im Erlebnis erstelltes Asset inspiziert wird, enthält das Element einen Link zum ursprünglichen Erlebnis, in dem es erstellt wurde.

Sie können die Erstellung im Erlebnis im Roblox Avatar Creator Demo testen.

So implementieren Sie die Erstellung im Erlebnis

Verwenden Sie die folgenden Anleitungen und Code-Referenzen, um Ihr erstes Avatar-Erstellungsprojekt im Erlebnis zu erstellen. Die folgenden Anweisungen verwenden einen Basis Körper Model, den die Spieler ändern und anpassen können, bevor sie ihn veröffentlichen.

Bevor Sie beginnen, machen Sie sich mit Folgendem vertraut:

  • Avatar-Modelle — Die folgende Implementierung erfordert das Importieren eines Basis Körpers, der den Roblox-Spezifikationen für 15 Teile entspricht. Dieses Model dient als Grundlage für zusätzliche Benutzeranpassungen und -änderungen.
    • Der Basis Körper muss den Richtlinien für Avatar-Körper von Roblox entsprechen, einschließlich der minimalen Anzahl von FACS-Steuerelementen für die Gesichtsrigging.
  • Avatar-Erstellungstoken — Erlebnisse, die die Avatar-Erstellung implementieren, erfordern mindestens ein Erstellungstoken. Diese Tokens erfordern Robux zur Durchführung des Kaufs und ermöglichen es Ihnen, Preise und andere Verkaufseinstellungen für Käufe, die im Erlebnis getätigt werden, festzulegen.
  • API-Klassen
    • AvatarCreationService — Verwaltet die Aufforderung zur Avatar-Erstellung und die Validierung.
    • EditableImage — Verwaltet die Erstellung und Manipulation von Texturen zur Laufzeit.
    • EditableMesh — Verwaltet die Manipulation der Mesh-Geometrie zur Laufzeit.
    • WrapDeformer — Verwaltet die Manipulation der unsichtbaren äußeren Käfiggeometrie zur Laufzeit, die es Avatar-Charakteren ermöglicht, 3D-Kleidung auszurüsten.

Ein Basis Körper importieren

Der Basis Körper dient als erste 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 müssen Komponenten wie die 15 MeshPart-Instanzen, die aus 6 Körperteilen bestehen: Kopf, Torso, linker Arm, linkes Bein, rechter Arm und rechtes Bein, sowie andere Avatarkomponenten enthalten.

Für Referenzen und Beispiele von richtig konfigurierten Avatarkörpern siehe Avatar-Referenzen.

Implementierung von Bearbeitungs-APIs

Um ein System zu entwickeln, in dem Benutzer die MeshPart-Instanzen eines Avatars in Ihrem Erlebnis zur Erstellung bearbeiten können, verwenden Sie EditableImage für die Texturbearbeitung, EditableMesh für die Mesh-Bearbeitung und WrapDeformer, um das Skinning und die FACS-Daten während der Mesh-Änderungen aufrechtzuerhalten.

  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 die MeshPart
    local wrapDeformer = Instance.new("WrapDeformer")
    wrapDeformer.Parent = meshPart
    -- Erstellen eines bearbeitbaren Meshs für das Käfig-Mesh des Wrap-Ziels
    local cageEditableMesh: EditableMesh =
    AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {
    FixedSize = true,
    })
    -- Zuweisen des Käfig-Meshs an den WrapDeformer
    wrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))
    end
    local function setupRigidMesh(meshPart)
    -- Erstellen eines bearbeitbaren Meshs aus der ursprünglichen MeshPart
    local editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {
    FixedSize = true,
    })
    -- Erstellen einer neuen MeshPart aus dem bearbeitbaren Mesh
    local newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))
    -- Kopieren von Größe, Position und Textur von der ursprünglichen MeshPart
    newMeshPart.Size = meshPart.Size
    newMeshPart.CFrame = meshPart.CFrame
    newMeshPart.TextureContent = meshPart.TextureContent
    -- Anwenden der neuen MeshPart auf die ursprüngliche
    meshPart:ApplyMesh(newMeshPart)
    end
    local function setupMeshTexture(meshPart, textureIdToEditableImageMap)
    -- Wenn bereits ein EditableImage für diesen TextureID existiert, verwenden Sie es erneut, anstatt ein neues zu erstellen
    if textureIdToEditableImageMap[meshPart.TextureID] then
    meshPart.TextureContent =
    Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])
    return
    end
    -- Erstellen eines neuen EditableImage und Anwenden es als Texturinhalt
    local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))
    textureIdToEditableImageMap[meshPart.TextureID] = editableImage
    meshPart.TextureContent = Content.fromObject(editableImage)
    end
    local function setupModel(model)
    -- Map für die Wiederverwendung von EditableImage-Instanzen durch Textur-ID
    local textureIdToEditableImageMap = {}
    for _, descendant in model:GetDescendants() do
    if not descendant:IsA("MeshPart") then
    continue
    end
    -- Konfigurieren der MeshPart basierend auf der WrapTarget-Präsenz
    -- Wenn WrapTarget vorhanden ist, fügen Sie ein WrapDeformer-Kind mit einem EditableMesh hinzu
    -- Andernfalls wenden Sie EditableMesh direkt auf die MeshPart an
    local wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")
    if wrapTarget then
    setupBodyPart(descendant, wrapTarget)
    else
    setupRigidMesh(descendant)
    end
    -- Konfigurieren des EditableImage für die MeshPart
    setupMeshTexture(descendant, textureIdToEditableImageMap)
    end
    end
  2. Erstellen Sie EditableImage-Tools, die Spielern ermöglichen, Ihre Basis Körper neu zu färben, zu zeichnen oder Aufkleber hinzuzufügen. Sie können APIs wie DrawImage(), DrawRectangle(), WritePixelsBuffer() nutzen.

    • Für erweiterte Transformationen ermöglicht DrawImageTransformed(), dass Sie Position, Rotation und Maßstab angeben, wenn Sie ein EditableImage auf ein anderes zeichnen. Ebenso funktioniert DrawImageProjected() ähnlich wie DrawImage(), projiziert das gezeichnete Bild jedoch korrekt, wenn die EditableImage-Instanz mit einer 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 für die Bearbeitung von Mesh-Verformungen an Ihrem Körper zu erstellen.

    1. WrapDeformer verwaltet die Live-Verformungen der gerenderten MeshPart-Geometrie und hält die zugrunde liegenden Skinning- und FACS-Daten aufrecht.

    2. EditableMesh ermöglicht es Ihnen, das Käfigmesh 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 Scheitelpunkte zu verformen und die Form der 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

Erstellung einer Aufforderung zur Erstellung

Nachdem Sie Ihren Basis Körper und die Bearbeitungs-APIs eingerichtet haben, erstellen Sie eine Aufforderung für Benutzer, die aus dem Erlebnis erstellen und kaufen können, 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("Unbeabsichtigt hochgeladen mit Fehlermeldung:", bundleIdOrErrorMessage)
end
else
print("Avatar-Erstellung nicht erfolgreich")
end
end

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

Die bereitgestellte HumanoidDescription sollte keine vorhandenen Asset-IDs enthalten, um Körperteile oder Zubehör auf der beabsichtigten Erstellung 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, den Skalen entsprechen, die der HumanoidDescription bereitgestellt werden.

Zubehör einfügen

Wenn ein Zubehör wie Haare eingefügt wird, sollte die HumanoidDescription ein Kind AccessoryDescription enthalten, wo:

Generieren Sie ein Avatar-Erstellungstoken

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

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

Auf Spieler, die über Attribution beitreten, reagieren

Avatar-Bundles, die im Erlebnis erstellt wurden, enthalten einen Attribution-Link zu dem ursprünglichen Erlebnis, in dem der Avatar erstellt wurde. Wenn der Avatar von einem anderen Spieler inspiziert wird, wird eine Aufforderung angezeigt, die die Möglichkeit bietet, das Erlebnis zu besuchen, in dem der Avatar erstellt wurde.

Um Spieler, die Ihrem Erlebnis über diesen Attribution-Link beitreten, zu behandeln, verwenden Sie Player:GetJoinData() und analysieren Sie die zurückgegebene Tabelle nach GameJoinContext.

GameJoinContext umfasst 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.