Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Question Agent destination

Discussion in 'Navigation' started by Immitated, Jan 21, 2024.

  1. Immitated

    Immitated

    Joined:
    Oct 31, 2023
    Posts:
    11
    Hi all, I need to set my AI nav mesh agent to target specific gameObject in multiplayer. So far in the setup I had used
    agent.destination = Player.LocalInstance.GetPosition();
    or
    agent.destination = Player.LocalInstance.transform.position;

    but since I am new to it all even I knew that will not work and that the problem will occure because I am basically referencing Player class and not specific GameTransform/Object.... so I know I need to do a setup where I identify players with something like an event _ OnPlayerSpawned.... and than listen that on other script and set there some sort of int or list for the spawned players that I can than use later in my code.

    I have tried all I know so far, but I am not good at using tools at my disposal yet. I have tried setting up ClientRpc with ulong targetClientId parameter... but I don't think I use that correctly.

    Anyway, I got to the point where I trigger the event but agent chases transform.position of game object from each client to his own.
    Is there a "simple" way to refer to specific game object (Player) rather than the class itself or LocalInstance? Or (and I guess not) if not. what would be a correct way? Make array? List? callback for int/id? and how would I go about it?

    Thanks in advance.
    P.S.
    I do hope I posted this question on the right subforum
     
  2. streetboys885

    streetboys885

    Joined:
    Jan 23, 2024
    Posts:
    1
    In your AI script, you can then access the synchronized position. You can try this code
    poly track

    void Update()
    {
    agent.destination = syncedPlayerTransform.position;
    }
     
  3. Immitated

    Immitated

    Joined:
    Oct 31, 2023
    Posts:
    11
    Hello. I have tried your suggestion and did not work. I have created new PlayerManager class and made a List of players and return an int for the players. Seems it will work as long as I refactor all my code to work with playerwithint. thanks anyway man.
     
  4. Gabo_campitelli

    Gabo_campitelli

    Joined:
    Oct 17, 2012
    Posts:
    426
    I don't know what networking are you using or what structure implementation. however, 99% of the times you have to set the AI navigation on the server only and then just replicate the position of the AI. Setting a destinaton in each client is bad practice. unless you don't care for syncronization. in wich case.. why?
     
  5. Immitated

    Immitated

    Joined:
    Oct 31, 2023
    Posts:
    11
    Ok I am new to game dev, so I am even now not shure what are you talking about but I am positive that I've gave way 2 few info for people to be able to help even if they wanted. So let me rectify that.

    It is 3d top down game. I got 2-3 classes that I am currently trying to properly connect for multiplayer. It is fairly basic setup of Players - Police - Npc. (Police also being non player char.). I first made core mechanics for single player and had a setup where Police and Npc are nav mesh agents. Police is doing its couroutine walking around points on nav mesh and Npc is on random movement. Player.cs is not nav mesh agent (still not shure if that is a good thing now). The police is suppose to change states when 2 conditions are met. If player is within range and has a weapon drawn, so in that case the destination of Police(non player char) was previously just agent.destination = Player.LocalInstance.GetPosition(); (Get position nothing more than a function in player.cs. that checks now if it isOwner and returns its transform.position). Players are their own thing. Each player controls one gameObject (network prefab) but now when trying to refactor for Unity.netcode. i ofc. return transform.positions of everyone if 1 person meets conditions.
    I have tryied now to create PlayerManager class to get some sort of int because I still dont know how to properly use Network(whatevers) that I have in options. I have tryied and failed. And I managed to create int and assign it to a player GameObject and it sort of worked a little but not quite. I know I should prob learn more before attempting MP but I hoped this issue would be easier to solve cos I feel like rest I can tackle (did somehow with RPC and variables and server/host/client relationships.) but I can't and I kind of don't want to do a whole new tutorial to maybe find how to tackle this specific issue. So i am hoping some1 like you can help.

    My guess now is to create a whole new class, try to assign it to player GameObject dynamically during OnPlayerSpawned and return some sort of ID and transform.position throught there, than refactor my non player classes to target that class and not Player.cs who is now a singleton basically. Public static Player LocalInstance. (that might be part of the issue).

    There is a chance I still did not understand you. So can you help? Can you at least (if you got what I need) push me in the right direction? How would you tacke this? I will learn just say what! :D Make a List<Player> and retrieve that? make new script for PlayerID? Is there a way to use NetworkBehaviourIDorWhatever from there and how? I did not want to do a new PlayerManager before cos I was hoping this was a common thing and they got it covered in Netcode with a simple 1 code line.

    Thanks in advance.
     
  6. Gabo_campitelli

    Gabo_campitelli

    Joined:
    Oct 17, 2012
    Posts:
    426
    unfortunately i'm not familiar with Netcode but i assume that it's pretty much a newer version of Mirror (uNet). In any case all multiplayer is coded pretty much in the same way at this level.

    So first of all you have to make sure that only SERVER runs the police and npc logic. Note that if the host is also a server then local player and server are both true. you need to check if the instance of the police/npc is the one on the server then do the stuff.
    After doing your stuff, send the results (positions) to all clients. If you already have a script for position just ignore.
    Finally make sure that the police/npc instance on the clients are not doing any logic at all. that the transform can move freely so it gets moved only by network updates.
    Same goes for animations and other events that might be involved. Do logic in server, send results apply results on remote.
    Then for each player control you can ask if it's the local instance and only active player there.
    Don't need to change the network manager.
    just check you only run logic in server and only propagate positions from server to clients.

    here is the Netcode logic for asking if it's the server

    if (NetworkManager.Singleton.IsServer)

    It looks a bit more complex than Mirror. i'm afraid i wount be able to pinpoint you in the codeing itself. but the logic remains the same
     
    Last edited: Jan 25, 2024
  7. Immitated

    Immitated

    Joined:
    Oct 31, 2023
    Posts:
    11
    Thank you very much. Thats all I need, a direction to look at. I will figure out the rest hopefully :)
     
    Gabo_campitelli likes this.