- Home /
Billboard system
I have create a billboard system, and I would like to get any improvements, because when I instantiate it it takes 5000-10000ms for the UpdateBillboard function, this script is attached to every gameobject, is there a way to do this in a shader instead, which should give better performance right? NOTE: You manually assign quad and tree through the inspector and the billboard is generated by another script at runtime (Once for each tree type, so only 1-10 times or so) Code:
public BillboardClass tree;
public float BillboardDistance = 250.0f;
private Renderer render;
private Renderer QuadRenderer;
private Collider col;
[Serializable]
public class BillboardClass
{
public GameObject tree;
public Texture2D billboard;
public GameObject Quad;
[HideInInspector]
public Mesh mesh;
[HideInInspector]
public Vector3 Scale;
public void UpdateSize()
{
mesh = new Mesh();
mesh = Quad.GetComponent<MeshFilter>().sharedMesh;
Bounds bb = tree.GetComponent<Renderer>().bounds;
Scale = new Vector3(bb.max.x - bb.min.x, bb.max.y - bb.min.y, 1);
}
}
void CreateQuad()
{
GameObject Quad = GameObject.Instantiate(tree.Quad); //Create quad (Used to display billboard)
Quad.GetComponent<MeshFilter>().mesh = tree.mesh; //Assign the custom sized mesh to it.
Quad.transform.parent = transform; //Make parent of the tree
Quad.transform.localPosition = Vector3.zero; //Reset position
Quad.transform.localScale = tree.Scale;
QuadRenderer = Quad.GetComponent<Renderer>(); //Cache the renderer for the update function
QuadRenderer.material.mainTexture = tree.billboard;
QuadRenderer.enabled = false;
}
void Start()
{
render = GetComponent<Renderer>();
col = GetComponent<Collider>();
CreateQuad();
InvokeRepeating("UpdateBillboard", UnityEngine.Random.Range(0.0f,1.0f), 1.0f);
}
Transform target;
bool ShowTree;
void UpdateBillboard()
{
if (target == null)
{
if (Camera.main != null)
{
target = Camera.main.transform;
}
return;
}
ShowTree = false;
if (Vector3.Distance(transform.position, target.position) < BillboardDistance)
{
ShowTree = true;
}
QuadRenderer.enabled = !ShowTree;
render.enabled = ShowTree;
col.enabled = ShowTree; //Should I disable the collider or not
}
Answer by _met44 · Mar 30, 2015 at 11:49 AM
Hi, you're instantiating a gameObject just to get its bounds, seems like an overkill to me.
Try to break down your code with Profiler.BeginSample()/Profiler.EndSample() to find what parts are costing you so much and figure a way to get rid of or go arround them !
Good luck :)
Here I changed the quad resize to be this:
public void UpdateSize()
{
Bounds bb = tree.GetComponent<Renderer>().bounds;
Quad.transform.localScale = new Vector3(bb.max.x - bb.$$anonymous$$.x, bb.max.y - bb.$$anonymous$$.y, 1);
}
The scale is shown correctly in the inspector, but the quad isn't affected at all
4/5 of the ms is from running the UpdateBillboard void itself.
If I'm right the Quad field of BillboardClass contains your prefab rather than the instantiated version no?
And you don't seem to keep a reference to the gameObject you instantiate at all. So unless the object handles is own lifetime and has a autonomous behavior it's going to stay there forever without ever being used !
@_met44 The the localScale is correct in the inspector but nothing is happening with the quad, even if I manually try to rescale it it doesn't change size Code:
private void CreateQuad()
{
GameObject Quad = GameObject.Instantiate(quad); //Create quad (Used to display billboard)
Quad.transform.parent = transform; //$$anonymous$$ake parent of the tree
Quad.transform.localPosition = Vector3.zero; //Reset position
Quad.transform.localScale = tree.Scale; //Set scale correctly
QuadRenderer = Quad.GetComponent<Renderer>();
QuadRenderer.material.mainTexture = tree.billboard;
QuadRenderer.enabled = false;
}