Unity 팀프 21.06.03 PUN2 - RPC
어제 해결못한 RPC이슈가 해결이 됐다. 어제 곰곰히 생각해보니 Local처리를 하지 않은것이 원인이라고 생각되어서 코드를 고친 후 결과를 비교해보았다.
자신의 객체 : this.gameObject & Local처리 안함 // 자신의 객체 : this & Local처리 함
아무래도 Local처리를 안해준 것이 문제였던 것 같다. Local 처리를 안하면 OnTriggerEnter를 방 안의 모든 플레이어들이 실행시켰던 것처럼(CustomProperties 이슈때) OnCollisionEnter도 로컬처리를 안해 RPC들이 충돌을 일으키지 않았나 싶다.
Log가 자신밖에 찍히지 않는걸 보니 전부 실행은 아닌듯 하다. 다만, RPC부분에서 에러가 나는데, RPC를 실행하면서 Null이 나는 이유는 photonView의 게임오브젝트가 InGame인데, InGame은 로컬오브젝트여서 나는 것이라고 생각된다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
public class PlayerController : MonoBehaviourPun
{
public Transform camera;
public Rigidbody rigid;
public Animator anime;
[HideInInspector]
public bool isLocal;
[SerializeField]
float speed;
VariableJoystick joystick;
PhotonView photonView;
bool isDie;
private void Start()
{
}
public void Init()
{
isDie = false;
if (!isLocal) return;
speed = 3f;
this.gameObject.GetComponent<CapsuleCollider>();
var cameraGo = GameObject.Find("Main Camera");
camera = cameraGo.GetComponent<Transform>();
var joystickGo = GameObject.Find("Variable Joystick");
joystick = joystickGo.GetComponent<VariableJoystick>();
var go = GameObject.Find("InGame");
photonView = go.GetComponent<PhotonView>();
var inGameRPCs = photonView.GetComponent<InGameRPCs>();
Debug.Log(inGameRPCs.gameObject.name);
inGameRPCs.OnRemoveTreasure = (number) =>
{
//PhotonNetwork.Destroy(treasure.gameObject);
Debug.LogFormat("Player {0} is Robbing", number);
};
inGameRPCs.OnBlockingHunter = (number) =>
{
if(PhotonNetwork.LocalPlayer.CustomProperties["IsRobber"] != null && (int)PhotonNetwork.LocalPlayer.CustomProperties["IsRobber"] == PhotonNetwork.LocalPlayer.ActorNumber)
{
Debug.Log("The Hunter is Dead.");
isDie = true;
Debug.Log(isDie);
}
else
{
Debug.Log("Take a Rest, Bud.");
this.anime.SetBool("IsSat", true);
}
};
}
private void FixedUpdate()
{
if (!isLocal) return;
Vector3 joystickDir = Vector3.forward * joystick.Vertical + Vector3.right * joystick.Horizontal;
if (isDie)
{
joystickDir = Vector3.zero;
anime.SetTrigger("IsDie");
}
if (joystickDir == Vector3.zero)
{
anime.SetBool("isRun", false);
}
if (joystickDir != Vector3.zero)
{
anime.SetBool("isRun", true);
Vector3 playerAngle = Quaternion.LookRotation(joystickDir).eulerAngles;
Vector3 camPivotAngle = camera.eulerAngles;
Vector3 towardAngle = Vector3.up * (playerAngle.y + camPivotAngle.y);
rigid.rotation = Quaternion.Euler(towardAngle);
rigid.transform.Translate(Vector3.forward * Time.deltaTime * speed);
}
}
private void OnTriggerEnter(Collider other)
{
if (!isLocal) return;
if (other.tag == "Treasure")
{
photonView.RPC("RPC_RemoveTreasure", RpcTarget.All, PhotonNetwork.LocalPlayer.ActorNumber);
var viewId = this.gameObject.GetComponent<PhotonView>().ViewID;
ExitGames.Client.Photon.Hashtable newHash = new ExitGames.Client.Photon.Hashtable();
newHash.Add("IsRobber", PhotonNetwork.LocalPlayer.ActorNumber);
newHash.Add("Robber", viewId);
PhotonNetwork.LocalPlayer.SetCustomProperties(newHash);
}
}
private void OnCollisionEnter(Collision collision)
{
if (!isLocal) return;
if(this.tag == "TreasureHunter" && collision.gameObject.tag == "Guardian")
{
photonView.RPC("RPC_BlockingHunter", RpcTarget.All, PhotonNetwork.LocalPlayer.ActorNumber);
}
}
}
TreasureHunter의 죽음 처리를 FixedUpdate에 한 이유는 람다식 내에 선언했더니, 죽는 애니메이션이 덮어씌워지는건지 겹쳐서 오류가 난건지 모르겠지만 die가 출력이 되지 않았다. 코드자체는 실행이 된 것으로 보엿는데, 애니메이션이 재생되지 않고 계속 달리기만 해서 isDie라는 bool값을 선언하여 FixedUpdate내에 조작제한과 죽음 애니메이션 출력을 구현하여 해결했다.
그리고 팀원들이 SVN업데이트를 한 후 함께 테스트를 하면 RPC에러가 나는 이슈가 있었다. 해당 에러는 RPCList의 인덱스가 서로 달라서 발생한 것으로 밝혀졌다. Clear해주고 Refresh해주면 간단히 해결된다.(물론 [PunRPC]를 필요없는 메서드에 할당하지만 않으면 같은 인덱스로 정렬될 것이다.)
이걸로서 메인 메커니즘은 다 만들었다.