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에서 회원가입한 이메일, 비밀번호로 로그인
SDK 없으므로 Install PlayFab SDK 하고 커피 한잔 하면서 기다리기
SETTINGS - STUDIO를 My Game Studio로 변경하면 Title ID가 알아서 잡힌다.
에러 해결
Assets > PlayFabSDK > Shared > Public > Resources 폴더를 Assets에 들어있게끔 폴더 이동
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에 로그 찍히는 것 확인.
My Game 대시보드 들어가서 보면 내가 입력한 Nickname을 가진 Player가 생성되어 있을 것이다.
Photon 연결
Window > Package Manager 클릭 > Packages: My Assets 로 변경 - Pun 검색 - 전부 Import
PUN2를 아직 설치해본 적이 없다면 Unity Asset Store 가서 다운로드할 것!
Window > Photon Unity Networking > Highlight Server Settings 클릭
Photon 사이트에서 Pun Id, Chat Id 받아서 복사-붙여넣기
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;
}
}
'Unity 공부' 카테고리의 다른 글
Agile 협업 흐름 (Jira - Confluence 설치 및 세팅) (0) | 2022.12.02 |
---|---|
[Unity] Photon RPC 에러 Exception: Write Failed. Custom type not found (0) | 2022.11.20 |
[Unity] 어몽어스 미니게임 (멀티) - 스위치 켜기 (Among Us - Light Switch task Multi ver) (0) | 2022.11.13 |
[Unity] Photon Serialization - RPC 동기화 가능한 데이터 타입 (0) | 2022.11.08 |
[Unity] 어몽어스 미니게임 - 방패 임무 (Among Us Shield Task) (2) | 2022.11.04 |
댓글