Search Unity

Huge FPS drop on Host when receiving a command

Discussion in 'Multiplayer' started by NeoHL, Sep 3, 2015.

  1. NeoHL

    NeoHL

    Joined:
    Aug 24, 2015
    Posts:
    9
    Hello, I'm making a 2D co-op game, with puzzles that involve moving physics objects.
    One of the weapons the player has is a weapon that imitates the behaviour of the Half-Life 2 Gravity Gun;
    1. You right click in a certain direction
    2. It makes a raycast in that direction, with a limit distance
    3. If it found a gameobject with a collider and a certain tag, it stores it as "grabbedObject"
    4. It sets the grabbedObject position making it float in front of the player
    5. You right click again and you drop it.

    That works fine on the Host, and as client you can see the box move.
    As a client, when you pick up a box, it sends the info to the host and this one gets a FPS drop (from 90 to 60 ~)

    Script 1 - In the player (SyncGrabbedObject.cs)
    Code (CSharp):
    1.     void FixedUpdate () {
    2.         if(grabbedObject != null){
    3.             if(isLocalPlayer && !isServer){
    4.                 timer++;
    5.                 if (timer>= 4) {
    6.                     Debug.Log("Hey, we're grabbing an object as a LocalPlayer");
    7.                     clientPos = grabbedObject.position; // Vector2 used for storing the data to send
    8.                     CmdUpdPos(grabbedObject.gameObject, clientPos, grabbedObject.GetComponent<GrabbedObject>().isBeingDragged);
    9.                     timer= 0;
    10.                 }
    11.             }
    12.         }
    13.     }
    14.     [Command] public void CmdUpdPos(GameObject grabbedObjectR, Vector2 clientPosR, bool isBDragged){
    15.         Debug.Log("Hey, we're being told that we should UpdPos");
    16.         grabbedObjectR.GetComponent<GrabbedObject>().isBeingDragged = isBDragged;
    17.         grabbedObjectR.GetComponent<GrabbedObject>().LerpPosition(clientPosR);
    18.     }
    19.  
    Script 2 - in the Box (GrabbedObject.cs)
    Code (CSharp):
    1.     public void LerpPosition(Vector2 clientPosR){
    2.         gameObject.GetComponent<Transform>().position = Vector2.Lerp(gameObject.GetComponent<Transform>().position, clientPosR, Time.deltaTime * lerpRate);
    3.         Debug.Log ("Hey, we're UpdPos!");
    4.     }
    Is there other better way to update the position?
     
  2. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    You shouldn't use GetComponent inside update loops. It will cause slowdown.

    Just get it working offline first before mixing in networking.
     
    Last edited: Sep 4, 2015
  3. James_BadAlchemy

    James_BadAlchemy

    Joined:
    Aug 18, 2015
    Posts:
    6
    How can he get the position of the object without using GetComponent? The script can't be ran from the box, it has to be ran as a local player on a player prefab because he's using a [Cmd]. What are his alternatives?

    Much Thanks
     
  4. l3fty

    l3fty

    Joined:
    Mar 23, 2013
    Posts:
    87
    Within the command itself they are using GetComponent twice to fetch the same script, that could be done once and held in a reference instead. On the grabbed object they are also using GetComponent to get the transform, which is unnecessary as you can access it simply with gameObject.transform (or just transform.position etc. if you want to change the transform of the object your script is on).

    Perhaps to save any GetComponent-ing you could just affect the target objects transform within the body of the command.
     
  5. chrismarch

    chrismarch

    Joined:
    Jul 24, 2013
    Posts:
    472
    how would it work when controlling from the host if your FixedUpdate has !isServer?
    Also, try commenting out your Debug.Logs after you cache your component references instead of using GetComponent every time (pass in references to the components you need to the methods that need them)
    if you have access to the profiler, try profiling a standalone host