playMaker

Author Topic: static batching  (Read 5755 times)

Sjones

  • Full Member
  • ***
  • Posts: 203
static batching
« on: September 10, 2012, 10:32:33 PM »
this is an odd one and not sure if the engine itself is capable of this, if it can though, could there be a PM action to add its functionality.

so I have been reading up on how unity handles batching, if you have the static check box ticked at the top it adds this to the static batching, this is great until you want to create objects on the fly.

I understand that static batching only works on stationary targets, however there is some script to handle this too http://docs.unity3d.com/Documentation/ScriptReference/StaticBatchingUtility.html

I am wondering if there could be an action to combine the mesh in real time in an fsm, once the object is placed it fulfils all the requirements of being able to be statically batched and thus if combined then to be able to cut down the draw call as long as there was already one of that object in the scene.

this will help a hell of a lot in performance if you wanted to place 100 of the same objects (ok big number but the point is there)

my idea for the fsm is to place object, then pass over to combine function to add it to the static batcher handler, that is if I understand how the feature would work

Sjones

  • Full Member
  • ***
  • Posts: 203
Re: static batching
« Reply #1 on: September 11, 2012, 12:42:57 AM »
well I have done more research on the matter and attempted to get an action set up for it.

so after looking at other actions and taking a base from them, along with this thread I found http://answers.unity3d.com/questions/65030/static-batching-on-dynamically-instantiated-conten.html I think that I am almost there, my problem following that script example is that I dont know/cant find the default staticbatchroot that unity creates at build time.

for now I tried to assign a gameobject as the root (for my purposes, as there are no batched items at the begining of the game the default is not an issue)

so I tried this

Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.UnityObject)]
[Tooltip("Removes all keys and values from the preferences. Use with caution.")]
public class staticCombine : FsmStateAction
{
[RequiredField]
[Tooltip("RootGameObject")]
public FsmGameObject gameObject;

public override void Reset()
{
gameObject = null;
}

public override void OnEnter()
{
GameObject go = gameObject.Value;

StaticBatchingUtility.Combine(go);
}
}
}

this built ok with no errors however when trying it in the preview window it did not batch, so instead I tried implementing more of the suggested code from sample above to

Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.UnityObject)]
[Tooltip("Removes all keys and values from the preferences. Use with caution.")]
public class staticCombine : FsmStateAction
{
[RequiredField]
[Tooltip("object to add to static batch")]
public FsmGameObject gameObject;
[RequiredField]
[Tooltip("RootGameObject")]
public FsmGameObject gameObject1;

public override void Reset()
{
gameObject = null;
gameObject1 = null;
}

public override void OnEnter()
{
GameObject[] go = gameObject.Value;
GameObject root = gameObject1.Value;

StaticBatchingUtility.Combine(go, root);
}
}
}

this gave me an error saying it can not convert from type gameobject to gameobject[] so this has came to the end of my knowledge currently, from searches this is because the [] is an array? would make sense that the [] would hold the list of other game objects within it?

so now I am lost, I find this fun and interesting but I think I have reached my current skill level.

Edit*
I just tried making an array with the code provided, built correctly but didnt work

Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.UnityObject)]
[Tooltip("Removes all keys and values from the preferences. Use with caution.")]
public class staticCombine : FsmStateAction
{
[RequiredField]
[Tooltip("static batch root")]
public FsmGameObject gameObject;
[RequiredField]
[UIHint(UIHint.Variable)]
[Tooltip("object to add to static batch")]
public FsmGameObject gameObject1;

public override void Reset()
{
gameObject = null;
gameObject1 = null;
}

public override void OnEnter()
{
GameObject go = gameObject.Value;
GameObject[] gos = new GameObject[10];
for (int i = 0; i < 10; i++) gos[i] = gameObject1.Value;


StaticBatchingUtility.Combine(gos,go);
}
}
}
« Last Edit: September 11, 2012, 01:48:19 AM by Sjones »

Sjones

  • Full Member
  • ***
  • Posts: 203
Re: static batching
« Reply #2 on: September 15, 2012, 05:27:03 AM »
so I re-visited this issue, this time I tried (at least I think it should be how it is) to create an array of game objects by searching for all that have a certain tag.

it builds the script with no errors but when testing it the fsm stops at that state and doesnt continue, in editor or published.

Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.UnityObject)]
[Tooltip("Removes all keys and values from the preferences. Use with caution.")]
public class staticCombine : FsmStateAction
{
[RequiredField]
[Tooltip("static batch root")]
public FsmGameObject gameObject;

public override void Reset()
{
gameObject = null;
}

public override void OnEnter()
{
GameObject go = gameObject.Value;
GameObject[] gos = GameObject.FindGameObjectsWithTag("buildings");


StaticBatchingUtility.Combine(gos,go);
return;
}
}
}

I really would like this feature as it could up performance a lot on mobile devices, as draw calls are the primary problem from what I have read, this reduces all of the same instanced objects into 1 draw call, performance would then rely upon poly counts, at that point I can reduce them in the model if need be.

I am testing my project as I go and I have had no issue my self, I have 110 draw calls before I start getting any performance issues (not sure if thats poly limit or draw calls yet)  but my device is one of the latest out there, I have read that the ipad struggles to handle 25, so the lower I can get this the more of a target audience I can aim for.

as such all I am trying to do is add a specified object to the static batching process at a given point in an fsm.

Sjones

  • Full Member
  • ***
  • Posts: 203
Re: static batching
« Reply #3 on: September 15, 2012, 05:38:26 AM »
OK scratch that!

IT WORKS!

my problem was I did not have anything tagged as buildings XP!

anyway, gona modify it to try and get it to use a custom string for your tag (unless you can get a list of tags?)

also I dont know how cost effective finding objects with a tag is, if theres a way that anyone can see to improve performance, maybe to use arraymaker? I can see if I can amend the above script.
« Last Edit: September 15, 2012, 05:40:26 AM by Sjones »

Sjones

  • Full Member
  • ***
  • Posts: 203
Re: static batching
« Reply #4 on: September 15, 2012, 06:18:10 AM »
k, so it actualy sort of works, it seems to batch things in pairs, batches the first 2 then seems to batch the next 2 after so this has halfed the draw calls instead of merged them into 1, its a good start but not working as intended :(

I remember seeing a post on the unity forums a few days ago about a similar issue, I cant find it atm but I know it was this problem with either static or dynamic batching.

Sjones

  • Full Member
  • ***
  • Posts: 203
Re: static batching
« Reply #5 on: September 15, 2012, 08:41:27 AM »
testing and problem solving...

so I done some more testing, it gets a little confusing because I am doing android and controls arnt native to pc but from what I have found out, if the script is run on a one off after a lot of object placement all of those are then added and work as 1 draw call.

if more objects are placed, all of the new objects that have not been combined combine together, so the idea is working and it looks like it is breaking down at the array of objects.

I went back over the example code I found.
Code: [Select]
GameObject[] objCreated = new GameObject[10] for (int i = 0; i < 10; i++) objCreated[i] = Object.Instantiate(blah);

StaticBatchingUtility.Combine(objCreated, someOtherObjectForTheRoot);
the part that I am finding hard is the array part, it looks like he is creating a game object array with 10 object spaces? and then creates 10 objects, this was posted as a reply with someone having over 5000 draw calls, so I am not sure if I am correct.

if this is the case I need to have it different and use the same array but add to it.

I have tried looking into linking arraymaker array for use as the array gameobject but I cant seem to find the actions for arraymaker to look into to try and work out how to access that array (within playmaker or just straight into the script)

now once that is fixed my issue will be deleting the object and its reference in the array list.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: static batching
« Reply #6 on: September 15, 2012, 09:11:52 AM »
Hi,

 can you clarify what you are willing to achieve with ArrayMaker? I am sure we'll find something,

bye,

Jean