Topic: Multiplayer on the map - it's easy (Online Maps + Photon PUN2)
Script:
/* INFINITY CODE 2013-2018 */
/* http://www.infinity-code.com */
using System.Collections.Generic;
using ExitGames.Client.Photon;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Random = UnityEngine.Random;
namespace InfinityCode.OnlineMapsExamples
{
/// <summary>
/// Example of how to display the location of several users on the map at the same time usign Photon PUN2.
/// Drag the player marker to move it synchronously for all clients.
/// </summary>
public class SyncDraggingUsingPhoton : MonoBehaviourPunCallbacks
{
/// <summary>
/// Dictionary of other players
/// </summary>
public Dictionary<string, OnlineMapsMarker3D> otherPlayers;
/// <summary>
/// Array of marker prefabs
/// </summary>
public GameObject[] prefabs;
/// <summary>
/// Reference to the map
/// </summary>
private OnlineMaps map;
/// <summary>
/// Reference to the control
/// </summary>
private OnlineMapsTileSetControl control;
/// <summary>
/// Creates a marker for another player, and sets the position
/// </summary>
/// <param name="player"></param>
private void CreateOtherPlayer(Player player)
{
// Get player properties
Hashtable props = player.CustomProperties;
double longitude = (double)props["longitude"];
double latitude = (double)props["latitude"];
int prefabIndex = (int)props["prefab_index"];
string id = player.UserId;
// Create a new marker
OnlineMapsMarker3D marker = OnlineMapsMarker3DManager.CreateItem(longitude, latitude, prefabs[prefabIndex]);
marker.label = player.NickName;
otherPlayers.Add(id, marker);
}
/// <summary>
/// Called when the client is connected to the Master Server and ready for matchmaking and other tasks
/// </summary>
public override void OnConnectedToMaster()
{
// Create a new room or connect to an existing one
RoomOptions roomOptions = new RoomOptions();
roomOptions.IsVisible = false;
roomOptions.MaxPlayers = 4;
roomOptions.PublishUserId = true;
PhotonNetwork.JoinOrCreateRoom("Test Room", roomOptions, TypedLobby.Default);
double tlx, tly, brx, bry;
map.GetCorners(out tlx, out tly, out brx, out bry);
// Create current player marker
int prefabIndex = Random.Range(0, prefabs.Length);
double longitude = Random.Range((float)tlx, (float)brx);
double latitude = Random.Range((float)bry, (float)tly);
OnlineMapsMarker3D marker = OnlineMapsMarker3DManager.CreateItem(longitude, latitude, prefabs[prefabIndex]);
marker.label = "My Player";
// Make a marker draggable, and subscribe to the drag event
marker.SetDraggable();
marker.OnDrag += OnDrag;
// Center the map on the marker
map.position = marker.position;
// Create initial properties
Hashtable hashtable = new Hashtable
{
{"prefab_index", prefabIndex},
{"longitude", longitude},
{"latitude", latitude}
};
PhotonNetwork.SetPlayerCustomProperties(hashtable);
}
/// <summary>
/// Called when dragging a player marker
/// </summary>
/// <param name="marker">Player marker</param>
private void OnDrag(OnlineMapsMarkerBase marker)
{
// Update location in player properties
double longitude, latitude;
marker.GetPosition(out longitude, out latitude);
Hashtable hashtable = new Hashtable
{
{"longitude", longitude},
{ "latitude", latitude}
};
PhotonNetwork.SetPlayerCustomProperties(hashtable);
}
/// <summary>
/// Called when the LoadBalancingClient entered a room, no matter if this client created it or simply joined
/// </summary>
public override void OnJoinedRoom()
{
// Create markers for other players.
foreach (KeyValuePair<int, Player> pair in PhotonNetwork.CurrentRoom.Players)
{
Player player = pair.Value;
if (player.IsLocal) continue;
CreateOtherPlayer(player);
}
}
/// <summary>
/// Called when a remote player entered the room. This Player is already added to the playerlist
/// </summary>
/// <param name="otherPlayer">The player who entered the room</param>
public override void OnPlayerEnteredRoom(Player otherPlayer)
{
CreateOtherPlayer(otherPlayer);
}
/// <summary>
/// Called when a remote player left the room or became inactive
/// </summary>
/// <param name="otherPlayer">The player who left the room</param>
public override void OnPlayerLeftRoom(Player otherPlayer)
{
OnlineMapsMarker3D marker;
if (otherPlayers.TryGetValue(otherPlayer.UserId, out marker))
{
otherPlayers.Remove(otherPlayer.UserId);
OnlineMapsMarker3DManager.RemoveItem(marker);
}
}
/// <summary>
/// Called when custom player-properties are changed
/// </summary>
/// <param name="targetPlayer">Player that changed</param>
/// <param name="changedProps">Properties that changed</param>
public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
if (targetPlayer.IsLocal) return;
// Update player marker location
double longitude = (double)changedProps["longitude"];
double latitude = (double)changedProps["latitude"];
string id = targetPlayer.UserId;
OnlineMapsMarker3D marker;
if (otherPlayers.TryGetValue(id, out marker))
{
marker.SetPosition(longitude, latitude);
map.Redraw();
}
}
private void Start()
{
map = OnlineMaps.instance;
control = OnlineMapsTileSetControl.instance;
otherPlayers = new Dictionary<string, OnlineMapsMarker3D>();
// Connect to Photon as configured in the PhotonServerSettings file
PhotonNetwork.LocalPlayer.NickName = "Player " + Random.Range(0, 100000);
PhotonNetwork.ConnectUsingSettings();
}
}
}
Edit (2019.10.11):
Updated script for Online Maps v3.
Infinity Code Team.
Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.