목차
- RPC 를 이용해서 맞은 Player 데미지 깎이게 하기
- RPC 를 이용해서 애니메이션 구현하기
- 애니메이션 상태머신 스크립트 만들기
- RPC 로 총 쏘게 하기
- PC로 Die 상태로 바꾸기
- Connection Scene 간단하게 꾸미기
RPC 를 이용해서 맞은 Player 데미지 깎이게 하기
Photon View 를 이용해 서버에 위치를 전송해줌 RPC 를 이용해서
RPC 는 모든 PC 에 붙어있긴 한데,
photonView 의 ID 는 다 다르다.
맞은 Player의 데미지를 달게 하기위해, PlayerFire 로 간다 --->
총알 생성한 부분을 RPC 로 빼서 넣는다.
OnDamaged 에 들어가서 그 안에있는것도 뺴서 Rpc 형태로 바꾸자
이렇게 OnDamaged 자체를 RPC 로 바꾸면 됨
이 함수는 맞은애의 PhotonView 에서 터지는거임
근데 여기서 문제가 Destroy 도 따로 해줘야함 해주는 방법이 있음
이게 Destroy 되면 카메라가 그냥 없어져버리니까 그게 문제인거임
-> Destroy 가 되면 파괴할 수도 있긴한데 , Player 가 중천을 떠돌면서 상황을 바라보게 하는게 더 나음
보통게임이 그렇기도 함
RPC 를 이용해서 애니메이션 구현하기
Player에게 넣은 프리팹에서 Animator 부분에 우리가 만든 Animator 를 넣는다
AnyState => Shoot ()
trigger -> Fire ,(HasExitTime x)
Shoot => Idle
(HasExitTime O)
Idle => Run
trigger -> Move, (HasExitTime X)
Run => Idle
trigger -> Idle , (HasExitTime X)
애니메이션 상태머신 스크립트 만들기
PlayerState.cs 스크립트 파일 만들어줌
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerState : MonoBehaviour
{
// 플레이어 상태 Enum
public enum State
{
IDLE,
MOVE,
DIE
}
// 현재 상태
public State currState;
//Animator
public Animator anim;
// 상태 변경 함수
public void ChangeState(State s)
{
// 현재 상태를 s상태로!
currState = s;
// 상태에 따라서 animation 처리
switch (currState)
{
case State.IDLE:
anim.SetTrigger("Idle");
break;
case State.MOVE:
anim.SetTrigger("Move");
break;
case State.DIE:
break;
}
}
Enum 과 Switch 문을 통해서, 애니메이션을 나눈다
그러면 이제 PlayerMove 로 와서
Player State 스크립트를 Player 에게 붙인다.
Anim 에는 건담프리팹을 넣어주면 됨
여기서 문제, animation 은 트리거가 계속나오게 되면 문제가 됨.
지금 Idle 이 계속 Update 에서 트리거가 계속 불림
(움직이지 않으면 Trigger 가 계속 불린다.
이렇게 되면 다른 애니메이션이 진행되도 Idle 이 불릴때가 있는 문제가 발생한다)
PlayerState 에서
if(currState == s)
return;
코드를 추가 시켜준다.
그러면 스테이트가 한번만 불리고 같은 State 일 경우 ChangeState 는 더이상 불리지 않는다!
(참고) 이전상태로 돌아가고 싶을 때는 어떻게?
![](https://blog.kakaocdn.net/dn/QYHD7/btrLWnomJ6d/kEmwi9p40MlynEwaPZVqck/img.png)
State prevState 를 만들어서 currState 를 저장해놓고 또 쓸 수 있음
이제 애니메이션까지는 완성 했는데, 다른사람은 안보임!
그러니까, Pun 을 사용하자
PlayerState 에서 Rpc 를 만들거니까, Photon.Pun 네임스페이스 추가 하자
// 상태 변경 함수
public void ChangeState(State s)
{
// 현재상태가 s와 같다면 함수를 나가라.
if (currState == s) return;
// 현재 상태를 s상태로!
currState = s;
// 상태에 따라서 animation 처리
switch (currState)
{
case State.IDLE:
photonView.RPC("RpcSetTrigger", RpcTarget.All, "Idle");
break;
case State.MOVE:
photonView.RPC("RpcSetTrigger", RpcTarget.All, "Move");
break;
case State.DIE:
break;
}
}
[PunRPC]
void RpcSetTrigger(string s)
{
anim.SetTrigger(s);
}
이렇게 되면, Rpc 로 애니메이션 같이 연동 됨!
RPC 로 총 쏘게 하기
PlayerFire 에서
RPC 는 PhotonView 가 같은라인에 있으면 Pun 함수를 다 불러올 수가 있음
그니까, PunRPC 가 다른 스크립트에서 쓰인 함수도 다 들고올 수 있음
void FireRay()
{
//2. 카메라 중심, 카메라 앞방향 에서 Ray를 생성
Ray ray = new Ray( Camera.main.transform.position , Camera.main.transform.forward );
//3. 생성된 Ray를 발사해서 어딘가에 부딪혔다면
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
//맞은애 한테 PlayerMove들고와서 함수 실행!
PlayerMove pm = hit.transform.GetComponent<PlayerMove>();
if (pm)
pm.OnDamaged();
// 서버에 접속되어있는 모든 PC 에 요청
// 근데 모든 PC 에 붙어있는거임. 거기 중에,
// 같은 photonView ID 를 가지고있는 애가 실행되게 해주는거임
photonView.RPC("RpcShowBulletImpact", RpcTarget.All, hit.point, hit.normal);
}
else
{
//총소리 -> 동기화
// PlayOneShot 은 또 쏴도 끝까지 플레이하고 다시 시작하게 됨
photonView.RPC("RpcBulletSound", RpcTarget.All);
}
//총쏘는 애니메이션
photonView.RPC("RpcSetTrigger", RpcTarget.All, "Fire");
}
[PunRPC]
void RpcBulletSound()
{
bulletSound.PlayOneShot(bulletSound.clip);
}
[PunRPC]
void RpcShowBulletImpact(Vector3 point, Vector3 normal)
{
//4. bulletImpact 효과를 만든다.
GameObject bulletImpact = Instantiate(bulletImpactFactory);
//5. 만든효과를 부딪힌 위치에 놓는다.
bulletImpact.transform.position = point;
//6. 만든효과의 앞방향을 normal 방향으로 한다.
bulletImpact.transform.forward = normal;
//7. 2초뒤에 파괴 한다.
Destroy(bulletImpact, 2);
}
PlayerFire 를 RPC 로 고친모습
RPC로 Die 상태로 바꾸기
Die 상태가 되면 모델과 컴포넌트를 꺼주자
(카메라만 키게 만들겠다는 거임)
배열 선언해서, 배열에 들어있는것들 다 끄겠다는거임
PlayerState ---->
MonoBehaviour 가 부모 이기 때문에 저렇게 넣을 수 있은거임
PlayerState 에서 Die 일 때, 게임오브젝트 다 끄고, 컴포넌트는 다 enabled = false 해줌
그러면 PlayerMove.cs 에서
이건 이미 PunRPC 안에있는거기 때문에 이걸 따로 RPC 로 안만들어줘도 된다.
지금 Bullet 이 파괴 되는게 내 컴퓨터에서만 파괴 될 텐데,
네트워크에서 OnTrigger 를 관리 하게 되면
네트워크의 지연이 일어나면 누구는 맞고 누구는 안맞을 수도 있다.
그러니까, 내가 모든걸 관리 할 거임
내 컴퓨터에서 Destroy 되면 그걸 서버에 올릴거란 얘기
Bullet.cs --->
내 총알이면 파괴 하게 만듦
근데 여기서 문제..
언제는 둘다 폭발효과가 일어나고, 하나는 안일어남
=> 부딪히기 전에 PhotonNetwork.Destroy(gameObject) 이 일어나서 상대방의 컴퓨터에서는 안보이는거임
그니가 부딪히기도 전에 없어져 버린거임. 게임오브젝트가.
다른 사람은 충돌처리 할 필요도 없이 한명이 폭발 하라고 시키면 다 폭발일어나게 하면 됨.
그래서 한명이 충돌처리를 다 하게 하면 됨.
RPC 로 Destroy 시켜도 상관없는데, 주인이 한방에 다 파괴 할 수 있다.
그니까, Bullet.cs 스크립트 ---->
그니까 애초에 Collider 꺼놓고 있겠다는거고,
다른사람 컴퓨터에서는 안부딪혀도 상관없음
내 컴퓨터에서 부딪히면, 그걸 서버에 올릴거니까
TriggerEnter 도 RPC 로 만든다.
원래 TriggerEnter 에 있던거를 RPC 에 넣는다
이렇게 해주면,
내총알이 Trigger 가 되서 다른 컴에는 효과가 다 같이 나오고,
파괴 하는것만 내 컴퓨터 에서 해주고 이 사실을 서버에 다 뿌려서
다른 컴에도 파괴 되게 하는거임
이렇게되면 효과가 나오기 전에 파괴되는 일이 없는거임
RPC 로 호출되기 때문에,
그냥
1. Destroy 를 해주는거나,
2. photonView.IsMine 일때 PhotonNetwork.Destroy 해주는거나 똑같다.
1번은 다 알다시피 내꺼만 Destroy 해주는거고
2번에 PhotonNetwork.Destroy(gameObject)는 모든 게임오브젝트(Player) 다파괴하는거다. 근데 내꺼일 때만 파괴하는거니까 결국 내꺼만 파괴되는것임
그냥 보여주기 위해서 한거임
IsMine 이면 나 자신을 파괴 하게 한거임
Connection Scene 간단하게 꾸미기
ConnectionManager.cs 에서 시작 ㄱㄱ
Start 에 있던 코드를
함수로 뺀다
이렇게 하면 Screen Size 에 맞춰주는거임
800,600 으로 맞춰주자
Main Camera 에서 Soild Color 로 맞춰주고
"연결 씬" 이라고 적었던 Text 도 없애버리면
닉네임 InputFiled 관련 코드 및 InputField 에 어떤게 써져 있어야만 버튼이 활성화 되게 하자
닉네임을 인풋닉네임의 txt 로 해주자.
이제 이름 쓰고 접속하면 그게 NickName 이 되게 됨!
값 안넣어주면 Button 안되게 하기
Button Interactive 꺼놓고 시작하면 됨
각 메소드의 역할
'Photon' 카테고리의 다른 글
Photon 일곱째 날 (void CreateRoomListUI(), 방정보 Custom 하기, Map Thumbnail 만들기, 상황별 정리) (0) | 2022.09.15 |
---|---|
Photon 여섯 째날 (LobbyScene 꾸미기, RemoveRoomListUI(),UpdateRoomCache()) (1) | 2022.09.14 |
Photon 넷째 날 (Photon View, OnPhotonSerializeView, RPC) (0) | 2022.09.12 |
Photon 셋째 날(PlayerFire , PlayerMove.OnDamage()) (0) | 2022.09.07 |
Photon 둘째 날 (PlayerMove, PlayerRot) (0) | 2022.09.06 |