This sample is based on the demoWorker scene provided with the Photon Packages available on the Ecosystem.
you can download it here directly:
Photon Server settings Setup
After you have setup Photon using the Photon Setup wizard, Make sure you turn Auto-join lobby to true, you can find this Setup Asset using the menu "Photon Unity Networking/Highlight Server settings".
The Scene set up is critical to grasp in order to understand how the various Fsm are working.
Scene reload on network status change:
The scene reload on the following network changes:
- When the user joins a room
- When the user creates a room
- When the user leave a room
- When the user is disconnected from the network.
This is important to understand that the various Fsm starts their process with this assumption, and because of that compulsory reload, Fsm needs to be disabled and enabled, which is explained next
GameObject enabling and disabling:
So: As the scene starts, gameObjects are enabled and disabled based on the current state of the photon network and User.
- if the user is in a room: the menu is disabled and the gameManager is enabled
- If the user is not in a room: the menu is enabled and the gameManager is disabled
This is a very effective and simple way of organizing processes, this means that an object is enabled, assumes a certain state, which makes process building easier, it doesn't need to do much condition checks.
note: It is also important to realize that on a real world scenario, other approaches are possible, gameObject can be created when required instead of disabled/enabled, scenes can be additivly composed to match the current scene, but that is another aspect of game management that is beyond the purpose of this demo, and would add a layer of complexity not required to understand the fundamentals of multi player development.
The player prefab plays a central role in this demo obviously, so it is essential to fully understand how it is rigged and how the various components work together to enable this object to beahve itsefl properly under multi player environment:
when you enter a room, your player gameObject ( that represent yourself) needs to be created on your application, but also on other running application that currently are in the same room as you. For this, Photon network ( and Unity network) have a simple mechanism to instantiate a gameObject over the network, and you need to follow three rules:
- Use Photon Network Instantiate action. If you simply create your player, it will only exists in your running application. so it is critical to make sure you are using this action
- The prefab you are using to instantiate MUST BE in a "Resources" folder, else Photon will complain.
- Have at least one photon view component attached to Prefab you are willing to instantiate over the network. You can find this photonView component in the standard unity menu. This component is the glue for the network system to keep track of your instance over the network. when you are joining a room with several players already in there, them players are automatically instantiated on your application for you to see them, this is all managed by the photonView component. DO NOT attempt to manage this yourself, this is the job of the network system to handle this. Your role it synchronize then data between the owner and the slaves ( concept explain next)
Ok, so we have our player prefab properly instantiating over the network, so you indeed have several of these prefab in a scene, one of them if you, the rest are other players. BUT since they are all sharing the same prefab, we need a mechanism to prevent you controlling all players! as you press the move forward input, you only want to control your player! So to do this, we need to enabled/disable the component responsible for controlling the player based on the user input. This is done in the fsm Fsm Photon player : Behavior set up (Prefab)
This fsm introduce a critical concept: the ownership of a GameObject. When you have a photonView component attached to a gameObject, you can query to know if this is yours or not ( that is does this gameObject represent your player or another users player). The action for this is Photon View Get Is Mine. So as you work your way through Fsm, you will need to ask this question a lot "Is this gameObject Mine?", if yes it represent the user, else it represent another user on the network.
Synchronizations over the network:
Now, the last aspect, but not the least :) how to synchronize then the player over the network?
For this, Playmaker makes it much easier than with standard scripting by hiding a lof of the work. Fsm Variable are featured with a check box "Network sync", by checking this, you effectively allow this variable to be synched over the network, so that ALL network instances of this Fsm share the same value.
When you have Fsm variable that are checked for synching over the network, YOU MUST have a photonView Component attached to the same gameObject observing this Fsm. Without this, it will simply not work.
That is not it tho. Once your variable is correctly synched, you need to decide on how to set and get this variable. for this, ask the question "Is this gameObject Mine?" using the action Photon View Get Is Mine, if it is "mine", then I MUST set this variable, this is my duty as the owner of this gameObject, if it is not mine, I MUST read and do something with it to reflect the changes. Typical example, synchronizing position of the player ( done in the fsm Fsm Photon player : Position synch (Prefab) ) , the owner ( when the answer to "is it mine?" is yes) MUST get the current position of the player and store it in a Fsm Vector3 variable that is checked to synch over the network, Slaves ( when the answer to "Is it mine?" is no) MUST read this variable and set their position to match, this is how synchronization is effectively done.
In order to get to the point, Fsms are organized by order of importance. this is so to get a good overview of the required work, and what is simply here to enhance the scene, without playing a central role to the multi player environment.
- Menu : Connection
- Menu : Connection failure
- Enabler : Enabler
- Game : Game Manager
- Game : Quit Manager
- Game : room players watcher
- Fsm Photon player : Variable synch repository (Prefab)
- Fsm Photon player : Behavior set up (Prefab)
- Fsm Photon player : Animation synch (Prefab)
- Fsm Photon player : Position synch (Prefab)
- Fsm Photon player : Rotation synch (Prefab)
- Menu : Create Room
- Menu : room listing gui
- Chat : Chat
- Chat : Chat target gui
- Chat : Chat users list
- Fsm Photon player : GameObject naming (Prefab)
- Game : Master Client switch watcher
- Menu : main menu
- Menu : Server stats GUI
- Menu : Join room by title
- Menu : Join random room gui