Skip to content
Published May 3, 2021
Photon has became much more of a standard in networking Unity3d + Industrial applications that I had expected. I have an interview tomorrow for a job that I would very much like to get, so I thought I would debrief on my previous experiences with Photon and do a little focused project beforehand. I have a few experiences with Photon. The first was when SwordStack was multiplayer and networked. I was working on some trying different modes of interpolation, and even messing around with bluetooth networking. This was a pretty deep dive where the client’s AI companions would switch to a second player if a controller was found. And back to AI if the controller was lost. I also worked on a game project that used PUN but I don’t remember much about it. Must have been 2013 or 2014. I searched for the name of the game but looks like it didn’t get far. Fast forward a year or so, 2015 or 2016 – I am Lead of R&D for an agency, and we get a project down the pipe for simulating a job site. This particular site had an instructor and student role. That project was done in a wild flurry of 90 hour weeks and had a lot of technical debt, but I remember Photon being an absolute breeze to use. It also was used in one of my client projects briefly when I worked as a contractor. So here is what I remember about Photon. I remember that there are functions that you call from client side code that are tagged as [RDP]. If you also had a Photon component on that GameObject. If another GameObject had that same component and ID, then that GameObject would receive an update of the data as a parameter in the similarly marked method. I recall that assigning the master / host client was a little bit fiddly, but I am sure a lot has changed.
  • I’m going to try to set up a simple change of UI and transformation based on input
  • Set up a ‘student’ and ‘teacher’ role such that the teacher can override the student’s input.
  • With a stretch goal of the instructor’s input overriding the student’s. Hopefully I can finish it today.
THE TASK
So my first problem is that the version of PUN that I own is now called Photon Unity Networking Classic – Free. But PUN 2 is now free! So no wall there. So at first I thought I would go ahead use an old app ID so that I wouldn’t have any wait period… but I realized that all my old projects with PUN have RPCs already defined. So I’m making a new one. Setting up the project, I realized that I probably ought to use TCP because this particular group would probably want a more secure packet. So first success was simply getting two clients to show the same changes. So I added a cylinder with some simple sin and cos movement, added a random lobby login, and true enough, I could see the transforms matching. Unfortunately, there was a lot of hiccups in the client, resulting some really poorly refined movement.
I modified SmoothSyncMovement to increase the amount of possible movement based on the amount of time in the delays in update. It became smoother. But not smooth enough.
I don’t like how SmoothSyncMovement works, it is incredibly jerky and was sending the cylinder to zero. So I made my own.
I recognize that with this particular simulation that I could simply be passing t to the client and the sin cos movement would update pleasantly. However, I happen to know that this application will require transforming to position in 3d space, and that this being smooth is important. After messing around with some different smoothing, I tried out the RPG example, which included this Photon Transform View Component.
This seems to give a pretty reasonably smooth positional update without much loss
Updating the UI Assigning something to a Photon View’s Observed Components will not magically make the state of that component appear to the client. Preventing the visual’s update when the UI component ‘does not belong to you’ takes some extra considerations.
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof (PhotonView))]
[RequireComponent(typeof(Toggle))]
public class PunToggle : Photon.PunBehaviour, IPunObservable
{
private Toggle _toggle;

void Awake()
{
_toggle = FindObjectOfType<Toggle>();
_toggle.onValueChanged.AddListener( delegate { ToggleValueChanged(_toggle.isOn); });
}

//PhotonTargets.Others should be the RPC mode, we don't want to flip this if we own it
private void ToggleValueChanged(bool toggled)
{
if (!photonView.isMine) return;

if(toggled )
this.photonView.RPC("ToggledOn", PhotonTargets.Others);
else
{
this.photonView.RPC("ToggledOff", PhotonTargets.Others);
}
}

[PunRPC]
public void ToggledOn(PhotonMessageInfo msgInfo)
{
_toggle.isOn = true;
}

[PunRPC]
public void ToggledOff(PhotonMessageInfo msgInfo)
{
_toggle.isOn = false;
}

public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (!photonView.isMine)
_toggle.interactable = false;
}
}
Share

Comments are closed.

Share