> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Início rápido de entidades

> Comece a usar entidades do PlayFab em C# no Unity: autentique-se para obter uma EntityKey e, em seguida, leia e grave objetos e arquivos de entidade com exemplos do SDK.

Este início rápido de entidades demonstra como trabalhar com objetos de entidade e arquivos de entidade.

Para obter informações sobre como migrar dos sistemas legados de conta e de dados para entidades do PlayFab, consulte [Informações de migração de entidades](/pt-BR/services/playfab/live-service-management/game-configuration/entities/migration-information).

## Requisitos

* Uma [conta de desenvolvedor do PlayFab](https://developer.playfab.com).
* Uma cópia instalada do Unity Editor. Para obter informações sobre como instalar o Unity Editor, consulte [Installing Unity](https://docs.unity3d.com/Manual/GettingStartedInstallingUnity.html) na documentação do Unity. Você também pode instalar uma versão do Unity usando o instalador de recursos do Visual Studio.

<Note>
  O SDK do PlayFab para Unity3D oferece suporte ao Unity Editor versão 5.3 e posteriores.
</Note>

* Um projeto do Unity. Para obter informações sobre como criar um projeto do Unity, consulte [o guia de início rápido](https://docs.unity3d.com/Manual/Quickstart3D.html).

<Note>
  Se você não estiver familiarizado com o Unity, os pacotes de instalação recentes oferecem a opção de instalar tutoriais de criação de jogos. Você pode usar um desses tutoriais para criar um jogo de exemplo para usar no início rápido a seguir.
</Note>

* O SDK do PlayFab para Unity3D.

Os exemplos em C# deste artigo foram escritos para o SDK do Unity. O SDK do Unity usa um modelo orientado a eventos para lidar com tarefas não síncronas. Para executar o código de exemplo usando o SDK do C#, você deve modificar o código para usar um modelo de Task assíncrono. Os métodos que precisam ser modificados têm Async acrescentado ao nome do método na assinatura. Por exemplo, SetObject no SDK do Unity se torna SetObjectAsync no SDK do C#. Para obter mais informações, consulte [Programação assíncrona com async e await](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/).

## Terminologia

Entidades são qualquer conceito do PlayFab que possa conter dados. Os tipos de entidade internos são:

* **title**: um título contém informações globais disponíveis para todos os jogadores. Isso é semelhante a [TitleData](xref:titleid.playfabapi.com.client.title-widedatamanagement.gettitledata). Ele é identificado pela ID de título (`TitleId`) do jogo/aplicativo.
* **master\_player\_account**: esse tipo de entidade permite compartilhar informações sobre um jogador entre vários jogos de um namespace. Ele é identificado pela ID do jogador (`PlayFabId`), que é retornada como parte de qualquer login ou de qualquer chamada para obter informações da conta do jogador (por exemplo, [GetAccountInfo](xref:titleid.playfabapi.com.client.accountmanagement.getaccountinfo) da PlayFab Client API).
* **title\_player\_account**: identifica uma conta de jogador que contém algumas informações para o título atual. Ele é identificado pela ID de entidade (`EntityKey.Id`) que você recebe no objeto [EntityKey](xref:titleid.playfabapi.com.authentication.authentication.getentitytoken#entitykey) em qualquer login.
* **character**: identifica um personagem do jogador que contém informações que você pode recuperar. Ele é identificado pela ID do personagem (`CharacterId`).

Para obter mais informações sobre os tipos de entidade internos, consulte [Tipos de entidade internos disponíveis](/pt-BR/services/playfab/live-service-management/game-configuration/entities/available-built-in-entity-types).

## Inicialização da entidade

Para chamar qualquer uma das APIs de entidade, você deve obter a `ID` e o `Type` da entidade. Você usa a `ID` e o `Type` para fazer chamadas a outros métodos da API de entidade. Eles são membros de um objeto [EntityKey](xref:titleid.playfabapi.com.authentication.authentication.getentitytoken#entitykey).

Para isso, chame qualquer um dos métodos de login, como `LoginWithCustomID`.

```csharp theme={null}
    void Login()
    {
        var request = new PlayFab.ClientModels.LoginWithCustomIDRequest
        {
            CustomId = SystemInfo.deviceUniqueIdentifier,
            CreateAccount = true,
        };
        PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure);
    }

    void OnLogin(PlayFab.ClientModels.LoginResult result)
    {
        entityId = result.EntityToken.Entity.Id;
        // The expected entity type is title_player_account.
        entityType = result.EntityToken.Entity.Type;
    }
```

Você também pode obter a `ID` e o `Type` da entidade chamando o método [GetEntityToken](xref:titleid.playfabapi.com.authentication.authentication.getentitytoken).

```csharp theme={null}
PlayFabAuthenticationAPI.GetEntityToken(new GetEntityTokenRequest(),
(entityResult) =>
{
    var entityId = entityResult.Entity.Id;
    var entityType = entityResult.Entity.Type;
}, OnPlayFabError); // Define your own OnPlayFabError function to report errors
```

Quando chamado do cliente, normalmente representa o jogador conectado. Quando chamado de servidores de jogo, representa seu título.

## Objetos de entidade

Os objetos de entidade permitem ler e gravar pequenos objetos serializáveis em JSON anexados a uma entidade. Todos os tipos de entidade oferecem suporte aos métodos `GetObjects` e `SetObjects`.

Os trechos de código a seguir mostram como definir e ler um `Object` em uma entidade `title_player_account`.

Use o método [SetObjects](xref:titleid.playfabapi.com.data.object.setobjects) para definir objetos de entidade em um jogador ou título.

```csharp theme={null}
var data = new Dictionary<string, object>()
{
    {"Health", 100},
    {"Mana", 10000}
};
var dataList = new List<SetObject>()
{
    new SetObject()
    {
        ObjectName = "PlayerData",
        DataObject = data
    },
    // A free-tier customer may store up to 3 objects on each entity
};

PlayFabDataAPI.SetObjects(new SetObjectsRequest()
{
    Entity = new EntityKey {Id = entityId, Type = entityType}, // Saved from GetEntityToken, or a specified key created from a titlePlayerId, CharacterId, etc
    Objects = dataList,
}, (setResult) => {
    Debug.Log(setResult.ProfileVersion);
}, OnPlayFabError);
```

Use o método [GetObjects](xref:titleid.playfabapi.com.data.object.getobjects) para recuperar objetos de entidade de um jogador ou título.

```csharp theme={null}
var getRequest = new GetObjectsRequest {Entity = new EntityKey {Id = entityId, Type = entityType}};
PlayFabDataAPI.GetObjects(getRequest,
    result => { var objs = result.Objects; },
    OnPlayFabError
);
```

## Arquivos de entidade

Os arquivos de entidade permitem ler e gravar arquivos anexados a uma entidade, em qualquer formato.

Use o método [GetFiles](xref:titleid.playfabapi.com.data.file.getfiles) para recuperar arquivos de entidade.

```csharp theme={null}
    void LoadAllFiles()
    {
        if (GlobalFileLock != 0)
            throw new Exception("This example overly restricts file operations for safety. Careful consideration must be made when doing multiple file operations in parallel to avoid conflict.");

        GlobalFileLock += 1; // Start GetFiles
        var request = new PlayFab.DataModels.GetFilesRequest { Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType } };
        PlayFabDataAPI.GetFiles(request, OnGetFileMeta, OnSharedFailure);
    }
```

Use o método [initiatefileuploads](xref:titleid.playfabapi.com.data.file.initiatefileuploads) para iniciar o upload de um arquivo para o perfil de uma entidade.

```csharp theme={null}
    void UploadFile(string fileName)
    {
        if (GlobalFileLock != 0)
            throw new Exception("This example overly restricts file operations for safety. Careful consideration must be made when doing multiple file operations in parallel to avoid conflict.");

        ActiveUploadFileName = fileName;

        GlobalFileLock += 1; // Start InitiateFileUploads
        var request = new PlayFab.DataModels.InitiateFileUploadsRequest
        {
            Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
            FileNames = new List<string> { ActiveUploadFileName },
        };
        PlayFabDataAPI.InitiateFileUploads(request, OnInitFileUpload, OnInitFailed);
    }
```

Use o método [AbortFileUploads](xref:titleid.playfabapi.com.data.file.abortfileuploads) para anular um upload de arquivo pendente para o perfil de uma entidade.

```csharp theme={null}
    void OnInitFailed(PlayFabError error)
    {
        if (error.Error == PlayFabErrorCode.EntityFileOperationPending)
        {
            // This is an error you should handle when calling InitiateFileUploads, but your resolution path may vary
            GlobalFileLock += 1; // Start AbortFileUploads
            var request = new PlayFab.DataModels.AbortFileUploadsRequest
            {
                Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
                FileNames = new List<string> { ActiveUploadFileName },
            };
            PlayFabDataAPI.AbortFileUploads(request, (result) => { GlobalFileLock -= 1; UploadFile(ActiveUploadFileName); }, OnSharedFailure); GlobalFileLock -= 1; // Finish AbortFileUploads
            GlobalFileLock -= 1; // Failed InitiateFileUploads
        }
        else
            OnSharedFailure(error);
    }
```

Use o método [FinalizeFileUploads](xref:titleid.playfabapi.com.data.file.finalizefileuploads) para finalizar uploads de arquivos para o perfil de uma entidade. O sistema de entidades não considera o upload do arquivo concluído nem reflete alterações para outros chamadores até que a operação de upload atômica seja finalizada com êxito.

```csharp theme={null}
    void FinalizeUpload(byte[] data)
    {
        GlobalFileLock += 1; // Start FinalizeFileUploads
        var request = new PlayFab.DataModels.FinalizeFileUploadsRequest
        {
            Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
            FileNames = new List<string> { ActiveUploadFileName },
        };
        PlayFabDataAPI.FinalizeFileUploads(request, OnUploadSuccess, OnSharedFailure);
        GlobalFileLock -= 1; // Finish SimplePutCall
    }
```

O exemplo mostrado abaixo demonstra um loop completo de arquivos de entidade, desde o login até o carregamento de um arquivo e o upload de um novo arquivo.

As etapas são:

* Fazer login e obter a `ID` e o `Type` da entidade.
* Inicializar a operação de upload atômica.
* Fazer upload de todos os arquivos.
* Finalizar a operação de upload atômica.

Para simplificar, este exemplo salva um arquivo por vez, mas os arquivos podem ser enviados atomicamente em conjuntos.

O exemplo pressupõe que você esteja familiarizado com o uso do mecanismo Unity 3D.

```csharp theme={null}
#if !DISABLE_PLAYFABENTITY_API && !DISABLE_PLAYFABCLIENT_API

using PlayFab;
using PlayFab.Internal;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class EntityFileExample : MonoBehaviour
{
    public string entityId; // Id representing the logged in player
    public string entityType; // entityType representing the logged in player
    private readonly Dictionary<string, string> _entityFileJson = new Dictionary<string, string>();
    private readonly Dictionary<string, string> _tempUpdates = new Dictionary<string, string>();
    public string ActiveUploadFileName;
    public string NewFileName;
    // GlobalFileLock provides is a simplistic way to avoid file collisions, specifically designed for this example.
    public int GlobalFileLock = 0;

    void OnSharedFailure(PlayFabError error)
    {
        Debug.LogError(error.GenerateErrorReport());
        GlobalFileLock -= 1;
    }

    // OnGUI provides a way to build a Unity GUI entirely within script.
    // Your GUI will be game-specific.
    void OnGUI()
    {
        if (!PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(0, 0, 100, 30), "Login"))
            Login();
        if (PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(0, 0, 100, 30), "LogOut"))
            PlayFabClientAPI.ForgetAllCredentials();

        if (PlayFabClientAPI.IsClientLoggedIn() && GUI.Button(new Rect(100, 0, 100, 30), "(re)Load Files"))
            LoadAllFiles();

        if (PlayFabClientAPI.IsClientLoggedIn())
        {
            // Display existing files
            _tempUpdates.Clear();
            var index = 0;
            foreach (var each in _entityFileJson)
            {
                GUI.Label(new Rect(100 * index, 60, 100, 30), each.Key);
                var tempInput = _entityFileJson[each.Key];
                var tempOutput = GUI.TextField(new Rect(100 * index, 90, 100, 30), tempInput);
                if (tempInput != tempOutput)
                    _tempUpdates[each.Key] = tempOutput;
                if (GUI.Button(new Rect(100 * index, 120, 100, 30), "Save " + each.Key))
                    UploadFile(each.Key);
                index++;
            }
            // Apply any changes
            foreach (var each in _tempUpdates)
                _entityFileJson[each.Key] = each.Value;

            // Add a new file
            NewFileName = GUI.TextField(new Rect(100 * index, 60, 100, 30), NewFileName);
            if (GUI.Button(new Rect(100 * index, 90, 100, 60), "Create " + NewFileName))
                UploadFile(NewFileName);
        }
    }

    void Login()
    {
        var request = new PlayFab.ClientModels.LoginWithCustomIDRequest
        {
            CustomId = SystemInfo.deviceUniqueIdentifier,
            CreateAccount = true,
        };
        PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure);
    }

    void OnLogin(PlayFab.ClientModels.LoginResult result)
    {
        entityId = result.EntityToken.Entity.Id;
        entityType = result.EntityToken.Entity.Type;
    }

    void LoadAllFiles()
    {
        if (GlobalFileLock != 0)
            throw new Exception("This example overly restricts file operations for safety. Careful consideration must be made when doing multiple file operations in parallel to avoid conflict.");

        GlobalFileLock += 1; // Start GetFiles
        var request = new PlayFab.DataModels.GetFilesRequest { Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType } };
        PlayFabDataAPI.GetFiles(request, OnGetFileMeta, OnSharedFailure);
    }

    void OnGetFileMeta(PlayFab.DataModels.GetFilesResponse result)
    {
        Debug.Log("Loading " + result.Metadata.Count + " files");

        _entityFileJson.Clear();
        foreach (var eachFilePair in result.Metadata)
        {
            _entityFileJson.Add(eachFilePair.Key, null);
            GetActualFile(eachFilePair.Value);
        }
        GlobalFileLock -= 1; // Finish GetFiles
    }

    void GetActualFile(PlayFab.DataModels.GetFileMetadata fileData)
    {
        GlobalFileLock += 1; // Start Each SimpleGetCall
        PlayFabHttp.SimpleGetCall(fileData.DownloadUrl,
            result => { _entityFileJson[fileData.FileName] = Encoding.UTF8.GetString(result); GlobalFileLock -= 1; }, // Finish Each SimpleGetCall
            error => { Debug.Log(error); }
        );
    }

    void UploadFile(string fileName)
    {
        if (GlobalFileLock != 0)
            throw new Exception("This example overly restricts file operations for safety. Careful consideration must be made when doing multiple file operations in parallel to avoid conflict.");

        ActiveUploadFileName = fileName;

        GlobalFileLock += 1; // Start InitiateFileUploads
        var request = new PlayFab.DataModels.InitiateFileUploadsRequest
        {
            Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
            FileNames = new List<string> { ActiveUploadFileName },
        };
        PlayFabDataAPI.InitiateFileUploads(request, OnInitFileUpload, OnInitFailed);
    }

    void OnInitFailed(PlayFabError error)
    {
        if (error.Error == PlayFabErrorCode.EntityFileOperationPending)
        {
            // This is an error you should handle when calling InitiateFileUploads, but your resolution path may vary
            GlobalFileLock += 1; // Start AbortFileUploads
            var request = new PlayFab.DataModels.AbortFileUploadsRequest
            {
                Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
                FileNames = new List<string> { ActiveUploadFileName },
            };
            PlayFabDataAPI.AbortFileUploads(request, (result) => { GlobalFileLock -= 1; UploadFile(ActiveUploadFileName); }, OnSharedFailure); GlobalFileLock -= 1; // Finish AbortFileUploads
            GlobalFileLock -= 1; // Failed InitiateFileUploads
        }
        else
            OnSharedFailure(error);
    }

    void OnInitFileUpload(PlayFab.DataModels.InitiateFileUploadsResponse response)
    {
        string payloadStr;
        if (!_entityFileJson.TryGetValue(ActiveUploadFileName, out payloadStr))
            payloadStr = "{}";
        var payload = Encoding.UTF8.GetBytes(payloadStr);

        GlobalFileLock += 1; // Start SimplePutCall
        PlayFabHttp.SimplePutCall(response.UploadDetails[0].UploadUrl,
            payload,
            FinalizeUpload,
            error => { Debug.Log(error); }
        );
        GlobalFileLock -= 1; // Finish InitiateFileUploads
    }

    void FinalizeUpload(byte[] data)
    {
        GlobalFileLock += 1; // Start FinalizeFileUploads
        var request = new PlayFab.DataModels.FinalizeFileUploadsRequest
        {
            Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
            FileNames = new List<string> { ActiveUploadFileName },
        };
        PlayFabDataAPI.FinalizeFileUploads(request, OnUploadSuccess, OnSharedFailure);
        GlobalFileLock -= 1; // Finish SimplePutCall
    }
    void OnUploadSuccess(PlayFab.DataModels.FinalizeFileUploadsResponse result)
    {
        Debug.Log("File upload success: " + ActiveUploadFileName);
        GlobalFileLock -= 1; // Finish FinalizeFileUploads
    }
}
#endif
```

<Note>
  Cada ação de arquivo exige muitas etapas e várias chamadas de API, portanto não tente acessar o mesmo arquivo de várias formas ao mesmo tempo. Se você for muito cuidadoso, talvez não precise de um mecanismo de bloqueio. Se quiser fazer algo complicado, seu mecanismo de bloqueio poderá ser muito mais complexo.
</Note>

## Game Manager e entidades

O Game Manager permite manipular objetos e arquivos de jogadores. A visão geral do jogador mostra as informações tanto do jogador do título quanto da conta mestre do jogador.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-overview.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=ceac36d3b1e7fd248caeedbf4bea8055" alt="Game Manager: Entidades: visão geral do jogador" width="1800" height="1406" data-path="images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-overview.png" />

Além disso, arquivos e objetos agora têm suas próprias seções na guia **Players**.

<img src="https://mintcdn.com/microsoft-4404708b/3hg2JQs0m7qmDqay/images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-files.png?fit=max&auto=format&n=3hg2JQs0m7qmDqay&q=85&s=70b96669460d8bb673ec25fdbcd1bd41" alt="Game Manager: Entidades: arquivos e objetos do jogador" width="1800" height="969" data-path="images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-files.png" />

## Confira também

[Introducing Entities, Objects and Files](https://blog.playfab.com/blog/introducing-entities-objects-and-files) no blog do PlayFab.


## Related topics

- [Início rápido das tabelas de classificação](/pt-BR/services/playfab/community/leaderboards/quickstart-leaderboards.md)
- [Informações de migração de entidades](/pt-BR/services/playfab/live-service-management/game-configuration/entities/migration-information.md)
- [Documentação do gerenciamento de serviços ao vivo do PlayFab](/pt-BR/services/playfab/live-service-management/index.md)
- [Início rápido de estatísticas](/pt-BR/services/playfab/player-progression/statistics/quickstart-statistics.md)
- [Início rápido do SDK de Matchmaking](/pt-BR/services/playfab/multiplayer/matchmaking/quickstart-client-sdk.md)
