Photon PUN
Exemple of Photon PUN integration
This exemple is pseudo code giving an idea on how to implement our Network module.
It may be different based on your Network Architecture and we recommend you to develop your own implementation.
PhotonConnectManager is a global script attached one time to get information if the local player joined a room and then instantiate its prefab.
Player is a script attached to the player prefab and will register and unregister if its local player or a remote player.
PhotonConnectionManager.cs
Player.cs
using Photon.Pun;
using Kinetix;
public class PhotonConnectionManager : MonoBehaviourPunCallbacks
{
// Called when local player joined room
public override void OnJoinedRoom()
{
GameObject gameObject = PhotonNetwork.Instantiate(PLAYER_PREFAB, Vector3.zero, Quaternion.identity);
Player player = gameObject.GetComponent<Player>();
player.Init()
}
}
using Photon.Pun;
using Kinetix;
public class Player : MonoBehaviourPun, IPunObservable
{
private string peerID;
private KinetixCharacterComponent Kcc;
private KinetixNetworkedPose nextPose;
private double timer = 0;
private double previousTimer = 0;
private void Init()
{
Animator animator = GetComponent<Animator>();
if (photonView.AmOwner)
{
// Player is local player
KinetixCore.Animation.RegisterLocalPlayer(animator);
}
else
{
peerID = PhotonView.Get(this).ViewID;
// Player is remote player
KinetixCore.Network.RegisterRemotePeerAnimator(peerID, animator);
}
}
public void ApplyReceivedPose(KinetixNetworkedPose pose, double timestamp)
{
((KinetixCharacterComponentRemote) Kcc).ApplyPose(pose, timestamp);
}
public void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
{
if (Kcc == null) return;
if (stream.IsWriting)
{
// Timer Handling
if (previousTimer == 0)
{
previousTimer = info.SentServerTime;
}
timer += info.SentServerTime - previousTimer;
previousTimer = info.SentServerTime;
// Send info only 60 times per second
if (timer < 1/60) return;
timer = 0;
// Pose sending
bool previousPoseWasNull = nextPose == null;
nextPose = ((KinetixCharacterComponentLocal) Kcc).GetPose();
if (nextPose != null)
{
stream.SendNext(nextPose.ToByteArray());
}
else if (!previousPoseWasNull)
{
stream.SendNext(new byte[0]);
}
}
else
{
if (stream.Count > 0)
{
byte[] frameData = (byte[]) stream.ReceiveNext();
nextPose = KinetixNetworkedPose.FromByte(frameData);
}
ApplyReceivedPose(nextPose, info.SentServerTime);
nextPose = null;
}
}
private void OnDestroy()
{
if (photonView.AmOwner)
{
KinetixCore.Animation.UnregisterLocalPlayer();
KinetixCore.Network.UnregisterAllRemotePeers();
}
else
{
KinetixCore.Network.UnregisterRemotePeer(peerID);
}
}
}
Last modified 1mo ago