Unity 5.3+ Networking Load Next Level - unity3d

In a networked game project following on from the Unity Multiplayer Tutorial, how is one supposed to go about changing scene to a new level/map while preserving camera/player GO/health etc. in one overarching master scene. (e.g. Gameplay.unity with Level1.unity or Level2.unity added to it)
All related help seems to be legacy code, singleplayer solutions or a more specialized circumstance. The current Unity 5.5 documentation suggests ServerChangeScene - which only seems to provide half the solution.
Does something like ServerAddScene and ServerGetScene exist?
Attempted solutions have been using DontDestroyOnLoad on known GameObjects in the master scene and keep a currentMapNumber variable synced between client NetworkManagers that gets updated when a player reaches the end-of-level trigger. This is then checked in the Update() method and either calls
networkManager.ServerChangeScene("Level" + networkManager.GetComponent<NetGame>().mapNumber);
or
SceneManager.LoadScene("Level" + networkManager.GetComponent<NetGame>().mapNumber, LoadSceneMode.Additive);
neither of which work as expected.

I am able to do this through an additive scene loading i used this code.
[ClientRpc]
public void RpcLoadLevelAcrossNetwork() {
SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
}
ClientRpc will load the new scene to all connected clients and additive scene loading will allow you to preserve camera/player GO/health etc

Related

Unity Navmesh bake multiple maps in the same scene

I have an scene with multiple maps, and when the game starts I randomly activate one of the maps and keep the others inactive.
My problem is that I can only have one the maps baked, because when I change to bake other map it's overwrited by the previous bake.
I search for other post to try baking at runtime but is seems it's not possible.
Is there a way to have multiple bakes or to bake only the active map at runtime?
To solve the problem, you can call the bake navigation code after the level changes.
Bake Navigation Inside Unity Editor
This code works similar to what is in the Unity Editor. Just make sure your Navigation Static object is enabled before using it.
The NavMeshBuilder class will allow this. In the code bellow.
using UnityEditor.AI;
...
public void Generate()
{
GenerateLevel(); // for e.g
NavMeshBuilder.BuildNavMesh();
}
Bake Navigation in Runtime
To bake in runtime, you need to download the necessary NavMeshComponents.
The component's will give you a NavMeshSurface component. It does not require static navmesh and works locally. Add component to all of your game ground's then put them in a list as the code bellow. After each run of the game, it is enough to BuildNavMesh all or part of them.
public List<NavMeshSurface> surfaces;
public void Start()
{
GenerateLevel(); // for e.g
surfaces.ForEach(s => s.BuildNavMesh());
}
Also this tutorial from Brackeys will help you so much.

Why is the NetworkIdentity component making my Game Object invisible? (Unity)

Currently trying to make a multiplayer snake game, I have never made a multiplayer game before. I am having a very strange issue where whenever I add the NetworkIdentity component to my 'Snake' game object, it becomes invisible, but is still there. The game is still functional; you just can't see the snake.
I have two pictures attached, one is the game with the NetworkIdentity component, one is the game without it. Thank you for the help.
Without component
With component
A) your image labels seem to be flipped .. exchange the Without and With ;)
and B) Afaik this is the expected behavior for any GameObject with a NetworkIdentity as long as you are not connected to any network yet. It will get enabled once you host or join a session.
You probably would rather convert this into the player prefab though and not have it in your scene from the beginning but rather let the NetworkManager automatically spawn it for every player in the session including yourself.

Unity | How to play animations that are stored in a variable (without having them in the animator)

I'm creating a 2D fighting game, where the player can choose from a number of fighters. the fighters have different attacks with different animations.
the data (damage, hitbox, cast time, animation, etc.) for every attack is stored in a Scriptable Object that is then triggered by the player script. this worked out fine so far, but I can't find out how to play an animation from code without needing it to be in the animator.
I've tried several solutions that I found here but they seem to end up having to fall back to putting the animation in the animator.
but I can't find out how to play an animation from code without needing it to be in the animator.
You will need the Animator-Component to run an animation.
But you can assign the animation you want to play at runtime. For this you need the RuntimeAnimationController to hold the AnimatorController-object and assign it to your Animator (in code).
You do not necessarily need the Animator component as stated in this answer.
There is also the Animation component. It is marked as legacy but is still quite powerful especially when you do not need to configure an entire state machine but want to rather simply playback single AnimationClip. Might be the reason why this still makes it into newer Unity versions:
public AnimationClip clip;
private void Awake()
{
var animation = GetComponent<Animation>();
animation.clip = clip;
animation.Play();
}
Also see Animation.Play

My Game object is not visible when I try and spawn in multiplayer

When I press the Lan host button when in unity multiplayer, it uses the prefab I assigned and Runner(Clone) appears in the hierarchy. But it does not appear on the screen. Then when you go into the scene view you see that there is an object but that for some reason it is not visible. What is the problem causing this and how do I fix it?
There can be many issues but I will give you a list of things to check.
Is the object visible in the host / server? is the camera position / rotation can properly view the spawned object's position? Have you spawned the object using Instantiate in the same way of Single Player, or properly used the Unity Network's way of instantiating?
This Unity Networking Tutorial talks in detail how to set up multiplayer game with a very concrete example. If you are new to Unity Networking, I recommend you start with the tutorial. The following shows how to instantiate objects in Multiplayer:
[Command]
void CmdFire()
{
// This [Command] code is run on the server!
// create the bullet object locally
var bullet = (GameObject)Instantiate(
bulletPrefab,
transform.position - transform.forward,
Quaternion.identity);
bullet.GetComponent<Rigidbody>().velocity = -transform.forward*4;
// spawn the bullet on the clients
NetworkServer.Spawn(bullet);
// when the bullet is destroyed on the server it will automaticaly be destroyed on clients
Destroy(bullet, 2.0f);
}
Note that the above is not enough to instantiate objects over network. There are other stuff that must be set up in order to execute the above code. Multiplayer is very different from SinglePlayer and if you are not familiar with the code above, you should definitely go to check the Unity Networking Tutorial.
Few things to note:
Method must be tagged with [Command]
Method name must start with Cmd.
The linked tutorial is probably the only tutorial provided by Unity. (Unity Networking is infamous for its lack of documentation.)

using NetworkLobbyManager with dynamic NetworkStartPositions

Having some trouble getting the NetworkLobbyManager to honor my NetworkStartPositions. This stems from the fact I generate my board dynamically when the game scene is loaded in my GameManager object.
I tried disabling auto spawn in the NetworkLobbyManager but it prevents LobbyPlayers from spawning too.
I would move my GameManager or NetworkStartPosition Spawner up into the Lobby scene but that doesn't seem like the right answer.
Here's where I am in my project: https://github.com/jakecoffman/tanks-unity/tree/f397b8b4e494461b94c718f1997d7572e5c6821f
Any suggestions? Any other tips on my project are welcome too.
I found someone else's project on Github that overrides OnLobbyServerSceneLoadedForPlayer and sets the position of the game player. Still not sure how to use NetworkStartPosition, but this is simple enough!