General direction to get started with Unity

Options

Hello there!

This is my first time trying to implement the multiplayer mechanics on any of my games, and I'm a bit lost on what I should be adding the photon view component or not, and which components should be present in the scene, and which on the player.

So far I followed some tutorials online and managed to create a "Connect to the server" page, with username input, a lobby, change all players to a new scene and spawn new players on the new scene. But I have a lot of questions on what I should do now!

Let me quickly explain how my game works:

*There're two types of characters, the Summoner and the Hero. The Hero should escape the enemies that the summoner spawn for the maximum amount of time possible. When the Hero dies, the match ends.

*The camera should follow the Hero at all times, the Summoner should see the Hero running around.

*The Hero will automatically shoot at the enemies.

*All the enemies are instantiated using Photon.Instantiate and (should be) quickly deactivated and added to a pool. (They're added to the pool, but aren't deactivating, don't know why) They contain a photon view, photon transform classic view and photon animator. But they don't appear to the Hero when the Summoner spawns (set active from pool) them.

*The Summoner clicks on the screen and summon an enemy that will automatically follow the Hero. The enemy comes from the pool generated earlier.

You can test how the game is here https://beorgames.itch.io/revenots-conquest, I'm basically taking the local multiplayer and making it online.

Questions:

  1. The enemies are controlled by an enemy manager script that is present in the scene, are there going to be two enemy managers if I spawn two players in the scene? Or is it controlled by the scene??
  2. Should I add a camera to the Summoner as well? currently the camera is set up on the scene.
  3. The UI is currently present in the scene, should it be loaded together with every player?

If you can point me to good tutorials explaining what should be present in the scene and what should be instantiated with the character I really appreciate it!


Also, I'm getting an error when the two character login:

Exiting receive thread (inside loop). Server: wss://GCAMS126.exitgames.com:19091:0 Error: An exception has occurred while receiving.

UnityEngine.Debug:LogError (object)

Photon.Realtime.LoadBalancingClient:DebugReturn (ExitGames.Client.Photon.DebugLevel,string) (at Assets/Photon/PhotonRealtime/Code/LoadBalancingClient.cs:2564)

ExitGames.Client.Photon.SocketWebTcp/<ReceiveLoop>d__12:MoveNext () (at Assets/Photon/PhotonLibs/WebSocket/SocketWebTcp.cs:317)

UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr)

Answers

  • Tobias
    Options
    1. You write "enemy manager script that is present in the scene". So this would mean one per client. You don't want to run it on just one client usually, so it makes sense to disable it unless the client is the Master Client.
    2. It does not hurt to have the camera in the scene. As long as there is only one, it's fine.
    3. Again: If it works, it's fine. It is not networked in any way, so keep it in the scene. If needed, pass a reference of the local player.

    I can't help with the error without context. How to get help.

  • BeorGames
    BeorGames
    edited June 2022
    Options

    Hi Tobias,

    Thank you very much for your reply.

    I've managed to make the enemies move toward the player and I'm correctly tracking the player with the camera.

    I'm still encountering issues with causing damage to the player and the enemies, none of them are taking any damage...

    Each one of them has a CharacterStats component with a TakeDamage function. This is how I'm implementing this:

    if (SessionManager.instance.onlineMode)
        {
          PhotonView photonView = PhotonView.Get(this);
          photonView.RPC("TakeDamage", RpcTarget.All, damage);
        }
        else
          TakeDamage(damage);
    


    And the TakeDamage function works like this:

      [PunRPC]
      public virtual void TakeDamage(int damage)
      {
        float randomizeDamage = damage * Random.Range(.8f, 1.3f);
        damage = (int)randomizeDamage;
        damage -= Defence.GetValue();
        damage = Mathf.Clamp(damage, 1 + (int)(randomizeDamage * .1f), damage); // Used to prevent taking no damage
    
        // Create the damage pop up object
        GameObject damagePopUp = PoolInitializer.Instance.GetPoolObject("DamagePopUp", true, PoolInitializer.Instance.transform);
        // Set it's position to this object's position and place it a little above the ground
        damagePopUp.transform.position = transform.position;// new Vector3(transform.position.x, transform.position.y + 1.5f, transform.position.z);
        // Configure the damage popup     
        if (colorParam == 0 && this is PlayerStats)
          damagePopUp.GetComponent<DamagePopUp>().Setup(damage, 1);
        else
          damagePopUp.GetComponent<DamagePopUp>().Setup(damage, colorParam);
    
        // Reduce health
        CurrentHealth -= damage; 
        CurrentHealth = (int)Mathf.Clamp(CurrentHealth, 0, TotalHealth.GetValue());
    
        if (CurrentHealth < 1)
        {
          if (SessionManager.instance.onlineMode)
          {
            PhotonView photonView = PhotonView.Get(this);
            photonView.RPC("Die", RpcTarget.All);
          }
          else
            Die();
        }
        colorParam = 0; // Resets color
      }
    

    The enemy attacks the player when it's close enough to him, it's controlled by a trigger collider. I'm getting this message "PhotonAnimatorView: When using triggers, make sure this component is last in the stack."

    What am I doing wrong?

  • Tobias
    Tobias admin
    edited June 2022
    Options

    Does that mean you sync the attack just via a trigger in an animation?

    Triggers in animations are a bit tricky to sync. The message points out you should order the triggers accordingly.

    I think I would sync the "attack" action explicitly via RPC or OnPhotonSerializeView. Then play the related animation based off that.

    Did you check if the RPC is getting called at all? If no damage is taken?

    It's really quite hard to help, not knowing project. Is TakeDamage being called?