위키북스 출판사 이재현 저자님 의 '절대강좌! 유니티' 책을 참고하여 필기한 내용입니다.
주인공 캐릭터 설정
프리팹인 Player를 하이러키뷰로 가져오고 Transform을 다음과 같이 설정한다.
Scripts 폴더를 새로 만들고 Movement 이름인 스크립트를 생성한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
// 컴포넌트 캐시 처리를 위한 변수
private CharacterController controller;
private new Transform transform;
private Animator animator;
private new Camera camera;
// 가상의 Plane에 레이캐스팅하기 위한 변수
private Plane plane;
private Ray ray;
private Vector3 hitPoint;
// 이동 속도
public float moveSpeed = 10.0f;
private void Start()
{
controller = GetComponent<CharacterController>();
transform = GetComponent<Transform>();
animator = GetComponent<Animator>();
camera = Camera.main;
// 가상의 바닥을 주인공 위치를 기준으로 생성
plane = new Plane(transform.up, transform.position);
}
private void Update()
{
Move();
Turn();
}
// 키보드 입력값 연결
float h => Input.GetAxis("Horizontal");
float v => Input.GetAxis("Vertical");
// 이동 처리하는 함수
void Move()
{
Vector3 cameraForward = camera.transform.forward;
Vector3 cameraRight = camera.transform.right;
cameraForward.y = 0.0f;
cameraRight.y = 0.0f;
// 이동할 방향 벡터 계싼
Vector3 moveDir = (cameraForward * v) + (cameraRight * h);
moveDir.Set(moveDir.x, 0.0f, moveDir.z);
// 주인공 캐릭터 이동 처리
controller.SimpleMove(moveDir * moveSpeed);
// 주인공 캐릭터의 애니메이션 처리
float forward = Vector3.Dot(moveDir, transform.forward);
float strafe = Vector3.Dot(moveDir, transform.right);
animator.SetFloat("Forward", forward);
animator.SetFloat("Strafe", strafe);
}
// 회전 처리하는 함수
void Turn()
{
// 마우스의 2차원 좌푯값을 이용해 3차원 광선을 생성
ray = camera.ScreenPointToRay(Input.mousePosition);
float enter = 0.0f;
// 가상의 바닥에 레이를 발사해 충돌한 지점의 거리를 enter 변수로 반환
plane.Raycast(ray, out enter);
// 가상의 바닥에 레이가 충돌한 좌푯값 추출
hitPoint = ray.GetPoint(enter);
// 회전해야 할 방향의 벡터를 계산
Vector3 lookDir = hitPoint - transform.position;
lookDir.y = 0;
// 주인공 캐릭터의 회전값 지정
transform.localRotation = Quaternion.LookRotation(lookDir);
}
}
이동 처리는 charaterController 의 simpleMove 함수를 이용
// 주인공 캐릭터 이동 처리
controller.SimpleMove(moveDir * moveSpeed);
A 좌표 - B 좌표 = B 지점에서 A 지점으로 향하는 벡터
// 회전해야 할 방향의 벡터를 계산
Vector3 lookDir = hitPoint - transform.position;
시네머신을 활용한 카메라 컨트롤
Package Manager 에서 Cinemachine 을 Install하기
Virtual Camera 속성은 다음과 같이 설정함
포톤 프로젝트 설정
PUN 2 - FREE | Network | Unity Asset Store
PUN 2 - FREE | 네트워크 | Unity Asset Store
Get the PUN 2 - FREE package from Photon Engine and speed up your game development process. Find this & other 네트워크 options on the Unity Asset Store.
assetstore.unity.com
위의 에셋을 받고 unity에서 Import 해준다.
패키지 설치가 완료되면 Wizard가 뜨게 되는데 이때 이전에 생성한 어플리케이션 ID를 입력하면 프로젝트 설정이 완료됐다는 문구가 뜸
Window - Photon Unity Networking - PUN Wizard
PhotonServerSettings에서 다양한 설정 정보 확인 가능
포톤 서버 접속
포톤 서버는 로비와 룸의 개념이 존재
룸 단위 네트워킹 기능을 제공, 포톤 서버에 접속하면 룸을 생성가능 ( 네트워크 게임을 실행할 수 있는 논리적인 공간으로 룸에 입장해야만 해당 룸에 접속한 유저와 통신 가능 )
PhotonManager 생성하고 다음과 같이 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class PhotonManager : MonoBehaviourPunCallbacks
{
// 게임의 버전
private readonly string version = "1.0";
// 유저의 닉네임
private string userId = "Zark";
private void Awake()
{
// 마스터 클라이언트의 씬 자동 동기화 옵션
PhotonNetwork.AutomaticallySyncScene = true;
// 게임 버전 설정
PhotonNetwork.GameVersion = version;
// 접속 유저의 닉네임 설정
PhotonNetwork.NickName = userId;
// 포톤 서버와의 데이터의 초당 전송 횟수
Debug.Log(PhotonNetwork.SendRate);
// 포톤 서버 접속
PhotonNetwork.ConnectUsingSettings();
}
// 포톤 서버에 접속 후 호출되는 콜백 함수
public override void OnConnectedToMaster()
{
Debug.Log("Connected to Master!");
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
PhotonNetwork.JoinLobby();
}
// 로비에 접속 후 호출되는 콜백 함수
public override void OnJoinedLobby()
{
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
}
}
PhotonManager 스크립트는 MonoBehaviour 에서 MonoBehaviorPunCallbacks 클래스로 베이스 클래스를 변경함
PUN의 다양한 콜백 함수를 오버라이드해서 작성해야됨
public class PhotonManager : MonoBehaviourPunCallbacks
{
}
AutomaticallySyncScene 속성은 방장이 새로운 씬을 로딩했을 때 해당 룸에 입장한 다른 접속 유저들에게도 자동으로 씬을 로딩해주는 기능
// 마스터 클라이언트의 씬 자동 동기화 옵션
PhotonNetwork.AutomaticallySyncScene = true;
GameVersion 속성은 같은 버전의 유저끼리 접속을 허용하는 기능
처음 릴리즈한 버전이 1.0이라면 이후에 수정한 1.1 버전을 업데이트 했을 경우 서로 동일한 버전 간의 접속만 허용한다는 기능
// 게임 버전 설정
PhotonNetwork.GameVersion = version;
SendRate 속성은 포톤 서버와 통신 횟수를 설정하는 것으로 기본 초당 30회
ConnectUsingSettings 함수는 포톤 서버에 접속하는 역할
// 포톤 서버와의 데이터의 초당 전송 횟수
Debug.Log(PhotonNetwork.SendRate);
// 포톤 서버 접속
PhotonNetwork.ConnectUsingSettings();
OnConnectedToMaster 콜백 함수
포톤 서버에 접속하면 가장 먼저 호출되는 함수
로비에 들어왔는지 여부를 나타내는 PhotonNetwork.InLobby 속성
포톤은 자동으로 로비에 입장시키지 않기 때문에 False 출력됨
public override void OnConnectedToMaster()
{
Debug.Log("Connected to Master!");
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
PhotonNetwork.JoinLobby();
}
PhotonNetwork.JoinLobby 함수
포톤 서버에 접속한 후 PhotonNetwork.JoinLobby 함수를 실행하면 로비에 입장
입장되면 OnJoinedLobby 콜백 함수가 호출됨
// 로비에 접속 후 호출되는 콜백 함수
public override void OnJoinedLobby()
{
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
}
새로운 빈 오브젝트를 생성하고 PhotonManager 스크립트를 연결한다
JoinRandomRoom 함수와 OnJoinRandomFailed 콜백 함수
포톤 서버는 랜덤 매치 메이킹 기능을 제공
JoinRandomRoom은 포톤 서버에 접속하거나 로비에 입장한 후 이미 생성된 룸 중에서 무작위로 선택해 입장할 수 있는 함수
아무런 룸이 생성되지 않았다면 룸에 입장할 수 없으며 OnJoinedRandomFailed 콜백 함수가 발생
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class PhotonManager : MonoBehaviourPunCallbacks
{
// 게임의 버전
private readonly string version = "1.0";
// 유저의 닉네임
private string userId = "Zark";
private void Awake()
{
...생략
}
// 포톤 서버에 접속 후 호출되는 콜백 함수
public override void OnConnectedToMaster()
{
Debug.Log("Connected to Master!");
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
PhotonNetwork.JoinLobby();
}
// 로비에 접속 후 호출되는 콜백 함수
public override void OnJoinedLobby()
{
Debug.Log($"PhotonNetwork.InLobby = {PhotonNetwork.InLobby}");
PhotonNetwork.JoinRandomRoom();
}
// 랜덤한 룸 입장이 실패했을 경우 호출되는 콜백 함수
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log($"JoinRandom Failed {returnCode}:{message}");
}
}
CreateRoom 함수
AppId 로 포톤 서버에 접속했기 때문에 입장할 수 있는 룸이 없음
직접 룸을 생성하고 입장해보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class PhotonManager : MonoBehaviourPunCallbacks
{
// 게임의 버전
private readonly string version = "1.0";
// 유저의 닉네임
private string userId = "Zark";
private void Awake()
{
...생략
}
// 포톤 서버에 접속 후 호출되는 콜백 함수
public override void OnConnectedToMaster()
{
...생략
}
// 로비에 접속 후 호출되는 콜백 함수
public override void OnJoinedLobby()
{
...생략
}
// 랜덤한 룸 입장이 실패했을 경우 호출되는 콜백 함수
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log($"JoinRandom Failed {returnCode}:{message}");
// 룸의 속성 정의
RoomOptions ro = new RoomOptions();
ro.MaxPlayers = 20; // 룸에 입장할 수 있는 최대 접속자 수
ro.IsOpen = true; // 룸의 오픈 여부
ro.IsVisible = true; // 로비에서 룸 목록에 노출시킬지 여부
// 룸 생성
PhotonNetwork.CreateRoom("My Room", ro);
}
// 룸 생성이 완료 된 후 호출되는 콜백 함수
public override void OnJoinedRoom()
{
Debug.Log($"PhotonNetwork.InRoom = {PhotonNetwork.InRoom}");
Debug.Log($"Player Count = {PhotonNetwork.CurrentRoom.PlayerCount}");
}
}
룸의 속성은 RoomOptions 구조체를 이용해 정의됨
룸의 속성에는 MaxPlayers, IsOpen, IsVisible 속성을 제공함
CreateRoom 함수의 첫번째 인자는 룸의 이름, 두번째 인자는 RoomOptions 데이터를 전달
동일한 룸이 있거나 룸 생성에 실패하면 OnCreateRoomFailed 콜백 함수가 호출됨
정상적으로 룸이 생성 된다면 OnCreatedRoom() 콜백 함수가 호출됨
유저가 룸에 정상적으로 입장했다면 OnJoinedRoom() 콜백 함수가 호출됨
룸에 접속한 사용자 정보
CurrentRoom.Players 로 확인 가능
// 룸 생성이 완료 된 후 호출되는 콜백 함수
public override void OnJoinedRoom()
{
Debug.Log($"PhotonNetwork.InRoom = {PhotonNetwork.InRoom}");
Debug.Log($"Player Count = {PhotonNetwork.CurrentRoom.PlayerCount}");
foreach(var player in PhotonNetwork.CurrentRoom.Players)
{
Debug.Log($"{player.Value.NickName},{player.Value.ActorNumber}");
}
}
NickName은 고유한 값이 아니기 때문에 동일한 이름을 볼 수 있음
접속자의 고유의 값이 필요할 경우에는 ActorNumber를 사용해야됨
'Unity 강의 > Unity Course(2) - 절대강좌! 유니티' 카테고리의 다른 글
[Unity Course 2] 15. 포톤 클라우드를 활용한 네트워크 게임 4 (0) | 2024.07.04 |
---|---|
[Unity Course 2] 15. 포톤 클라우드를 활용한 네트워크 게임 3 (0) | 2024.07.01 |
[Unity Course 2] 15. 포톤 클라우드를 활용한 네트워크 게임 1 (0) | 2024.06.29 |
[Unity Course 2] 14. Input System - Player Input 컴포넌트 (0) | 2024.06.29 |
[Unity Course 2] 14. Input System - 새로운 Input System의 특징 (0) | 2024.06.29 |