1

I'm trying to pass two values in a return but I get an error.

By calling it I would be able to update the values that are in the playfab. Does anyone have an idea how to solve this? Thanks in advance. Every help is welcome.

Any suggestion that leads the winning player to the "Win" scene is welcome. since scenemanager is void. Any suggestion to resolve the issue is welcome.

Hello, it's a possible solution, but always at the end of the game, the loser is the winner, I've already reversed the order of the "scenes" but the result is always the same, the loser goes to "scene" "Win", does anyone have an idea how to fix this statment if/else to make it work properly?

Update Real Problem this possible sollution

 public void CheckWinCondition()
    {
        // If we're not currently playing the game, return.
        if (gameState != GameState.Playing) return;

        // Get the winning player.
        Player winningPlayer = GetWinningPlayer();
        bool hasWon = false;

        switch (gameMode)
        {
            case GameModeType.ScoreBased:
                hasWon = winningPlayer.score >= winningScore;
                if (hasWon)
                {

                    SceneManager.LoadScene("Menu");
                }
                else
                {

                    SceneManager.LoadScene("Win");
                }
                break;
            case GameModeType.TimeBased:
                hasWon = Time.time > startTime + timeLimit;
                if (hasWon)
                {

                    SceneManager.LoadScene("Menu");
                }
                else
                {

                    SceneManager.LoadScene("Win");
                }
                break;
        }

        // If the conditions are right for a win - then that player wins.
        if (hasWon)
        
            photonView.RPC("WinGame", PhotonTargets.All, winningPlayer.networkPlayer.networkID);
           
       

    }

I saw that the tuple implementation has to be done, but as I even tried to implement the tuple. code snippet that I'll leave here below but also without success Unsuccessful attempt to declare variables.(That's not what's causing the error, it's just my attempt...) I tried without success :(

    // Returns the player who is currently ahead in score.
public Player GetWinningPlayer (int[] args)
{
  
    Player winningPlayer = PlayerManager.inst.players[0].player;

    // Loop through all players, except for the first one as they're winning by default.
    for (int x = 1; x < PlayerManager.inst.players.Length; ++x)
    {
        Player curPlayer = PlayerManager.inst.players[x].player;

        if(curPlayer.score > winningPlayer.score)
            winningPlayer = curPlayer;
    }
      {
        
        (var winningPlayer, var SceneManager.LoadScene("Win")) = GetData();
    }
   
    return GetData();
}

REAL PROBLEM --->

Code snippet where the error is ->

// Returns the player who is currently ahead in score.
public Player GetWinningPlayer()
{
    Player winningPlayer = PlayerManager.inst.players[0].player;

    // Loop through all players, except for the first one as they're winning by default.
    for (int x = 1; x < PlayerManager.inst.players.Length; ++x)
    {
        Player curPlayer = PlayerManager.inst.players[x].player;

        if (curPlayer.score > winningPlayer.score)
            winningPlayer = curPlayer;
    }
   
    return (winningPlayer, SceneManager.LoadScene("Win")); <--- error line 212
}

error->

 \Scripts\Managers\GameManager.cs(212,32): error CS8210: A tuple may not contain a value of type 'void'.

Full CODE -->

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using System;
public class GameManager : MonoBehaviour
{
    public GameState gameState;                         // Current state of the game.
    public GameModeType gameMode;                       // Game Mode we're currently playing.
    public SpellDistributionType spellDistribution;     // How the spells are given to the player in-game (not including pickups).

    [Header("Win Conditions")]
    [HideInInspector]
    public int winningScore;                // The score needed to win the game (Score Based game mode).
    [HideInInspector]
    public float timeLimit;                 // Time until the game ends (Time Based game mode).
    private float startTime;                // Time the game started - used to keep track of time remaining.
    public float endGameHangTime;           // How long do we wait after the game ends, before going back to the menu?

    [Header("Death")]
    public float deadDuration;              // The time between the player dying and respawning.
    public float minYKillPos;               // Kills the player if they go below this height (so they don't fall forever).

    [Header("Components")]
    public PhotonView photonView;           // PhotonView component.
    private Camera cam;                     // Main camera, used to calculate the min Y kill pos.

    // Map
    [HideInInspector]
    public Vector3[] spawnPoints;           // Array of player spawn points.
    [HideInInspector]
    public bool mapLoaded;                  // Has the map loaded in?

    // Events
    [HideInInspector] public UnityEvent onMapLoaded;            // Called when the map has been loaded in.
    [HideInInspector] public UnityEvent onPlayersReady;         // Called when all the players are spawned in and ready to go.
    [HideInInspector] public UnityEvent onGameStart;            // Called when the game begins and the players can start fighting.
    [HideInInspector] public System.Action<int> onGameWin;      // Called when a player has won the game.

    // Instance
    public static GameManager inst;

    #region Subscribing to Events

    void OnEnable ()
    {
        // Subscribe to events.
        onMapLoaded.AddListener(OnMapLoaded);
        onPlayersReady.AddListener(OnPlayersReady);
    }

    void OnDisable ()
    {
        // Un-subscribe from events.
        onMapLoaded.RemoveListener(OnMapLoaded);
        onPlayersReady.RemoveListener(OnPlayersReady);
    }

    #endregion

    void Awake ()
    {
        #region Singleton

        // If the instance already exists, destroy this one.
        if(inst != this && inst != null)
        {
            Destroy(gameObject);
            return;
        }

        // Set the instance to this script.
        inst = this;

        #endregion

        SetState(GameState.Initiation);
    }

    void Start ()
    {
        if(!PhotonNetwork.inRoom)
        {
            Debug.LogError("Cannot directly play this scene before connecting to network! <b>Start game in Menu scene.</b>");
            return;
        }

        // Initiate the game mode.
        InitiateGameMode();

        // Load the map.
        MapLoader.inst.LoadMap(PhotonNetwork.room.CustomProperties["map"].ToString());

        // Get the camera.
        cam = Camera.main;
    }

    void Update ()
    {
        // Are we currently playing the game?
        if(gameState == GameState.Playing)
        {
            // Host checks win condition every frame if it's a Time Based game mode.
            if(PhotonNetwork.isMasterClient && gameMode == GameModeType.TimeBased)
            {
                if(Time.time > startTime + timeLimit)
                    CheckWinCondition();
            }
        }
    }

    // Called when the map has been loaded in.
    void OnMapLoaded ()
    {
        // Calculate the min Y kill pos.
        minYKillPos = MapLoader.inst.GetLowestPoint() - 4.0f;

        // When the map has been loaded, tell everyone we're in the game and ready to go.
        if(PhotonNetwork.inRoom)
            NetworkManager.inst.photonView.RPC("ImInGame", PhotonTargets.AllBuffered);
    }

    // Called when all the players are spawned and ready to go.
    void OnPlayersReady ()
    {
        SetState(GameState.PreGame);
    }

    // Gets the gamemode from custom properties.
    void InitiateGameMode ()
    {
        int gm = (int)PhotonNetwork.room.CustomProperties["gamemode"];
        int gmProp = (int)PhotonNetwork.room.CustomProperties["gamemodeprop"];

        gameMode = (GameModeType)gm;

        switch(gameMode)
        {
            case GameModeType.ScoreBased:
                winningScore = gmProp;
                break;
            case GameModeType.TimeBased:
                timeLimit = (float)gmProp;
                break;
        }
    }

    // Called by the host after the countdown to begin the game.
    [PunRPC]
    public void StartGame ()
    {
        SetState(GameState.Playing);
        startTime = Time.time;
        onGameStart.Invoke();
    }

    // Checks if a player / can win the game. If so - end the game.
    public void CheckWinCondition ()
    {
        // If we're not currently playing the game, return.
        if(gameState != GameState.Playing) return;

        // Get the winning player.
        Player winningPlayer = GetWinningPlayer();
        bool hasWon = false;

        switch(gameMode)
        {
            case GameModeType.ScoreBased:
                hasWon = winningPlayer.score >= winningScore;
                break;
            case GameModeType.TimeBased:
                hasWon = Time.time > startTime + timeLimit;
                break;
        }

        // If the conditions are right for a win - then that player wins.
        if(hasWon)
            photonView.RPC("WinGame", PhotonTargets.All, winningPlayer.networkPlayer.networkID);
    }

    // Called when a player wins the game.
    [PunRPC]
    public void WinGame (int winningPlayer)
    {
        SetState(GameState.EndGame);
        onGameWin.Invoke(winningPlayer);

        // Go back to the menu in 'endGameHangTime' seconds.
        Invoke("GoBackToMenu", endGameHangTime);
    }

    // Called after a player wins the game, we go back to the menu.
    void GoBackToMenu ()
    {
        NetworkManager.inst.HostBackToMenu();
    }

    // Returns the player who is currently ahead in score.
    public Player GetWinningPlayer()
    {
        Player winningPlayer = PlayerManager.inst.players[0].player;

        // Loop through all players, except for the first one as they're winning by default.
        for (int x = 1; x < PlayerManager.inst.players.Length; ++x)
        {
            Player curPlayer = PlayerManager.inst.players[x].player;

            if (curPlayer.score > winningPlayer.score)
                winningPlayer = curPlayer;
        }
       
        return (winningPlayer, SceneManager.LoadScene("Win"));
    }

    // Sets the current game state.
    public void SetState (GameState state)
    {
        gameState = state;
    }

    // If this is of game mode Score Based, return the remaining time.
    public float TimeRemaining ()
    {
        return (startTime + timeLimit) - Time.time;
    }
}

// The game state keeps track of the current state of the game. This can dictate what gets checked and what things are allowed to happen.
public enum GameState
{
    Initiation,         // If we're currently waiting for players, spawning the map, initiating the players.
    PreGame,            // Counting down before the game begins.
    Playing,            // When the game is in progress.
    EndGame             // When the game has ended and a player has won.
}

// The game mode dictates the win condition for the game.
public enum GameModeType
{
    ScoreBased,         // First player to a specific score (kills) - wins.
    TimeBased           // After a set duration, the player with the most kills wins.
}

// How the spells are given to the player in-game (not including pickups).
public enum SpellDistributionType
{
    RandomOnStart,      // Random spell at the start of the game.
    RandomOnSpawn       // Random spell everytime the player spawns.
}
Davi
  • 67
  • 1
  • 14
  • 1
    `SceneManager.LoadScene` doesn't return a value. Are you trying to return a function to call later? It isn't clear why you need to return two values. – Retired Ninja Aug 18 '22 at 02:14
  • @RetiredNinja Hello, it's a scene that is informed to the player data and also the update of the same, I thought it could be easier. but I also have the StartCloudUpdatePlayerStats() method that updates but the error is the same. Attention the complete code is not with the playfab dependencies much less the code of the StartCloudUpdatePlayerStats() method, I'm just wanting to try another way. But the error itself is the same, I need to pass two values but every way I try I get the same error. Thanks again for your comment. – Davi Aug 18 '22 at 02:23
  • Because as was cited. Load scene doesnt return a value. So retired Ninja is right and the question still stands. What is the point of the second value. What are you trying to do with it – BugFinder Aug 18 '22 at 07:49
  • @BugFinder Hello, I need to take the player to a winning scene, but when I put it before or after the "return" the losing player is the one who is taken to the scene so I thought a lot and I believe I should call this scene within the "return". Thanks again for your comment. – Davi Aug 20 '22 at 17:50
  • No. The scene is loaded by the load scene. There is nothing of it to return – BugFinder Aug 20 '22 at 17:56
  • @BugFinder I understand, well I've tried everything, could you, analyzing my code, suggest a possible solution to this issue? I've been trying for several days, I've tried several things but all to no avail. Thanks in advance for your attention. – Davi Aug 20 '22 at 18:00
  • Somewhere there must be some code you can add that says. If winning player=me load win else load lose – BugFinder Aug 20 '22 at 18:09
  • @BugFinder I really tried in several parts of the code but without success it is always displayed to the loser the "scene" I tried some "if" conditions but also without success, I took this code to learn and try to create something simple but it is becoming something difficult. Thanks for the support. – Davi Aug 20 '22 at 18:21
  • @BugFinder Please if possible check my implements for possible solution, thanks in advance thats in top of ask this update question. – Davi Aug 20 '22 at 20:38
  • @RetiredNinja Please if possible check my implements for possible solution, thanks in advance thats in top of ask this update question. – Davi Aug 20 '22 at 20:38
  • Its not clear how you are networking these players and im in hospital on a phone. So you would need to find a point where a given player is recognised as the winner and instruct it to do win and the rest to do lose – BugFinder Aug 20 '22 at 21:14

2 Answers2

1

The problem is most likely in this line: (var winningPlayer, var SceneManager.LoadScene("Win")) = GetData();

  1. You can not set a variable of name SceneManager.LoadScene("Win") because that is a function, not a variable. If you want to set a variable to a function's return value, do var foo = SceneManager.LoadScene("Win"); (See 3)
  2. You are putting the variable assignments in brackets, meaning it thinks that you are making a tuple out of them.
  3. LoadScene does not have a return value.

Correct code would look like this. var winningPlayer = GetData(); SceneManager.LoadScene("Win");

EDIT: Sorry, forgot about the actual problem: return (winningPlayer, SceneManager.LoadScene("Win")); You can not return a void, it does not have a return value. Simply return winningPlayer and call LoadScene somewhere else.

MrDiamond
  • 958
  • 3
  • 17
  • Hi thanks for your comment, it gives error, and even if I call scenemanager after the return. The losing player goes to the "Win" scene so any solution that really takes the winning player to the correct scene would be ideal but I tried to implement it but without success, my only alternative would be to call him on the return right after winningplayer but every way I try it goes wrong . – Davi Aug 20 '22 at 03:37
  • Please if possible check my implements for possible solution, thanks in advance thats in top of ask this update question. – Davi Aug 20 '22 at 20:38
0

SOLVED. Problem Menu not exists. I m created new scene named by Loser. Thanks for all users for the support.

public void CheckWinCondition()
{
    // If we're not currently playing the game, return.
    if (gameState != GameState.Playing) return;

    // Get the winning player.
    Player winningPlayer = GetWinningPlayer();
    bool hasWon = false;

    switch (gameMode)
    {
        case GameModeType.ScoreBased:
            hasWon = winningPlayer.score >= winningScore;
            if (hasWon)
            {

                SceneManager.LoadScene("Win");
            }
            else
            {

                SceneManager.LoadScene("Loser");
            }
            break;
        case GameModeType.TimeBased:
            hasWon = Time.time > startTime + timeLimit;
            if (hasWon)
            {

                SceneManager.LoadScene("Win");
            }
            else
            {

                SceneManager.LoadScene("Loser");
            }
            break;
    }

    // If the conditions are right for a win - then that player wins.
    if (hasWon)
    
        photonView.RPC("WinGame", PhotonTargets.All, winningPlayer.networkPlayer.networkID);
       
    





}
Davi
  • 67
  • 1
  • 14