简体   繁体   中英

Keep Web API Player on Login and change Scene in Unity. (ASP.NET Web API - Unity)

I want to keep my Player when I Load a new Scene when he has loged in at my Web API.

code:

Client

Login Script

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class Login : MonoBehaviour
{
    public TMP_InputField emailInputField;
    public TMP_InputField passwordInputField;
    public Button loginButton;

    public Text popup;

    private string httpServerAddress = "myadress";

    public Player player;

    private void Start()
    {
        player = FindObjectOfType<Player>();
    }

    public void OnLoginButtonClicked()
    {
        if (string.IsNullOrEmpty(emailInputField.text))
        {
            popup.text = "Email can't be void";

        }
        else if (string.IsNullOrEmpty(passwordInputField.text))
        {
            popup.text = "Password can't be void";

        }
        else
        {
            StartCoroutine(TryLogin());

        }
        
    }

    private IEnumerator TryLogin()
    {
        yield return InitializeToken(emailInputField.text, passwordInputField.text);
        yield return GetPlayerInfo();

        SceneManager.LoadScene("MainScene");
    }


    IEnumerator InitializeToken(string email, string password)
    {
        Player player = FindObjectOfType<Player>();
        if (string.IsNullOrEmpty(player.Token))
        {
            UnityWebRequest httpClient = new UnityWebRequest(httpServerAddress + "Token", "POST");

            
            WWWForm dataToSend = new WWWForm();
            dataToSend.AddField("grant_type", "password");
            dataToSend.AddField("username", email);
            dataToSend.AddField("password", password);

            httpClient.uploadHandler = new UploadHandlerRaw(dataToSend.data);
            httpClient.downloadHandler = new DownloadHandlerBuffer();

            httpClient.SetRequestHeader("Accept", "application/json");

            yield return httpClient.SendWebRequest();

            if (httpClient.isNetworkError || httpClient.isHttpError)
            {
                throw new Exception("Helper > InitToken: " + httpClient.error);
            }
            else
            {
                string jsonResponse = httpClient.downloadHandler.text;
                AuthorizationToken authToken = JsonUtility.FromJson<AuthorizationToken>(jsonResponse);
                player.Token = authToken.access_token;
            }
            httpClient.Dispose();
        }
    }

    IEnumerator GetPlayerInfo()
    {
        Player player = FindObjectOfType<Player>();
        UnityWebRequest httpClient = new UnityWebRequest(httpServerAddress + "api/Player/Info", "GET");

        httpClient.SetRequestHeader("Authorization", "bearer " + player.Token);
        httpClient.SetRequestHeader("Accept", "application/json");

        httpClient.downloadHandler = new DownloadHandlerBuffer();

        yield return httpClient.SendWebRequest();

        if (httpClient.isNetworkError || httpClient.isHttpError)
        {
            throw new Exception("Helper > GetPlayerInfo: " + httpClient.error);
        }
        else
        {
            PlayerSerializable playerSerializable = JsonUtility.FromJson<PlayerSerializable>(httpClient.downloadHandler.text);
            player.Id = playerSerializable.Id;
            player.Nickname = playerSerializable.Nickname;
        }

        httpClient.Dispose();
    }

    
}

Player Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    private string _token;
    public string Token
    {
        get { return _token; }
        set { _token = value; }
    }

    private string _id;
    public string Id
    {
        get { return _id; }
        set { _id = value; }
    }

    private string _nickname;
    public string Nickname
    {
        get { return _nickname; }
        set { _nickname = value; }
    }
}

PlayerSerializable Script

using System;

[Serializable]
public class PlayerSerializable
{
    public string Id;
    public string Nickname;
}

AuthorizationToken Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class AuthorizationToken
{
    public string access_token;
    public string token_type;
}

Web API

PlayerController Script

        // GET api/Player/Info
        [HttpGet]
        [Route("Info")]
        public Models.PlayerModel GetPlayerInfo()
        {
            string authenticatedAspNetUserId = RequestContext.Principal.Identity.GetUserId();
            using (IDbConnection cnn = new ApplicationDbContext().Database.Connection)
            {
                string sql = $"SELECT Id, Nickname FROM dbo.Players " +
                    $"WHERE Id LIKE '{authenticatedAspNetUserId}'";
                var player = cnn.Query<Models.PlayerModel>(sql).FirstOrDefault();
                return player;
            }
        }

I think that this can be a solution, DontDestroyOnLoad Script and a GameManager Script on the Client:

DontDestroyOnLoad Script, assigned to the Player GameObject on the Login Scene

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DontDestroyOnLoad : MonoBehaviour
{
    void Awake()
    {
        int count = FindObjectsOfType<DontDestroyOnLoad>().Length;
        if (count > 1)
        {
            Destroy(gameObject);
        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }
}

GameManager Script, assigned to a Game Manager Game Object in the Main Scene

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    public Text playerNameText;

    public Player player;

    void Start()
    {
        player = FindObjectOfType<Player>();
        playerNameText.text = player.Nickname;
    }

}

You need to use DontDestroyOnLoad() for the GameObject so this should be in the Start/Awake of the Player. https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html

Or you move the GameObject from the old Scene to the new Scene SceneManager.MoveGameObjectToScene() . This should be in a Manager which handels the Scenes. https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.MoveGameObjectToScene.html

Here how the DontDestroyOnLoad could look like for your Player:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    private string _token;
    public string Token { get => this._token; set => this._token = value; }

    private string _id;
    public string Id { get => this._id; set => this._id = value; }


    private string _nickname;
    public string Nickname{ get => this._nickname; set => this._nickname = value; }
    
    void Awake()
    {
        DontDestroyOnLoad(this.gameObject);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM