본문 바로가기
Unity 공부

Azure PlayFab 회원가입, 로그인

by 개발하는 디토 2022. 11. 18.

 

PlayFab 설치

 

클릭 시 PlayFab 사이트로 이동

 

Azure PlayFab에서 회원 가입 후 Verify Email 해주고 시간대와 언어 변경. Password에 자동으로 비밀번호가 들어가 있을 텐데 비밀번호를 지워야 설정 저장이 된다.

 

API로 가서 PlayFab SDK용 Unity 편집기 확장 다운로드

 

Unity3D(C#) SDK - PlayFab

PlayFab Unity3D(C#) SDK의 방문 페이지입니다.

learn.microsoft.com

 

다운로드 된 패키지 Unity 창 켜진 상태에서 실행 -> Import

 

회원가입하지 말고 로그인, Azure PlayFab에서 회원가입한 이메일, 비밀번호로 로그인

LOG IN 클릭
EMAIL, PASSWORD 입력해 로그인

SDK 없으므로 Install PlayFab SDK 하고 커피 한잔 하면서 기다리기

Install PlayFab SDK

 

SETTINGS - STUDIO를 My Game Studio로 변경하면 Title ID가 알아서 잡힌다.

STUDIO 변경

 

에러 해결

Unity 2020에서는 안 뜨는데 2021에서 뜬다고 함

Assets > PlayFabSDK > Shared > Public > Resources 폴더를 Assets에 들어있게끔 폴더 이동 

Assets > Resources 되게끔 폴더 이동

Play하면 Console창이 깨끗해진다.

 

 

연결 테스트

대충 요래 만들어두고

NetworkManager.cs 작성

로그인 InputField와 회원가입용 InputField 나눠서 작성. 빈 오브젝트에 NetworkManager.cs 연결 후 Inspector에서 필요한 오브젝트 연결.

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

public class NetworkManager : MonoBehaviour
{
    [SerializeField] InputField emailInput, pwInput, emailInputRgst, pwInputRgst, nameInputRgst;
}

아래 사이트로 가서 PlayFabLogin 안에 있는 코드 복사 붙여넣기

 

Unity3D 빠른 시작 - PlayFab

이 가이드는 Unity3D 엔진에서 첫 번째 PlayFab API 호출을 만드는 도움말입니다.

learn.microsoft.com

 

완성하면 대충 아래처럼 된다.

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using PlayFab;
using PlayFab.ClientModels;

public class NetworkManager : MonoBehaviour
{
    [SerializeField] InputField emailInput, pwInput, emailInputRgst, pwInputRgst, nameInputRgst;
    
    public void Start()
    {
        if (string.IsNullOrEmpty(PlayFabSettings.staticSettings.TitleId))
        {
            /*
            Please change the titleId below to your own titleId from PlayFab Game Manager.
            If you have already set the value in the Editor Extensions, this can be skipped.
            */
            PlayFabSettings.staticSettings.TitleId = "42";
        }
        var request = new LoginWithCustomIDRequest { CustomId = "GettingStartedGuide", CreateAccount = true };
        PlayFabClientAPI.LoginWithCustomID(request, OnLoginSuccess, OnLoginFailure);
    }

    private void OnLoginSuccess(LoginResult result)
    {
        Debug.Log("Congratulations, you made your first successful API call!");
    }

    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your first API call.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());
    }

}

 

결과

실행해보면 로그가 뜬다.

성공했다고 뜨면 PlayerFab.com으로 가서 My Game > Build > Players로 들어가 Search를 눌러보자

로그인 기록이 뜬다. (Search 누르기 전까지는 안 뜨니까 버튼을 누르자...ㅋㅋ)

 

이메일로 로그인

참고)

 

Authentication - Login With Email Address - REST API (PlayFab Client)

Signs the user into the PlayFab account, returning a session identifier that can subsequently be used for API calls which require an authenticated user.

learn.microsoft.com

 

테스트 해봤으면 Start문의 이름을 바꿔 일반 함수로 만들고 이메일과 비밀번호로 로그인하기 위해 LoginWithCustomIDRequest -> LoginWithEmailAddressRequest를 사용한다.

스크립트 작성 후 Unity Inspector에서 loginPanel, selectPanel, registerPanel을 등록하고 로그인 버튼, 회원가입 버튼 등에 각각 LoginBtnClick(), RegisterBtnClick() 함수를 연결한다.

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using PlayFab;
using PlayFab.ClientModels;

public class NetworkManager : MonoBehaviour
{
    [SerializeField] InputField emailInput, pwInput, emailInputRgst, pwInputRgst, nameInputRgst;
    public GameObject loginPanel, selectPanel, registerPanel;
    
    public void LoginBtnClick()
    {
        if (string.IsNullOrEmpty(PlayFabSettings.staticSettings.TitleId))
        {
            /*
            Please change the titleId below to your own titleId from PlayFab Game Manager.
            If you have already set the value in the Editor Extensions, this can be skipped.
            */
            PlayFabSettings.staticSettings.TitleId = "42";
        }
        var request = new LoginWithEmailAddressRequest { Email = emailInput.text, Password = pwInput.text };
        PlayFabClientAPI.LoginWithEmailAddress(request, OnLoginSuccess, OnLoginFailure);
    }

    public void RegisterBtnClick()
    {
        // use only email, no username
        var request = new RegisterPlayFabUserRequest { Email = emailInputRgst.text, Password = pwInputRgst.text, RequireBothUsernameAndEmail = false, DisplayName = nameInputRgst.text };
        PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnRegisterFailure);
    }

    private void OnRegisterSuccess(RegisterPlayFabUserResult result)
    {
        // Register Success
        Debug.Log("Register Success!");
        registerPanel.SetActive(false);
        loginPanel.SetActive(true);
    }
    private void OnLoginSuccess(LoginResult result)
    {
        Debug.Log("Congratulations, you made your first successful API call!");
        loginPanel.SetActive(false);
        selectPanel.SetActive(true);
    }
    

    private void OnRegisterFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your registration.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());

        // fail popup 등을 띄울 수 있음
    }
    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your first API call.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());

        // fail popup 등을 띄울 수 있음
    }

}

 

테스트

스크립트 작성 후 Register Panel에서 가상의 이메일과 비밀번호, 닉네임을 입력하고 Register 버튼을 누르면 RegisterBtnClick()이 실행되면서 서버에 사용자가 등록된다. Login Panel에서 등록한 가상의 이메일, 비밀번호를 입력한 뒤 로그인 버튼을 누르면 LogInBtnClick()이 실행되면서 로그인 기능을 수행한다. 성공하면 다음 Panel이 보일 것이다. 

 

 

결과

Console에 로그 찍히는 것 확인.

Memory Leak는 왜 나만 뜨는지 모르겠음...인 줄 알았는데 다른 사람도 찍히더라 ㅎㅎ... 버그인 듯...

 

My Game 대시보드 들어가서 보면 내가 입력한 Nickname을 가진 Player가 생성되어 있을 것이다.

 

 

Photon 연결

Window > Package Manager 클릭 > Packages: My Assets 로 변경 - Pun 검색 - 전부 Import

PUN2를 아직 설치해본 적이 없다면 Unity Asset Store 가서 다운로드할 것!

PUN 2 패키지 Import

 

 

Window > Photon Unity Networking > Highlight Server Settings 클릭

Photon 사이트에서 Pun Id, Chat Id 받아서 복사-붙여넣기

Window > Photon Unity Networking > Highlight Server Settings
Chat, Pun 어플리케이션 하나씩 만들고 어플리케이션 ID 복사해와서 Unity 창에 넣어줌

 

Photon 관련 코드 추가

로그인을 통해 각 클라이언트가 접속하면 자신의 캐릭터를 고른 뒤 게임 scene에 접속할 수 있게 한다.

 

NetworkManager

로그인 성공 시 실행하는 함수에 PhotonNetwork 연결하는 내용을 추가하고 OnConnectedToMaster()를 작성한다.

 

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using PlayFab;
using PlayFab.ClientModels;
using Photon.Pun;
using Photon.Realtime;


public class NetworkManager : MonoBehaviourPunCallbacks
{
    [SerializeField] InputField emailInput, pwInput, emailInputRgst, pwInputRgst, nameInputRgst;
    public GameObject loginPanel, selectPanel, registerPanel;
    string nickname;

    public void LoginBtnClick()
    {
        if (string.IsNullOrEmpty(PlayFabSettings.staticSettings.TitleId))
        {
            /*
            Please change the titleId below to your own titleId from PlayFab Game Manager.
            If you have already set the value in the Editor Extensions, this can be skipped.
            */
            PlayFabSettings.staticSettings.TitleId = "42";
        }
        var request = new LoginWithEmailAddressRequest { Email = emailInput.text, Password = pwInput.text };
        PlayFabClientAPI.LoginWithEmailAddress(request, OnLoginSuccess, OnLoginFailure);
    }

    public void RegisterBtnClick()
    {
        // use only email, no username
        var request = new RegisterPlayFabUserRequest { Email = emailInputRgst.text, Password = pwInputRgst.text, RequireBothUsernameAndEmail = false, DisplayName = nameInputRgst.text };
        PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnRegisterFailure);
    }

    public void StartBtnClick()
    {
        PhotonNetwork.JoinOrCreateRoom("Room", new RoomOptions(), TypedLobby.Default);
    }
    public override void OnJoinedRoom()
    {
        PhotonNetwork.LoadLevel(1);
    }

    private void OnRegisterSuccess(RegisterPlayFabUserResult result)
    {
        // Register Success
        Debug.Log("Register Success!");
        registerPanel.SetActive(false);
        loginPanel.SetActive(true);
    }
    private void OnLoginSuccess(LoginResult result)
    {
        Debug.Log("Congratulations, you made your first successful API call!");
        loginPanel.SetActive(false);
        selectPanel.SetActive(true);
        var request = new GetAccountInfoRequest { Email = emailInput.text };
        PlayFabClientAPI.GetAccountInfo(request, GetAccountSuccess, GetAccountFail);

        // Connect to Network after login was successful
        PhotonNetwork.ConnectUsingSettings();
        
    }

    public override void OnConnectedToMaster()
    {
        selectPanel.SetActive(true);
        
        PhotonNetwork.LocalPlayer.NickName = nickname;
    }
    
    private void GetAccountSuccess(GetAccountInfoResult result)
    {
        nickname = result.AccountInfo.TitleInfo.DisplayName;
    }

    private void OnRegisterFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your registration.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());

        // fail popup 등을 띄울 수 있음
    }
    private void OnLoginFailure(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with your first API call.  :(");
        Debug.LogError("Here's some debug information:");
        Debug.LogError(error.GenerateErrorReport());

        // fail popup 등을 띄울 수 있음
    }
    private void GetAccountFail(PlayFabError error)
    {
        Debug.LogWarning("Something went wrong with getting your account.  :(");
    }

}

 

Player 캐릭터 생성

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class PlayerSpawn : MonoBehaviour
{
    string prefabName;
    // Start is called before the first frame update
    void Start()
    {
        if (Data.charNum == 0) prefabName = "PlayerChoonsik";
        if (Data.charNum == 1) prefabName = "PlayerHoory";
        SpawnPrefab(prefabName);
    }

    private void SpawnPrefab(string _objectName)
    {
        Vector3 spawnPosition = Vector3.zero;
        PhotonNetwork.Instantiate(_objectName, spawnPosition, Quaternion.identity);
    }

}

 

Player Nickname 설정 추가

Player의 Prefab에 PhotonView를 붙이고 움직임 관련 Script를 붙인다. Player 움직이는 script에 닉네임 받아오는 부분을 추가한다. 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using Photon.Pun;

public class PlayerMoveNetwork : MonoBehaviour
{
    Rigidbody rb;
    private float speed = 10f;

    [SerializeField] private float moveSpeed = 300f; // Time.deltaTime 곱해지면서 숫자가 엄청 작아지기 때문
    private float walkSpeed;
    private float rotateY = 0;
    private float rotSpeed = 100f;
    private float x = 0;
    private float z = 0;

    //Animation Blend Tree related variables
    private float moveY;
    private float moveZ;

    [SerializeField]
    private bool isGrounded = true;
    private bool isJump = false;

    private int jumpCount = 2;


    private Vector3 startPosition;
    private Vector3 moveDir;
    private Vector3 worldDir;

    public Animator anim;

    public Item itemScript;
    public PlayerSelect playerSelect;

    [Header("Networking")]
    TMP_Text playerNick;
    PhotonView pv;

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);
        playerSelect = this.GetComponent<PlayerSelect>();
        
    }
    // Start is called before the first frame update
    void Start()
    {
        pv = GetComponent<PhotonView>();
        startPosition = transform.position;
        rb = GetComponent<Rigidbody>();
        
        anim = playerSelect.playerArr[Data.charNum].GetComponent<Animator>();    
        itemScript = GameObject.FindObjectOfType<Item>();
        transform.rotation = Quaternion.Euler(0, 0, 0);
        walkSpeed = moveSpeed; // save original speed
        playerNick.text = pv.Owner.NickName;
      
    }
}

 

댓글