Eenheid3D. Proberen opdracht voor object te verzenden zonder toestemming

Ik heb een turn-based strategiespel voor meerdere spelers waarvoor een spelmanager nodig is, die de huidige spelstatus regelt (wie is er aan de beurt enz.). Deze manager zou gemeenschappelijk moeten zijn voor elke client, zijn status moet worden gesynchroniseerd op de server.

Hier is hoe ik dit doe:
Het gamemanager-object is NetworkBehaviour en het heeft NetworkIdentity, wat geen lokale spelerautoriteit of serverautoriteit is. Ik heb een aangepaste NetworkManager gemaakt en deze activeert de Game Manager bij verbinding met de client, waarbij ook wordt getest of het een server is. Hier is een code:

public override void OnClientConnect(NetworkConnection conn)
    {
        ClientScene.Ready(conn);
        if (NetworkServer.active)
        {
            var manager = Instantiate(MultiplayerManagerPrefab, Vector3.zero, Quaternion.identity) as GameObject;
            var tacticsManager = manager.GetComponent<MultiplayerManagerModel>();
            NetworkServer.RegisterHandler(MsgType.AddPlayer, tacticsManager.CreatePlayerOnServer);
            NetworkServer.Spawn(manager);
        }
        ClientScene.AddPlayer(0);
    }

Als ik het op een server uitvoer, werkt het prima, het maakt een instantie op een client en synchroniseert variabelen van server naar client. Maar wanneer ik commando’s van de client probeer uit te voeren, negeert het ze en geeft het deze waarschuwing:

Probeer opdracht voor object te verzenden zonder toestemming.
UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter,
Int32, String)

Merk op dat deze Game Manager eerder wordt uitgezet dan een speler, omdat hij verantwoordelijk moet zijn voor het spawnen van spelers. Wat doe ik verkeerd?


Antwoord 1, autoriteit 100%

Naast uw codefragment, de waarschuwing

Probeer -opdracht voor object zonder autoriteit toe te sturen.

betekent dat: u -opdracht verzenden vanuit een object waarvan autoriteit , uw (speler) niet heeft.

Welke eenheid DOCLS Staat:
-opdrachten worden verzonden van spelersobjecten op de client naar spelersobjecten op de server. Voor beveiliging kunnen -opdrachten alleen worden verzonden vanaf uw spelerobject , zodat u de objecten van andere spelers niet kunt beheersen.

maar

Beginnen met eenheidsversie 5.2 Het is mogelijk om opdrachten van te verzenden
Niet-spelerobjecten
die klantautoriteit hebben. Deze objecten moeten hebben
zijn voortgebracht met NetworkServer.SpawnWithClientAuthoorn of hebben
Autoriteit ingesteld met NetworkIdentity.Assignclientauthioriteit. Opdrachten
verzonden vanuit dit object worden uitgevoerd op de serverinstantie van het object,
Niet op het bijbehorende spelerobject voor de klant (meer ).

Dus wat is de oplossing:
Voordat u de opdracht verzenden (of -opdracht -functie uitvoeren), wijst Autoriteit van dat object toe aan uw speler . Zoiets als deze

assignAuthorityObj.GetComponent<NetworkIdentity>().AssignClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

Dit ” is vertegenwoordig op uw spelerobject. Na het maken van -opdracht Oproep kunt u autoriteit verwijderen met behulp van dit codefragment.

assignAuthorityObj.GetComponent<NetworkIdentity>().RemoveClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

Nogmaals, “dit” wordt weergegeven voor uw Player-object.

Belangrijke opmerking: ik wijs meestal autoriteit van een object toe (als ik dat wil gebruiken) met behulp van OnTriggerEnteren verwijder autoriteit op OnTriggerExit. Het hangt af van een specifiek scenario dat u bij welke gebeurtenis een objectmachtiging wilt verkrijgen of verwijderen.


Antwoord 2, autoriteit 29%

Je kunt geen commando verzenden zonder lokale autoriteit.

if (!isLocalPlayer) return;

Maar wat voor soort gegevens verstuur je met deze opdracht?
In het algemeen, en zoals je zei:

“de status moet worden gesynchroniseerd op de server”

Dus, IMHO, je hebt geen reden om een Commandvan je speler te sturen.
Commando’s moeten voor spelerinvoer zijn.
Deze ingangen zullen acties in je spel activeren.
Uw manager krijgt informatie van deze acties (score-update, einde van het spel…) en verzendt gegevens en/of activeert acties op klanten, met behulp van ClientRpc

Dit is het serverautoriteitsmodel. Als u een lokaal object opdrachten laat verzenden, kan een hacker gemakkelijk binnenkomen en tegen uw manager zeggen

“Hé, ik ben aan de beurt. Hé, ik ben weer aan de beurt. Hé, mijn score is 9999999 en ik heb het spel in 1 seconde gewonnen.”.

Other episodes