> ## 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.

# Inicio rápido de entidades

> Introducción a las entidades de PlayFab en C# para Unity: autentíquese para obtener una EntityKey y, a continuación, lea y escriba objetos de entidad y archivos de entidad con ejemplos del SDK.

En este inicio rápido de entidades se muestra cómo trabajar con objetos de entidad y archivos de entidad.

Para obtener información sobre la migración de los sistemas heredados de cuentas y datos a las entidades de PlayFab, consulte [Información de migración de entidades](/services/playfab/live-service-management/game-configuration/entities/migration-information).

## Requisitos

* Una [cuenta de desarrollador de PlayFab](https://developer.playfab.com).
* Una copia instalada del editor de Unity. Para obtener información sobre cómo instalar el editor de Unity, consulte [Installing Unity](https://docs.unity3d.com/Manual/GettingStartedInstallingUnity.html) en la documentación de Unity. También puede instalar una versión de Unity mediante el instalador de características de Visual Studio.

<Note>
  El SDK de Unity3D de PlayFab admite el editor de Unity versión 5.3 y posteriores.
</Note>

* Un proyecto de Unity. Para obtener información sobre cómo crear un proyecto de Unity, consulte [la guía de inicio rápido](https://docs.unity3d.com/Manual/Quickstart3D.html).

<Note>
  Si no está familiarizado con Unity, los paquetes de instalación recientes le ofrecen la opción de instalar tutoriales de creación de juegos. Puede usar uno de los tutoriales para crear un juego de ejemplo que utilizar en el siguiente inicio rápido.
</Note>

* El SDK de Unity3D de PlayFab.

Los ejemplos de C# de este artículo están escritos para el SDK de Unity. El SDK de Unity usa un modelo controlado por eventos para gestionar las tareas no sincrónicas. Para ejecutar el código de ejemplo con el SDK de C#, debe modificar el código para usar un modelo asincrónico de tareas (async Task). Los métodos que deben modificarse tienen Async anexado al nombre del método en la firma. Por ejemplo, SetObject en el SDK de Unity se convierte en SetObjectAsync en el SDK de C#. Para obtener más información, consulte [Programación asincrónica con async y await](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/).

## Terminología

Las entidades son cualquier concepto de PlayFab que puede contener datos. Los tipos de entidad integrados son:

* **title**: un título contiene información global disponible para todos los jugadores. Es similar a [TitleData](xref:titleid.playfabapi.com.client.title-widedatamanagement.gettitledata). Se identifica mediante el identificador de título (`TitleId`) del juego o la aplicación.
* **master\_player\_account**: este tipo de entidad le permite compartir información sobre un jugador entre varios juegos dentro de un espacio de nombres. Se identifica mediante el identificador de jugador (`PlayFabId`) del jugador, que se devuelve como parte de cualquier inicio de sesión o de cualquier llamada para recuperar la información de cuenta de la cuenta de jugador (por ejemplo, la API de cliente de PlayFab [GetAccountInfo](xref:titleid.playfabapi.com.client.accountmanagement.getaccountinfo)).
* **title\_player\_account**: identifica una cuenta de jugador que contiene cierta información para el título actual. Se identifica mediante el identificador de entidad (`EntityKey.Id`) que se obtiene en el objeto [EntityKey](xref:titleid.playfabapi.com.authentication.authentication.getentitytoken#entitykey) en cualquier inicio de sesión.
* **character**: identifica un personaje que posee el jugador y que contiene información que puede recuperar. Se identifica mediante el identificador de personaje (`CharacterId`) del personaje.

Para obtener más información sobre los tipos de entidad integrados, consulte [Tipos de entidad integrados disponibles](/services/playfab/live-service-management/game-configuration/entities/available-built-in-entity-types).

## Inicialización de entidades

Para llamar a cualquiera de las API de entidad, debe obtener el `ID` de entidad y el `Type` de entidad. Use el `ID` y el `Type` para realizar llamadas a otros métodos de la API de entidad. Estos son miembros de un objeto [EntityKey](xref:titleid.playfabapi.com.authentication.authentication.getentitytoken#entitykey).

Para ello, llame a cualquiera de los métodos de inicio de sesión, 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;
    }
```

También puede obtener el `ID` de entidad y el `Type` de entidad llamando al 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
```

Cuando se llama desde el cliente, esto normalmente representa al jugador que ha iniciado sesión. Cuando se llama desde servidores de juego, representa a su título.

## Objetos de entidad

Los objetos de entidad le permiten leer y escribir objetos pequeños serializables en JSON adjuntos a una entidad. Todos los tipos de entidad admiten los métodos `GetObjects` y `SetObjects`.

Los fragmentos de código siguientes muestran cómo establecer y leer un `Object` en una entidad `title_player_account`.

Use el método [SetObjects](xref:titleid.playfabapi.com.data.object.setobjects) para establecer objetos de entidad en un jugador o un 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 el método [GetObjects](xref:titleid.playfabapi.com.data.object.getobjects) para recuperar objetos de entidad de un jugador o un 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
);
```

## Archivos de entidad

Los archivos de entidad le permiten leer y escribir archivos adjuntos a una entidad, en cualquier formato.

Use el método [GetFiles](xref:titleid.playfabapi.com.data.file.getfiles) para recuperar archivos de entidad.

```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 el método [initiatefileuploads](xref:titleid.playfabapi.com.data.file.initiatefileuploads) para iniciar una carga de archivo en el perfil de una entidad.

```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 el método [AbortFileUploads](xref:titleid.playfabapi.com.data.file.abortfileuploads) para anular una carga de archivo pendiente en el perfil de una entidad.

```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 el método [FinalizeFileUploads](xref:titleid.playfabapi.com.data.file.finalizefileuploads) para finalizar las cargas de archivos en el perfil de una entidad. El sistema de entidades no considera que la carga del archivo esté completa, ni refleja ningún cambio a otros autores de llamadas, hasta que la operación de carga atómica se finaliza correctamente.

```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
    }
```

El ejemplo que se muestra a continuación demuestra un bucle completo de archivos de entidad, desde el inicio de sesión hasta la carga de un archivo y la subida de un archivo nuevo.

Los pasos son:

* Iniciar sesión y recuperar el `ID` de entidad y el `Type` de entidad.
* Inicializar la operación de carga atómica.
* Cargar todos los archivos.
* Finalizar la operación de carga atómica.

Para simplificar, este ejemplo guarda un archivo a la vez, pero los archivos se pueden cargar de forma atómica en conjuntos.

El ejemplo asume que está familiarizado con el uso del motor 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 acción de archivo requiere muchos pasos y varias llamadas a la API, por lo que no intente acceder al mismo archivo de varias maneras al mismo tiempo. Si tiene mucho cuidado, es posible que no necesite un mecanismo de bloqueo. Si quiere hacer algo complicado, su mecanismo de bloqueo puede ser mucho más complejo.
</Note>

## Game Manager y entidades

Game Manager le permite manipular objetos y archivos de los jugadores. La información general del jugador muestra tanto la información del jugador del título como la de la cuenta de jugador maestra.

<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 - Información general del jugador" width="1800" height="1406" data-path="images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-overview.png" />

Además, los archivos y los objetos ahora tienen sus propias secciones en la pestaña **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 - Archivos y objetos del jugador" width="1800" height="969" data-path="images/playfab/live-service-management/game-configuration/entities/tutorials/game-manager-entities-player-files.png" />

## Consulte también

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


## Related topics

- [Inicio rápido de tablas de clasificación](/es/services/playfab/community/leaderboards/quickstart-leaderboards.md)
- [Información de migración de entidades](/es/services/playfab/live-service-management/game-configuration/entities/migration-information.md)
- [Documentación de administración de servicios en vivo de PlayFab](/es/services/playfab/live-service-management/index.md)
- [Inicio rápido de propiedades personalizadas de jugador](/es/services/playfab/live-service-management/game-configuration/segmentation/player-custom-properties-qs.md)
- [Inicio rápido de contenido generado por el usuario (UGC)](/es/services/playfab/economy-monetization/economy-v2/ugc/quickstart.md)
