- Home /
Need help with my view distance script, and if i can either A. optimize it or B. split a table into multiple pieces.
So, what im trying to accomplish here is to make a view distance script for the camera, and im trying to optimize it, as i have about 175k objects in the scene(an open-world game), and its laggy each frame it detects the view distance and i want to fix it somehow. Please help!
here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ViewDistance : MonoBehaviour
{
// Start is called before the first frame update
public GameObject Parent = null;
public WorldValues values;
GameObject RootPart = null;
Vector3 OldPlayerPos;
public float MaxDistance;
public float MaxItems;
public float TickSpeed = 1;
bool cantickagain = true;
public bool cam;
void Start()
{
RootPart = values.RootPart;
}
// Update is called once per frame
void Update()
{
if (OldPlayerPos != values.MainCamera.transform.position)
{
if (cantickagain)
{
foreach (Transform object1 in Parent.transform)
{
Vector2 camdis = new Vector2(values.MainCamera.transform.position.x, values.MainCamera.transform.position.z);
Vector2 objdis = new Vector2(object1.transform.position.x, object1.transform.position.z);
if (Vector2.Distance(camdis, objdis) > MaxDistance)
{
object1.gameObject.SetActive(false);
}
else
{
object1.gameObject.SetActive(true);
}
}
OldPlayerPos = values.MainCamera.transform.position;
}
}
if (cantickagain)
{
IEnumerator tick()
{
cantickagain = false;
yield return new WaitForSeconds(TickSpeed);
cantickagain = true;
}
StartCoroutine(tick());
}
}
}
Answer by Captain_Pineapple · Feb 15 at 09:31 PM
There are multiple things you can do.
Though the best you can do to begin with is to actually check the profiler what actually takes up all the performance. You should never optimize blindly.
Howevery an easy improvement would be to not get the Distance but the squared distance instead.
if (camdis - objdis).sqrMagnitude > MaxDistance
where in your start function you add the line:
MaxDistance *= MaxDistance
This will greatly improve performance but you might have to turn MaxDistance into a long
Why is this faster you ask? -> Because distance is the squareroot of the squares of the vector elements. Calculating the squareroot is really really slow.
Apart from this you should consider to group your objects on a grid. Then you only have to check your players position if it moves into a new grid element. So for example your grid has a size of 50x50 units. You have a 2D list of all grid elements which in turn each contain a reference to all objects which are positioned within. (This can already be setup in your scene so takes up no performance at runtime)
Assuming your player starts at grid (0,0). At startup you can disable all objects in grid elements which are lets say between -4 and 4 in x and y direction.
Then when your player for example leaves grid element (0,0) for grid element (0,1) you disable all objects in grid elements (-4 to 4, -4) and enable all objects in grid elements (-4 to 4, 5).
This can then be further optimized by creating a routine which only enables and disables like 5 objects per frame so that your game is not overloaded on the instance you move from one grid to another.
Games like minecraft for example use similar system. There the grid elements are called "chunks".
Hope this helps, let me know if something was unclear.
Thanks for the help, i think i will use the grid system you mentioned, as i like to use things i understand so i can change them later on if needed, and im basically a newborn at coding and dont get what really happens to make the performance easier in the first solution, but i think the grid will help a lot with performance, as instead of calculating say, 200k objects i'd calculate 10k or something, thanks for the help! This is like, my first real question on the site.
cool, good luck then :)
Just to clarify what the first part is about:
x^2 is cheap to calculate. This is just y = x*x right?
But the inverse of this is really difficult on a computer. so to get x from y you need x = sqrt(y)
Now if you calculate the length of a vector, which in your case is your distance value then unity calculates this below the hood:
d = sqrt(x*x + y*y + z*z)
And then you compare d to some distance which is your threshold.
Now Unity offers the sqrMagnitude
which is (for some vector v) just
v.sqrMagnitude = v.x*v.x + v.y*v.y + v.z*v.z
You can see that unity does not calculate the squareroot here. So before you had the equation:
Maxdist > v.magnitude
But faster is to write:
Maxdist*Maxdist > v.sqrMagnitude
As the sqrt is not calculated here.
Your answer
![](https://koobas.hobune.stream/wayback/20220613053031im_/https://answers.unity.com/themes/thub/images/avi.jpg)