playMaker

Author Topic: Help with triggers / cheaper methods  (Read 3680 times)

jess84

  • Hero Member
  • *****
  • Posts: 515
Help with triggers / cheaper methods
« on: January 08, 2014, 08:47:24 AM »
Hi,

OK, so my level has 16 cubes on a grid. If you touch one cube, I detect all bordering cubes and send an even to them to play an animation.

At the moment, I'm doing this via;

A cube has a child object that just contains a trigger zone collider.
I have 15 FSMs on this trigger zone object, one for each other cube on the map
These start with a global event (not a start event), e.g. "Cube 1 Clicked", and then use Trigger Event "On Trigger Stay", if it matches another cubes tag, then it progresses to another state where it then sends an event to that corresponding cube.

This works fine, it detects the right cubes and the timings are perfect.

However, I noticed when duplicating these FSMs to test out a secondary design idea, that performane was severely hit. I guess 15x16 FSMs is the problem, coupled with the fact that when Cube1 is clicked, it activates 15 FSMs and the ones that aren't matched just sit on the "On Trigger Stay" event waiting for a match.  This is probably quite inefficent?

So what are my options?

Should I add a small wait step so that if another cube doesn't match, then it goes back to the nothing Start state (and isn't therefore on an "On Trigger Stay" event)?

Or should I look at raycasting from my clicked cube in 4 directions (at a specific length) to find bordering cubes?

I couldn't see an easy way of detecting what 4 cubes (in particular states) were nearby and bordering my original cube.

This might explain the performance problems I encountered on Android, which didn't get resolved even after changing shaders and vfx to cheaper elements.

Thanks in advance.

Andy22

  • Junior Playmaker
  • **
  • Posts: 99
Re: Help with triggers / cheaper methods
« Reply #1 on: January 09, 2014, 03:53:48 AM »
I guess 15x16 FSMs is the problem, coupled with the fact that when Cube1 is clicked, it activates 15 FSMs and the ones that aren't matched just sit on the "On Trigger Stay" event waiting for a match.  This is probably quite inefficent?

U need to fire up the profiler and see what really is the performance problem, i don't see any reason why u cant have several 100 of those FSM. Did u test in release mode outside of the editor? Often many performance problems are caused by editor or debug code that exists only inside unity/editor, so package a release version.

The other tip i can give is that: event logic/fsm's are rarely the direct cause for performance problems, since usually u don't fire several 100 events per frame. U could also try disabling certain FSM actions (per frame actions) u suspect and see what happens, if u can't find the cause via profiling.

bye Andy

jess84

  • Hero Member
  • *****
  • Posts: 515
Re: Help with triggers / cheaper methods
« Reply #2 on: January 09, 2014, 11:46:02 AM »
Thanks for the advice. I'll definitely look at the profiling stuff tonight.

I actually went through all of those FSMs and added a global events that linked back to an empty state, and when running the checks (fired from a cube), I added another event to return all of those events to the empty state. It actually made quite a difference. I guess that was to be expected if the On Trigger event was sat there waiting for a match on over 200 FSMs, presumably every frame.

It was quite tedious to do, but worth it in the end.

I actually do most of my testing on the actual build outside of Unity. I can't get a proper respresentation of the aspect ratio with all GUI elements in the right place inside Unity, so I only really test within Unity when I need to track down a bug or test something new.

I think I have to hold off on testing properly on Android until there's LeanTween support. I don't use iTween very much, but there's clearly a big difference in performance when I disable it.

I guess going back to my original question;

When a cube is clicked, I need to find which other cubes (gameobject variables) are within the cube's trigger zone AND sent events to those specific other cubes.
As I'm quite a noob, there's probably a much simpler way, but I have no idea.

Is there a more efficient way than what I've used? (the multiple FSMs checking each other cube on the map individually)

Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2511
  • Mender of the past
    • Cleverous
Re: Help with triggers / cheaper methods
« Reply #3 on: January 09, 2014, 11:52:24 AM »
Have you tried doing this with ArrayMaker?
Products by Cleverous
|| Vault Core : Database
|| Vault Inventory : Multiplayer Inventory
|| Vault Attributes : Character Stats
|| That Hurt! : Dmg Floaties
|| Quinn : 3D

jess84

  • Hero Member
  • *****
  • Posts: 515
Re: Help with triggers / cheaper methods
« Reply #4 on: January 09, 2014, 12:12:14 PM »
Ah, profiler is Pro only  :'(

@Lane - Nope, as I noob, I don't quite get the concept of ArrayMaker and how I can use it for my needs.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Help with triggers / cheaper methods
« Reply #5 on: January 10, 2014, 08:25:40 AM »
Hi,

 you can use a very simple technic to do all this efficiently.

 Name all your cubes using the following pattern:

 x-y

x being the column index and y the row index.

 so if you have 16 cubes arrange on a 4*4 grid. The top left cube is 1-1, the bottom right cube is 4-4

on top of that you will have an Fsm on each cube named "Interface" and it will have two int variables, x and y. For each cube you will properly set them to reflect this position so cube "2-4" must have its fsm "interface" x variable set to 2 and y variable set to 4

 now, if you click on cube 3-3 you simply query that "interface" fsm for the x and y values, work out all the references for the sides cube ( 2-3, 4-3,3-2,4-2), find and call each of these cubes with a specific event.

 NOW, finding objects is very expensive and should not be used too much, that's where ArrayMaker becomes handy. All of the above works without ArrayMaker, but playmaker can help you organize and refer to GameObject without having to "find" them, they would be referenced in a hashtable with key being "x-y" and with their values being the gameobject representing that grid slot. then you can use ArrayMaker custom actions to get to the gameobject on a specific slot which will be a lot more efficient then use "find".

Bye,

 Jean