목차
Photon Voice 세팅
플레이어 안에 스피커 역할 하는 애를 하나 만들거임
우리가 필요한 정보들 =
Game Scene----->
voice 오브젝트
여기에 Recorder 컴포넌트 넣기
(참고)
Voice 오브젝트에
Photon Voice Network 컴포넌트도 추가해주자!
Primary Recorder 에 Recorder 를 넣어야 하는데,
지금 Voice 오브젝트에 붙어있으니까, Voice 를 집어넣자
그다음에 우리가 만든 Player 에 가보자
Player 라는 프리팹은 Photon.Instantiate 때문에
Reseources 폴더에 넣어놨을 거임!
여기에 Speaker 라는 오브젝트추가하고
Speaker 의 Position 등을 Reset 시켜준다.
Speaker 가 멀어지면 소리도 잘 안들리기 때문이다
저 위의 컴포넌트 2개를 추가한다
Audio 와 Speaker
그 후, Player Object 에서 Photon Voice View 컴포넌트 추가!
그리고 Speaker In Use 에 Speaker 컴포넌트 넣자! (Player 안에 있는 컴포넌트)
위에 AudioSource 는 예전에 총소리 때문에 넣었던거임
Use Primary Recordcer 에 체크 하면 Recorder In Use 에 안넣어도 알아서 찾아줌!
원래는 저것도 넣어야 하는데, 그럴려면 아까 GameScene 에 넣어줬던 Recorder 오브젝트를 넣어줘야 하는데,
프리팹에는 오브젝트를 넣을 수 없다! (프리팹에 프리팹은 넣을 수 있는데)
그렇기 때문에 Use Primary Recorder 를 체크해서 알아서 찾게 하게 하자
Speaker 는 각자가 나와야 하기 때문에 Player 안에 있는 Speaker 를 넣자
내가 말했을 때 저게 올라가고 그런거면, 상대방도 들리는거임!
재생 했을 때만 저 Level 이 나온다!!!
마이크 체크 해보기
LobbyManager.cs 에서
Start() 에
이렇게 마이크 디바이스 배열로 넣어서 확인 해볼 수 있음
지금은 마이크 1개만 있어서 위와 같이 나오는거임
보이스는 여기서 마무리!
포톤 소유권 넘기기
isMine 의 소유권을 넘길 수가 잇음
그러면
B는 움직여도 아무것도 안움직이는데
A 가 움직이면 A,B 둘다 움직여짐
어떤 협동게임에서, A는 몸을 맡고 B는 팔을 맡았을 때,
어떨 때는 A가 두개 다 컨트롤 하는 기획의 게임이 있었다.
그럴 때, 이런식으로 isMine 의 소유권을 넘겨줘서 하는 방식을 쓰기도 한다.
좀 재밌는거 해보기
( Feat. 서버에서 움직임을 자체적으로 통제하는 방법 )
소유권 문제
2D Shooting 느낌으로 Plane 하나 만든다
스크립트도 하나 만들어서 집어넣는다
그리고 Resources 에 Plane 을 Prefab 으로 넣자
Photon으로 생성시키려고
GameManger 에서 Plane 소환하는 코드 넣자
Plane 에는 카메라 없으니까
방장 컴퓨터에 있는 오브젝트들은 같이 움직임.
방장이 같이 움직여준거임
왜? IsMine 을 안걸러줬기 때문!
그래서 IsMine 을 넣어보자
photonView.IsMine
조건문 안에 다 넣어서, 내꺼만 실행 되게 해보자
이제 이 조건문을 Update 문에 넣을 건데
저게 무슨말이냐면, 5번키를 눌렀을때
만약 방장이 아니고, 내 것일 때
나의 소유권을 방장한테 넘긴다는거임!
왜 방장이 아니고, 내것이어야 하냐면,
소유권을 방장한테 넘겨줄건데, 방장이면 안되지?
그리고 내거를 상대방한테 소유권을 넘겨준다는거니까 그런거임!
이거 되게 하려면 Photon View 에 옵션을 하나 건드려야함
TakeOver 를 해줘야 저게 바꿀 수 있음
Request 는 요청하는거임!
실행 했을 때 B 의 컴퓨터의 B캐릭터
True 상태
5번 키를 넘기면 False 가 된다.
Controller 와, Owner 의 이름도 A꺼로 바뀌는데
지금 A의 이름도 123 이고 B 의 이름도 123 이어서 안바뀐것 처럼 보이는 것이다.
이제는
방장이 둘 다 움직이게 할 수 있음!
근데 이 상황에서 B 가 움직이게 할 수 있음
B의 키값을 A가 받고
그 키값을 통해 A가 B 의 오브젝트를 움직이게 하는것이다.
이게 시사하는 바가 크다.
아니, 굳이 B가 원래 움직이게 할 수 있었는데
A한테 소유권 주고 B가 왜 또 움직이게 하게 하는 건지?
라고 생각 할 수 있다.
근데 이렇게 해버리면,
모든 움직임을 서버에 보내고 그 서버가 통제하게 할 수 있는것이다.
구조로 보자면 이게 훨씬 합리적이고, 원래 이런식으로 서버에서 통제 하게 한다.
isCreator 라는 bool 형식을 하나 생성
시작할 때, isMine 을 넣으면 true 가 들어갈꺼임
A든 B 든
각각의 PC 에서 자기자신은 IsMine 이 true 이기 때문
(당연한 말)
B PC 에서 캐릭터 B 의 경우
이렇게 하면, isCreator 가 true 이니까
저게 Update 에 있는 코드가 사용은 되는데
transform.position 이 안먹힘
방장한테 소유권을 줘버렸으니까
이 코드도 추가한다.
transform.position 코드는 위에서 끌고 내려온거임
만약 내가 방장일 때,
움직임이 감지되면
이동시킨다.
움직임 벡터 dir 의 크기가 0보다 클 때, 움직이게 하는것.
저기서 sqrMagnitude 는 루트를 안씌운 상태이다.
Ex) Vector2 (1,1) 의 Magnitude(크기) 는 루트(1^2 + 1^2) 이다. 루트(x의 제곱 + y의 제곱)
근데 위의 경우는 0이상인지만 판단 하면 되니까, 루트까지 굳이 계산할 필요없게
(x의 제곱 + y의 제곱)
인 경우이다.
그리고, Rpc 함수로 , 아까 구현했던 dir 을 넣는다.
여기에 RPC 함수 호출 (방장한테만 호출)
(이렇게 되면 B PC 에 있는 B 가 호출 할 거임
isCreator 가 true 라는 얘기는, 원래 자기 PC 에 주인이었다는 소리기 때문에)
그러면 B pc 에 있는 B 가 자기 dir 을 동기화 요청을 함
그럼 이제 여기서,
A pc 가 MasterClient 이니까,
A pc 에서 A, B 둘 다 움직이게 한다.
즉, B의 dir 값을 A한테 보내고,
A는 그 값을 받아서 A pc 에 있는 p=p0 + Vt 계산을 해서
B 를 움직이게 한다.
서버에서 다 계산하고 움직이게 한거임
소유권을 넘길 수 잇음
일단 이건 방장한테 보낸 모습이고
이거는 지금 나한테 준다는거고,
다른사람의 Owner 를 찾아서 가져오면 내 소유권을 다른사람한테 줄 수 있다는거임
결국 시사하는 바는
이렇게 하면 모든 움직임을 다 서버에서 하겠다는거임
나의 소유권을 가지고 있는 사람한테 보낸다는거임
맵 툴 제작
Project 를 새로 만들자!
빈게임 오브젝트 Map 을 만들고
Script 이름도 Map 으로 해서 넣자
가로 3 세로 3인 타일을 맵 툴을 이용해서 만들어 볼거임
좀 커스텀 해볼거야 ㅎㅎ
일단 위처럼 작성하고,
MapEditor 라는 스크립트를 하나 더 만들자
MapEditor ---->
네임스페이스로 using UnityEditor; 작성한 후,
[CustionEditor] 위에 저렇게 꼭 써줘야 한다
얘는 플레이를 안해도 계속 돌아가고 있음. Editor 로 쓰게 저렇게 작성하면.
실험으로, 해당 게임오브젝트(Map) 이 선택되면 불러지는 함수를 작성해보자
OnEnable 이라고 있음
다른오브젝트 눌렀다가
Map 누르면 계속 선택된다고 뜬다!
Override 로 OnInspectorGUI 를 불러오자
그리고 base 에서 저렇게 또 뜰 텐데,
저걸 주석처리 해버리면 해버리면 자식이 저걸 없앤거임.
그러면 인스펙터 창에 보면 저게 안나올 거임
있었는데,,?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Map))]
public class MapEditor : Editor
{
// target 을 담을 변수
Map map;
// 해당 게임 오브젝트가 클릭되었을 때 호출되는 함수
private void OnEnable()
{
Debug.Log("선택됨");
// 선택될 때마다 map 에 넣는거임
map = (Map)target;
}
//Inspector 에 변화가 있을 때 호출되는 함수
public override void OnInspectorGUI()
{
//base.OnInspectorGUI();
// tileX, tileZ 를 표현
EditorGUILayout.IntField("타일 가로", map.tileX);
}
}
이제 이렇게 작성해보자
OnEnable()
안에 map = (Map)target; 을 해버리면
Map 컴포넌트를 가져오게 하는거임
target 으로 하면 무조건 잡히게 되어있음
Map 컴포넌트를 가져오는 느낌
위처럼 입력하면
근데 Enter 만 눌러도 0이 되버리네,,?
그러니까, map 에서 변수를 가져와서 저장하자
Z까지 해보자
타일은 -1 값이 있으면 안되니까,
0~100까지 제한 해주자
Clamp도 넣고
저 변수 사이에 공간이 생김
Map 을 클릭하면 저렇게 나옴
//Scene 화면을 그리는 함수
private void OnSceneGUI()
{
Vector3 start;
Vector3 end;
Handles.color = Color.red;
//Handles.DrawLine(Vector3.zero, Vector3.one * 5);
for (int i = 0; i <= map.tileX; ++i)
{
start = new Vector3(i, 0, 0);
end = new Vector3(i, 0, map.tileZ);
Handles.DrawLine(start,end);
}
Handles.color = Color.blue;
for (int i = 0; i <= map.tileZ; ++i)
{
start = new Vector3(0, 0, i);
end = new Vector3(map.tileX, 0, i);
Handles.DrawLine(start, end);
}
}
이렇게 작성해버리면
타일 가로 세로에 따라서 그리드가 생김!
그리고 이걸 DrawGrid() 함수로 빼자!
'Photon' 카테고리의 다른 글
Photon 열 번째 날 (채팅길면 개행시키기, Scroll Bar 맨 밑으로 최신화, Photon Voice 맛보기) (1) | 2022.09.21 |
---|---|
Photon 아홉째 날 (포톤채팅구현, 채팅 동기화 후 나오는 문제 해결, 닉네임 색 바꿔주기) (1) | 2022.09.20 |
Photon 여덟째 날(Password 생성, SpawnPoint 생성, 턴 형식 만들기) (2) | 2022.09.16 |
Photon 일곱째 날 (void CreateRoomListUI(), 방정보 Custom 하기, Map Thumbnail 만들기, 상황별 정리) (0) | 2022.09.15 |
Photon 여섯 째날 (LobbyScene 꾸미기, RemoveRoomListUI(),UpdateRoomCache()) (1) | 2022.09.14 |