[포톤] 직접 예제 만들어보기 (PunRPC 사용하기)
목표
몬스터의 체력 동기화를 해볼 것이다.
예제들을 살펴보니, 체력 같은 경우는 보통 PunRPC보다 OnPhotonSerializeView에서 동기화해주는 것 같다.
이번에는 PunRPC를 써보기 위해, PunRPC를 사용해서 동기화를 해볼 것이다.
동기화하는 법 종류는 여기 정리했다.
2021.09.28 - [Unity/포톤] - [포톤] 동기화하는 법
몬스터 체력 동기화하기
일단 순서대로 차근차근 해본다.
1. 동기화할 변수를 만든다.
public float Health = 1f;
2. 맞았을 때의 함수를 구현한다.
TakeHit함수는 따로 인터페이스로 뺏다.
인터페이스에서 TakeHitRPC도 선언해야하나 싶었는데, 음... 뭐가 더 좋을지는 잘 모르겠다.
using UnityEngine;
public interface IDamageable
{
void TakeHit(float _damage);
}
// IDamageable 인터페이스 구현.
public void TakeHit(float _damage)
{
photonView.RPC("TakeHitRPC", RpcTarget.All, _damage);
}
[PunRPC]
public void TakeHitRPC(float _damage)
{
Health -= _damage;
GetComponent<Animator>().SetTrigger("Hit");
}
3. 때리는 함수를 구현한다.
IDamageable을 구현한 클래스라면, 데미지를 입도록 구현했다.
public void Attack(GameObject attacked, float damage)
{
IDamageable damageableObject = attacked.GetComponent<IDamageable>();
if (damageableObject != null)
{
damageableObject.TakeHit(damage);
}
}
아니!!! 코딩할 때는 되게 헷갈렸는데, 글로 적고보니까 너무나도 당연하다는 듯이 로직이 구성된다.
주의할 점
여기서 잠시 삽질했던 부분은 이 부분이다.
PunRPC로 Animation Trigger를 호출했는데, 마스터클라이언트가 아닌 클라이언트에서 애니메이션이 2번씩 발동됐다.
GetComponent<Animator>().SetTrigger("Hit");
원인은 PhotonView에서도 동기화가 되고 있었다.
Discrete는 초당 10번씩 동기화하기 때문에, 동기화하지 않는 Disabled로 바꾸었다.
포톤 동기화에 대한 생각
내 컴퓨터에서만 발생할건지, 전체에서 발생할건지 구분이 잘 돼야할 듯 싶다.
1. 로컬에서 발생시키고, 그 변수를 동기화할 수도 있고.
2. 로컬에서 발생을 감지했으면, 전체로 뿌릴 수도 있고.
상황에 맞게 쓰면 될 것 같다.
잘 모르고 되는대로 하다보면, 전체로 이벤트르 뿌렸는데도 또 변수를 동기화하는 낭비가 생길 수도 있을 것 같다.