I am making a multiplayer game and I am at the MenuScene where I make the choose room - on one panel and create room - other panel . It works to create a room , but when I press to show the panel with "ChooseRoom" it doesn't appear anything. here is the script that I use.So it doesn't appear the prefab that I made with the RoomListing1(text)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SingletonReferences : MonoBehaviour
{
[SerializeField]
private MasterManager _masterManager;
}
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RoomListingsMenu : MonoBehaviourPunCallbacks
{
[SerializeField]
private Transform _content;
[SerializeField]
private RoomListing _roomListing;
private List<RoomListing> _listings = new List<RoomListing>();
private RoomsCanvases _roomsCanvases;
public void FirstInitialize(RoomsCanvases canvases)
{
_roomsCanvases = canvases;
}
public override void OnJoinedRoom()
{
_roomsCanvases.CurrentRoomCanvas.Show();
// _content.DestroyChildren();
_listings.Clear();
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
foreach (RoomInfo info in roomList)
{
//Removed from rooms list.
if (info.RemovedFromList)
{
int index = _listings.FindIndex(x => x.RoomInfo.Name == info.Name);
if (index != -1)
{
Destroy(_listings[index].gameObject);
_listings.RemoveAt(index);
}
}
//Added to rooms list.
else
{
int index = _listings.FindIndex(x => x.RoomInfo.Name == info.Name);
if (index == -1)
{
RoomListing listing = Instantiate(_roomListing, _content);
if (listing != null)
{
listing.SetRoomInfo(info);
_listings.Add(listing);
}
}
else
{
//Modify listing here.
//_listings[index].dowhatever.
}
}
}
}
}
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RoomListing : MonoBehaviour
{
[SerializeField]
private Text _text;
public RoomInfo RoomInfo { get; private set; }
public void SetRoomInfo(RoomInfo roomInfo)
{
RoomInfo = roomInfo;
_text.text = roomInfo.MaxPlayers + ", " + roomInfo.Name;
}
public void OnClick_Button()
{
PhotonNetwork.JoinRoom(RoomInfo.Name);
}
}
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestConnect : MonoBehaviourPunCallbacks
{
private void Start()
{
Debug.Log("Connecting to Photon...", this);
AuthenticationValues authValues = new AuthenticationValues("0");
PhotonNetwork.AuthValues = authValues;
PhotonNetwork.SendRate = 20; //20.
PhotonNetwork.SerializationRate = 5; //10.
PhotonNetwork.AutomaticallySyncScene = true;
PhotonNetwork.NickName = MasterManager.GameSettings.NickName;
PhotonNetwork.GameVersion = MasterManager.GameSettings.GameVersion;
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
Debug.Log("Connected to Photon.", this);
Debug.Log("My nickname is " + PhotonNetwork.LocalPlayer.NickName, this);
if (!PhotonNetwork.InLobby)
PhotonNetwork.JoinLobby();
}
public override void OnDisconnected(DisconnectCause cause)
{
Debug.Log("Failed to connect to Photon: " + cause.ToString(), this);
}
public override void OnJoinedLobby()
{
print("Joined lobby");
PhotonNetwork.FindFriends(new string[] { "1" });
}
public override void OnFriendListUpdate(List<FriendInfo> friendList)
{
base.OnFriendListUpdate(friendList);
foreach (FriendInfo info in friendList)
{
Debug.Log("Friend info received " + info.UserId + " is online? " + info.IsOnline);
}
}
}
Related
I'm trying to sync all the player names on server and client side, I'm following this tutorial, but I've made some changes to the code.
InitiateMultiplayer.cs
using Unity.Netcode;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
namespace Multiplayer
{
public class InitiateMultiplayer : MonoBehaviour
{
[Serializable]
public class ConnectionPayload
{
public string password;
public string playerName;
}
public struct PlayerData
{
public string PlayerName { get; private set; }
public PlayerData(string playerName)
{
PlayerName = playerName;
}
}
private static Dictionary<ulong, PlayerData> clientData;
// Start is called before the first frame update
void Start()
{
NetworkManager.Singleton.NetworkConfig.ConnectionApproval = true;
switch (Buttons.GameMode)
{
case "Host":
clientData = new Dictionary<ulong, PlayerData>();
clientData[NetworkManager.Singleton.LocalClientId] = new PlayerData(Buttons.PlayerName);
NetworkManager.Singleton.ConnectionApprovalCallback += ApprovalCheck;
NetworkManager.Singleton.StartHost();
break;
case "Client":
Debug.Log("Client Started");
var payload = JsonUtility.ToJson(new ConnectionPayload()
{
password = "",
playerName = Buttons.PlayerName,
});
byte[] payloadBytes = Encoding.ASCII.GetBytes(payload);
// Set password ready to send to the server to validate
NetworkManager.Singleton.NetworkConfig.ConnectionData = payloadBytes;
NetworkManager.Singleton.StartClient();
break;
default:
break;
}
}
public static PlayerData? GetPlayerData(ulong clientId)
{
if (clientData.TryGetValue(clientId, out PlayerData playerData))
{
return playerData;
}
return null;
}
private void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
{
Debug.Log("approving");
string payload = Encoding.ASCII.GetString(request.Payload);
var connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);
response.Approved = true;
response.Position = Vector3.zero;
response.Rotation = Quaternion.identity;
if (response.Approved)
{
response.CreatePlayerObject = true;
Debug.Log("approved");
response.PlayerPrefabHash = null;
response.Pending = false;
if (!clientData.TryGetValue(request.ClientNetworkId, out PlayerData playerData)) {
Debug.Log("we dont got data");
clientData[request.ClientNetworkId] = new PlayerData(connectionPayload.playerName);
}
}
}
}
}
Player.cs
using Unity.Netcode;
using UnityEngine;
using TMPro;
using Unity.Collections;
namespace Multiplayer
{
public class Player : NetworkBehaviour
{
[SerializeField] private TMP_Text displayNameText;
[SerializeField] private Renderer playerBody3D;
private NetworkVariable<FixedString32Bytes> displayName = new NetworkVariable<FixedString32Bytes>();
public override void OnNetworkSpawn()
{
if (!IsServer) { return; }
Debug.Log("Sapwned");
InitiateMultiplayer.PlayerData? playerData = InitiateMultiplayer.GetPlayerData(OwnerClientId);
if (playerData.HasValue)
{
Debug.Log("data -"+playerData.Value.PlayerName);
displayName.Value = playerData.Value.PlayerName;
}
}
private void OnEnable()
{
displayName.OnValueChanged += HandleDisplayNameChanged;
}
private void OnDisable()
{
displayName.OnValueChanged -= HandleDisplayNameChanged;
}
private void HandleDisplayNameChanged(FixedString32Bytes oldDisplayName, FixedString32Bytes newDisplayName)
{
if (IsClient) Debug.Log("client");
Debug.Log("Change in value"+newDisplayName.ToString());
displayNameText.text = newDisplayName.ToString();
}
}
}
The issue I'm facing is that the names are getting synced only on the server side, on the client side the palyer names are the default text.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[CreateAssetMenu(fileName = "NewItem", menuName = "Items/NewItem", order = 1)]
public class NewBehaviourScript : ScriptableObject
{
[HideInInspector]
public string buy = "BUY";
[HideInInspector]
public string OWNED = "EQUIP";
[HideInInspector]
public Color equipColor = new Color(0.53333f, 1.00000f, 0.30196f);
[HideInInspector]
public Color buyColor = new Color(1.00000f, 0.10196f, 0.10196f);
public new string name;
public float price;
public Sprite Image;
public bool Owned;
public float spreadAmmount;
public float damage;
public bool equiped;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DisplayItems : MonoBehaviour
{
public MoneyUpdate curency;
public NewBehaviourScript item;
public TextMeshProUGUI Cost;
public TextMeshProUGUI ItemName;
public Image image;
public TextMeshProUGUI buttonText;
public Button button;
private void Update()
{
if (item.Owned)
{
buttonText.text = "" + item.OWNED;
ColorBlock cb = button.colors;
cb.normalColor = item.equipColor;
button.colors = cb;
}
else
{
buttonText.text = "" + item.buy;
ColorBlock cb = button.colors;
cb.normalColor = item.buyColor;
button.colors = cb;
}
}
void Start()
{
Cost.text = "$" + item.price;
ItemName.text = "" + item.name;
image.sprite = item.Image;
}
public void BuyWeapon()
{
if (!item.Owned && item.price <= curency.money)
{
item.Owned = true;
PlayerPrefs.SetInt("Money", (int)curency.money - (int)item.price);
}
if (item.Owned)
{
item.equiped = true;
}
}
}
When i press the button to equip, bool is gonna set to true,but when i press the other button it equip booth
enter image description here
That s the shop system UI,that I made with the buttons in it,can t figgure out how i can equip only one once!
I have been stuck on this problem for a few months now. The problem being that I cannot properly instantiate my prefabs in the scene I want. I need the spawning to be one person on one team, and the rest on the other. But I'm not sure how to do that. What happens is that when I click the play button on my lobby menu, I get an error called "No cameras to display." I also noticed that the scene I want does load, but it doesn't switch to it because there are no cameras that are instantiated. I am using Photon 2. I am new to game development and your guys' help would be greatly appreciated! :)
I will post my code if that will help:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using TMPro;
using Photon.Realtime;
using System.Linq;
using System.IO;
public class Launcher : MonoBehaviourPunCallbacks
{
public static Launcher Instance;
[SerializeField] TMP_InputField roomNameInputField;
[SerializeField] TMP_Text errorText;
[SerializeField] TMP_Text RoomNameText;
[SerializeField] Transform RoomListBackground;
[SerializeField] Transform PlayerListBackground;
[SerializeField] GameObject roomListItem_pf;
[SerializeField] GameObject PlayerListItem_pf;
[SerializeField] GameObject startGameButton;
public PhotonView PV;
public int myTeam;
public GameObject myAvatar;
void Awake()
{
Instance = this;
}
void Start()
{
Debug.Log("Connecting to Master");
PhotonNetwork.ConnectUsingSettings();
}
public void Update()
{
PV = GetComponent<PhotonView>();
if (PV)
{
PV.RPC("RPC_GetTeam", RpcTarget.MasterClient);
}
if (myAvatar == null && myTeam != 0)
{
if (myTeam == 1)
{
if (PV.IsMine)
{
int spawnPicker = Random.Range(0, GameSetup.GS.spawnPointsTeamOne.Length);
myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Player"), GameSetup.GS.spawnPointsTeamOne[spawnPicker].position, GameSetup.GS.spawnPointsTeamOne[spawnPicker].rotation, 0);
}
}
if (myTeam == 2)
{
if (PV.IsMine)
{
int spawnPicker = Random.Range(0, GameSetup.GS.spawnPointsTeamTwo.Length);
myAvatar = PhotonNetwork.Instantiate(Path.Combine("PhotonPrefabs", "Player"), GameSetup.GS.spawnPointsTeamTwo[spawnPicker].position, GameSetup.GS.spawnPointsTeamTwo[spawnPicker].rotation, 0);
}
}
}
}
public override void OnConnectedToMaster()
{
Debug.Log("Connected to Master");
PhotonNetwork.JoinLobby();
PhotonNetwork.AutomaticallySyncScene = true;
}
public override void OnJoinedLobby()
{
MenuManager.Instance.OpenMenu("title");
Debug.Log("Joined Lobby");
}
public void CreateRoom()
{
if (string.IsNullOrEmpty(roomNameInputField.text))
{
return;
}
PhotonNetwork.CreateRoom(roomNameInputField.text);
MenuManager.Instance.OpenMenu("loading");
}
public override void OnJoinedRoom()
{
MenuManager.Instance.OpenMenu("room");
RoomNameText.text = PhotonNetwork.CurrentRoom.Name;
Player[] players = PhotonNetwork.PlayerList;
for (int i = 0; i < players.Count(); i++)
{
Instantiate(PlayerListItem_pf, PlayerListBackground).GetComponent<PlayerListItem>().Setup(players);
}
startGameButton.SetActive(PhotonNetwork.IsMasterClient);
}
public override void OnMasterClientSwitched(Player newMasterClient)
{
startGameButton.SetActive(PhotonNetwork.IsMasterClient);
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
errorText.text = "Room Creation Failed: " + message;
MenuManager.Instance.OpenMenu("error");
}
public void LeaveRoom()
{
PhotonNetwork.LeaveRoom();
MenuManager.Instance.OpenMenu("loading");
}
public void JoinRoom(RoomInfo info)
{
PhotonNetwork.JoinRoom(info.Name);
MenuManager.Instance.OpenMenu("loading");
}
public override void OnLeftRoom()
{
MenuManager.Instance.OpenMenu("title");
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
foreach (Transform trans in RoomListBackground)
{
Destroy(trans.gameObject);
}
for (int i = 0; i < roomList.Count; i++)
{
Instantiate(roomListItem_pf, RoomListBackground).GetComponent<RoomListItem>().Setup(roomList);
}
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
Instantiate(PlayerListItem_pf, PlayerListBackground).GetComponent<PlayerListItem>().Setup(newPlayer);
}
[PunRPC]
public void RPC_GetTeam()
{
myTeam = GameSetup.GS.nextPlayersTeam;
GameSetup.GS.UpdateTeam();
PV.RPC("RPC_SentTeam", RpcTarget.OthersBuffered, myTeam);
}
[PunRPC]
public void RPC_SentTeam(int whichTeam)
{
myTeam = whichTeam;
}
}
I am doing a multiplayer game and I want to know how I can add a minimum number of players for a user to enter a room . Like to not be alone till one player is connected at least. What I should add to my script? I have this Room Options function but It doesn't work too add like Min players or something to it. (I expected if is MaxPlayers to exist MinPlayers too)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon;
using Photon.Pun;
using UnityEngine.UI;
using Photon.Realtime;
public class MPManager : MonoBehaviourPunCallbacks, IPunObservable
{
public PlayFabAuth auth;
public string GameVersion;
public Text connectState;
public GameObject[] DisableOnConnected;
public GameObject[] DisableOnJoinRoom;
public GameObject[] EnableOnConnected;
public GameObject[] EnableOnJoinRoom;
public LoadedPlayer loadPlayer;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
connectState.text = "Connection: " + PhotonNetwork.NetworkClientState;
}
public void ConnectToMaster()
{
// PhotonNetwork.connectionStateDetailed
PhotonNetwork.ConnectUsingSettings();
}
public override void OnConnectedToMaster()
{
PhotonNetwork.JoinLobby();
}
public override void OnJoinedLobby(){
foreach(GameObject disable in DisableOnConnected){
disable.SetActive(false);
}
foreach (GameObject enable in EnableOnConnected){
enable.SetActive(true);
}
}
public void CreateOrJoin()
{
PhotonNetwork.LeaveLobby();
PhotonNetwork.JoinRandomRoom();
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
RoomOptions rm = new RoomOptions
{
MaxPlayers = 3,
IsVisible = true
};
int rndID = Random.Range(0, 3000);
PhotonNetwork.CreateRoom("Default: " + rndID, rm, TypedLobby.Default);
}
public override void OnJoinedRoom()
{
foreach (GameObject disable in DisableOnJoinRoom)
{
disable.SetActive(false);
}
foreach (GameObject enable in EnableOnJoinRoom)
{
enable.SetActive(true);
}
Debug.Log(loadPlayer.currentPlayer.name);
GameObject player = PhotonNetwork.Instantiate(loadPlayer.currentPlayer.name , Vector3.zero, Quaternion.identity, 0);
}
public override void OnLeftRoom()
{
PhotonNetwork.LeaveRoom();
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
throw new System.NotImplementedException();
}
}
Thank you for choosing Photon!
You need to get the count of actors (PhotonNetwork.CurrentRoom.PlayerCount) when you join the room (OnJoinedRoom) or when another player joins the room (OnPlayerEnteredRoom). When the number of actors joined is enough for you, start the game logic, e.g. load scene, send a custom event etc.
I want to create a ProbeManager where I can move around probes using Handles. Here is my MonoBehaviour and its Custom Editor:
MonoBehaviour:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class ProbeManager : MonoBehaviour
{
public Probe[] probes;
[System.Serializable]
public class Probe
{
public Vector3 pos;
public float radius;
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.white;
for (int i = 0; i < probes.Length; i++)
{
Probe probe = probes[i];
Gizmos.DrawWireSphere(probe.pos, probe.radius);
}
}
}
Custom Editor:
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(ProbeManager))]
public class ProbeManagerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
}
protected virtual void OnSceneGUI()
{
ProbeManager probe_manager = (ProbeManager)target;
EditorGUI.BeginChangeCheck();
for (int i = 0; i < probe_manager.probes.Length; i++)
{
probe_manager.probes[i].pos = Handles.PositionHandle(probe_manager.probes[i].pos, Quaternion.identity);
}
EditorGUI.EndChangeCheck();
}
}
The problem is that when I change probes' properties be it radius or position through Inspector it works fine. But when I try to move them aroung with Handles they teleport back to its previous position after I press Play.
I suspect it has something to do with serialization but thats it :(
I should have done this through serializedObject:
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(ProbeManager))]
public class ProbeManagerEditor : Editor
{
SerializedProperty probes_prop;
private void OnEnable()
{
probes_prop = serializedObject.FindProperty("probes");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
}
protected virtual void OnSceneGUI()
{
ProbeManager probe_manager = (ProbeManager)target;
for (int i = 0; i < probe_manager.probes.Length; i++)
{
EditorGUI.BeginChangeCheck();
Vector3 position = Handles.PositionHandle(probe_manager.probes[i].pos, Quaternion.identity);
SerializedProperty probe = probes_prop.GetArrayElementAtIndex(i);
SerializedProperty probe_pos = probe.FindPropertyRelative("pos");
if (EditorGUI.EndChangeCheck() == true)
{
probe_pos.vector3Value = position;
serializedObject.ApplyModifiedProperties();
}
}
}
}