1
\$\begingroup\$

I am trying to improve the fps and in my scene there are 4322 scripts attached to 4322 objects. When I activate those objects the fps go down. Right now it's around 100fps when i active those objects it drops to 40fps. I found and identified these two scripts are dropping the fps signficantly. Around 20 FPS i can save by commenting the methods which i am running in lateUpdate event.

public class ZoomNamePlace : MonoBehaviour
{
    public CameraController camContrller;
    public float size;
    public float distance;
    void Reset()
    {
        camContrller = FindObjectOfType<CameraController>();
    }

    private void Start()
    {
        //GetComponent<TextMeshPro>().text = this.transform.parent.name.Split('_')[0] + "_" + GetComponent<TextMeshPro>().text;
    }

    void LateUpdate()
    {
       Zoom();
    }

    void Zoom()
    {
        // if(camContrller ==null)
        //  camContrller = FindObjectOfType<cc>();

        //size = (camContrller.currentActiveCam.transform.position - transform.position).magnitude;
        size = Vector3.Distance(camContrller.currentActiveCam.transform.position , transform.position);
        if (size >= 200) return;
        if ((size / 600) >= .8f)
        {
            transform.localScale = new Vector3(size / 600, size / 600, size / 600);
        }
        else
        {
            transform.localScale = new Vector3(.8f, .8f, .8f);
        }

        
    }
   

}

If I comment out zoom method then fps improve around 5-8.

The second script is:

public class lookAtIcon : MonoBehaviour
{
    
    public CameraController camContrller;

    void Reset()
    {
        camContrller = FindObjectOfType<cc>(); 
    }

    void LateUpdate()
    {
        transform.LookAt(transform.position + camContrller.currentActiveCam.transform.rotation * Vector3.forward *-1 ,
           camContrller.currentActiveCam.transform.rotation * Vector3.up);
    }

   
}

The above script LateUpdate() code taking around 10-15 fps.

If I comment out both script updates functionality then FPS is around 59-61. If I comment out lookAtIcon script Updates event then fps around 65-67 (5 FPS improvement). If I comment out LateUpdate script LateUpdates event then fps around 74-75 (10 FPS improvement).

So it's about 25 fps improvement if I disable both script Events.

Please help me how should I improve it? I am thinking to disable the event if the object is far from the camera. Is there anyway avaible to disable the event on some objects? or do you have any other suggestion to improve it?

\$\endgroup\$
6
  • \$\begingroup\$ Can you show us what kind of visual effect you're creating with these items? We might be able to recommend more efficient ways to achieve that effect. In particular, this looks like it might be a candidate for Unity's Data-Oriented Technology Stack, which is built for dealing with large volumes of simple entities. \$\endgroup\$
    – DMGregory
    Aug 18 '20 at 11:32
  • \$\begingroup\$ Thanks you are always hepful. But DOTS may not work on unity webgl. \$\endgroup\$ Aug 18 '20 at 14:58
  • \$\begingroup\$ If WebGL is a constraint for you, that should definitely be mentioned in your question. \$\endgroup\$
    – DMGregory
    Aug 18 '20 at 15:02
  • \$\begingroup\$ The objects are 3D icons and some text mesh pros. Showing location text and icons \$\endgroup\$ Aug 18 '20 at 15:02
  • \$\begingroup\$ That should also be shown in your question, not relegated to a comment. \$\endgroup\$
    – DMGregory
    Aug 18 '20 at 15:03
2
\$\begingroup\$

The best way to skip calling a MonoBehaviour message is to not declare it.

As long as your script has a method called LateUpdate and your script is enabled, the engine will spend some measurable time calling it.

So, we'll take the LateUpdate method off of our individual instances, and instead just task them with tracking a shortlist of the instances we care about updating, using the methods Philipp showed:

public class Billboard : MonoBehaviour {

    public static List<Transform> billboards = new List<Transform>();

    void OnBecameVisible() {
        billboards.Add(transform);
    }

    void OnBecameInvisible() {
        billboards.Remove(transform);
    }
}

Then a script on our camera can receive a single LateUpdate call, and update everything in the shortlist all at once, without the overhead of calling all 4000 individually:

public class BillboardDirector {

    void LateUpdate() {
        Quaternion rotation = transform.rotation;

        foreach(var billboard in Billboard.billboards)
            billboard.rotation = rotation;    
    }
}
\$\endgroup\$
0
\$\begingroup\$

When you want to run some code only for objects which are on screen, then the events OnBecameVisible and OnBecameInvisible can be useful to you.

private bool isVisible = false;

void OnBecameVisible() {
     isVisible = true;
}

void OnBecameInVisible() {
     isVisible = false;
}

void LateUpdate() {
    if (isVisible) {
        // do something completely cosmetic
    }
}

But keep in mind that the visibility calculation of Unity tends to err on the side of caution. When it isn't completely sure that an object is invisible, it will consider it visible. To get the number of definitely invisible objects as high as possible, make sure you enable occlusion culling.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .