Having trouble with RTS

Options
greatsoccerman1
edited February 2023 in Fusion

Hey I am currently working on a RTS game and its multiplayer. The biggest issue I'm running into is being able to spawn objects. I need the game to be synced between client/host but also players be able to spawn objects. Is there a way to do this??


It makes the code very complicated and hard to do. For example if I have 5 wizards selected and I want them to all cast fireball at a target or "rain fire" on an area its hard to do that with the input system. What if I have 80 units all trying to spawn projectiles in a fight? RPCS would take to long.


Is there a way to sync this up in shared mode? Or will shared mode be enough maybe im misunderstanding shared mode


Another issue I have is trying to pass information when the unit is spawned from the host. Since the player who built the units reference is stored on the client or host when I try to access that variable from the other machine I get an NPC.

So when i player spawns an unit it passes the player object to the unit. So the unit knows exactly which player built it. But it only does it on the player who built it. Later when the host tries and spawns a projectile from that unit and it needs to reference the "player" (who built the unit) its null since another player built it.


I think if there is a way to let players spawn there own units and be synced with all the other players both problems will resolve.

Answers

  • WARdd
    WARdd ✭✭
    Options

    Using RPCs to command units to launch projectiles is completely the wrong approach for Fusion, you should generally avoid RPCs for anything except chat messages and special cases like ending a match or syncing player info.

    For spawning projectiles you can take a look at the tanknarok example, the code may look a bit like this:

    var key = new NetworkObjectPredictionKey { Byte0 = (byte)owner.RawEncoded, Byte1 = (byte)Runner.Simulation.Tick };

    Runner.Spawn(projectilePrefab, exitPos, rot, owner, (r, obj) => {

    obj.GetComponent<NetworkProjectile>().InitNetworkState(weapon);

    }, key);

    Which would crucially run somewhere in a FixedUpdateNetwork.

    This allows all simulations to spawn a predicted projectile at the same time and then later compare/correct with each-other.

    The decision whether to fire or not is of course part of your unit AI and should also run in FixedUpdateNetwork. Crucially, almost all the variables you work with in that logic should be marked as [Networked] so they can be corrected over time as Network predictions diverge from each-other.

    To sync info between a spawner and other clients what you need to do is use Runner.Spawn(...OnBeforeSpawned={...});

    The OnBeforeSpawned function can be used to pass info into variables that are marked as [Networked] which are then synced among all players. If you need to do anything with that info when that thing is spawned use public override Spawned() to achieve it, since OnBeforeSpawned only runs for the spawner player (usually the host).

    For the case of a player reference you don't even need this approach, since you can just use InputAuthority. The Runner.Spawn method asks for an owner reference, which will be passed to the spawned object as the InputAuthority of that object. That means you have a PlayerRef, which you can use to find your own custom Player Script with the right coding, again there are good examples of this in the Fusion sample projects.

    Overall it sounds like you're figuring out the basics, so I recommend you take some time to just familiarize yourself with Fusion, looking at tutorials and sample projects.

    Shared mode I think is only useful for small demos and casual games, I would recommend you use host/client for RTS.