PhotonView Class Reference

Public Member Functions

void RequestOwnership ()
 Depending on the PhotonView's ownershipTransfer setting, any client can request to become owner of the PhotonViewMore...
 
void TransferOwnership (PhotonPlayer newOwner)
 Transfers the ownership of this PhotonView (and GameObject) to another player. More...
 
void TransferOwnership (int newOwnerId)
 Transfers the ownership of this PhotonView (and GameObject) to another player. More...
 
void OnMasterClientSwitched (PhotonPlayer newMasterClient)
 Check ownerId assignment for sceneObjects to keep being owned by the MasterClient. More...
 
void SerializeView (PhotonStream stream, PhotonMessageInfo info)
 
void DeserializeView (PhotonStream stream, PhotonMessageInfo info)
 
void RefreshRpcMonoBehaviourCache ()
 Can be used to refesh the list of MonoBehaviours on this GameObject while PhotonNetwork.UseRpcMonoBehaviourCache is true. More...
 
void RPC (string methodName, PhotonTargets target, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RpcSecure (string methodName, PhotonTargets target, bool encrypt, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RPC (string methodName, PhotonPlayer targetPlayer, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
void RpcSecure (string methodName, PhotonPlayer targetPlayer, bool encrypt, params object[] parameters)
 Call a RPC method of this GameObject on remote clients of this room (or on all, inclunding this client). More...
 
override string ToString ()


PhotonView 클래스는 네트워크상에 전송되는 오브젝트를 위한것으로 보인다 유니티네트워크의 NetworkIdentity 컴포넌트와 비슷한 역할을 하는듯하다


홈페이지에서는 아래와같이 설명되었있다


네트워크 객체

일반 GameObject들은 PhotonView 컴포넌트가 있는 네트워크 객체로 전환될 수 있습니다. PhotonView는 네트워크를 통해 객체를 식별하고 해당 객체의 상태를 동기화하는 데 사용됩니다. 일반적으로, PhotonView는 런타임에 인스턴스화된 프리팹에 연결됩니다. 종종 모든 선수들은 통제할 자신만의 객체들을 가지고 있습니다.

GameObject에 PhotonView를 추가하기위해서는, 단순히 GameObject를 선택하고 사용하면 됩니다:"Components/Miscellaneous/Photon View"

Transform 동기화


튜도리얼에 따르면 트랜스폼 동기화를 위한 컴포넌트가 PhotonTransformView  라고 되었는데 PUN2 에서는  튜토리얼버전은 클래식으로 되어있다. 클래식에 비해 옵션이 없기때문에 사용이 좀더 편해보인다



Animation 동기화


PhotonAnimatiorView 스크립트를 추가하면 해당 오브젝트의 animator 에서 레이어와 파라미터를 친절하게 가져와준다


Discreate : 초당 10회의 데이터를 전송

Continuous : 매 프레임마다 데이터를 전송






위에 두 컴포넌트를 추가한 뒤 PhotonView 컴포넌트에 observed components에 추가해주자





기타 컴포넌트 동기화


동기화가 필요한 컴포넌트일 경우 IPunObservable 인터페이스를 상속받아 OnPhotonSerializeView를 정의 후 

위 컴포넌트들 처럼 PhotoView 컴포넌트에 추가해준다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class PlayerManager : MonoBehaviourPunCallbacks , IPunObservable
{
 
     public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)        
    {
            if (stream.IsWriting)
            {             
                stream.SendNext(IsFiring);
            }
            else
            {          
                this.IsFiring = (bool)stream.ReceiveNext();
            }
    }
}
cs


https://doc.photonengine.com/ko-kr/pun/v2/demos-and-tutorials/pun-basics-tutorial/player-prefab


캐릭터 프리펩을 만들기 위한 애니메이션, 입력 관련이 주된내용으로 관련 내용은 따로 포스팅을 해보자


이번 장에서 사용한 포톤 관련 클래스는 PhotonView 클래스로 해당 오브젝트가 클라이언트의 소유인지 확인 할 수 있다


bool PhotonView.isMine
get

True if the PhotonView is "mine" and can be controlled by this client.

PUN has an ownership concept that defines who can control and destroy each PhotonView. True in case the owner matches the local PhotonPlayer. True if this is a scene photonview on the Master client.

https://doc-api.photonengine.com/en/pun/current/class_photon_view.html


아래와 같이 빔에 맞았을 때 본인의 캐릭터일때만 hp를 깍게 되어있다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void OnTriggerEnter(Collider other)
        {
            if (!photonView.IsMine)
            {
                return;
            }
 
            if (!other.name.Contains("Beam"))
            {
                return;
            }
            Health -= 0.1f;
        }
 
        void OnTriggerStay(Collider other)
        {
 
            if (!photonView.IsMine)
            {
                return;
            }
 
            if (!other.name.Contains("Beam"))
            {
                return;
            }
   
            Health -= 0.1f * Time.deltaTime;
        }
cs








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
 
 
namespace Com.MyCompany.MyGame
{
    public class GameManager : MonoBehaviourPunCallbacks
    {
 
        public override void OnLeftRoom()
        {
            SceneManager.LoadScene(0);
        }
 
        public void LeaveRoom()
        {
            PhotonNetwork.LeaveRoom();
        }
 
        private void LoadArena()
        {
            if(!PhotonNetwork.IsMasterClient)
            {
                Debug.LogError("PhotonNetwork : Trying to Load a level but we are not the master Client");
            }
 
            Debug.LogFormat("PhotonNetwork : Loading Level : {0}", PhotonNetwork.CurrentRoom.PlayerCount);
            PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.CurrentRoom.PlayerCount);
        }
 
 
        public override void OnPlayerEnteredRoom(Player other)
        {
            Debug.LogFormat("OnPlayerEnteredRoom() {0}", other.NickName); 
 
 
            if (PhotonNetwork.IsMasterClient)
            {
                Debug.LogFormat("OnPlayerEnteredRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient);
 
                LoadArena();
            }
        }
 
        public override void OnPlayerLeftRoom(Player other)
        {
            Debug.LogFormat("OnPlayerLeftRoom() {0}", other.NickName); 
 
            if (PhotonNetwork.IsMasterClient)
            {
                Debug.LogFormat("OnPlayerLeftRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient); 
 
                LoadArena();
            }
        }
    }
}
cs

GameManager 스크립트에  OnPlayerEnteredRoom 메소드로 현재 플레이 인원에 따라 만들어둔 씬을 로드하게 하자
** PhotonNetwork.LoadLevel() 는 MasterClient 만이 호출가능하다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
 
namespace Com.MyCompany.MyGame
{  
    public class Launcher : MonoBehaviourPunCallbacks
    {
 
        [SerializeField]
        private GameObject controlPanel;
        [Tooltip("The UI Label to Inform the user that the connection is in progress")]
        [SerializeField]
        private GameObject progressLabel;
 
        string gameVersion = "1";
 
        bool isConnecting=false;
 
        private void Awake()
        {
            PhotonNetwork.AutomaticallySyncScene = true;
        }
 
        void Start()
        {
            progressLabel.SetActive(false);
            controlPanel.SetActive(true);
 
        }
   
        void Update()
        {
        
        }
        public void Connect()
        {
            isConnecting = true;
            if (PhotonNetwork.IsConnected)
            {
                PhotonNetwork.JoinRandomRoom();
            }
            else
            {
                PhotonNetwork.GameVersion = gameVersion;
                PhotonNetwork.ConnectUsingSettings();
            }
 
            progressLabel.SetActive(true);
            controlPanel.SetActive(false);
 
        }
 
        public override void OnConnectedToMaster()
        {
            Debug.Log("PUN Basics Tutorial/Launvher: OnConnectedToMaster() was called by PUN");
            if (isConnecting)
            {
                PhotonNetwork.JoinRandomRoom();
            }
        }
        public override void OnJoinRandomFailed(short returnCode, string message)
        {
            Debug.Log("PUN Basics Tutorial/Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
            PhotonNetwork.CreateRoom(nullnew RoomOptions());
        }
 
        public override void OnDisconnected(DisconnectCause cause)
        {
            Debug.LogWarningFormat("PUN Basics Tutorial/Launcher: OnDisconnected() was called by PUN with reason {0}", cause);
        }
 
        public override void OnJoinedRoom()
        {
            Debug.Log("OnJoinedRoom Event");
            if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
            {
                Debug.Log("We load the 'Room for 1' ");
 
                PhotonNetwork.LoadLevel("Room for 1");
            }
        }
    }
}
cs


Launcher 스크립트에 PhotonNetwork.JoinRandomRoom() 으로 랜던룸에 입장을 시도 할때 방이없으면 접속에 실패하게되는데 해당 코드를 작성하지 않았다


OnJoinRandomFailed 콜백 메소드를 통하여 방이없을 때 방을 만들어보자


이 후 서버에 연결을 해보면 어제 만든 씬으로 이동하는 것을 볼 수 있다


대강 접속로직 알것같다



+ Recent posts