Forum rules - please read before posting.
Tech questions during the weekend? Drop in on the community Discord channel!

Performance Questions

I am now doing some optimization in my game to find out how much visual fidelity I can go with. I combined meshes and reduced drawcalls but already after a short time suddenly AC is the main culprit for performance.
  • There seem to be constant object activations and deactivations going on (expensive!)
  • There is constantly significant memory allocated, resulting in constant garbage collections (red line and huge CPU spikes)
Is there a way to get this CPU and memory activity down? I think an optimization pass on AC would really be benefitial to all users :-)
image
image

Comments

  • I think this is kind of research are very important. Hope Chris could give some love to the performance since is key to make AC more awesome and useful. Thanks for the report!
  • edited June 2015
    Open PlayerInput.cs, and find the InputGetButtonDown function on line 1236.

    AC implements a try/catch routine so that non-existing inputs don't throw an error.  I wonder if that causes a performance hit.  Try removing the try {}, catch {} lines inside it - does that improve things?
  • It's a bit tricky. Removing try catch will show tons of errors on the console messing up the profiler. I put a return true at the beginning of the method and it already used 4kb less memory per frame. So making sure only valid axis are called seems like a very good idea to get rid of constant error handling.
  • Sure - but the problem is that there are so many inputs available that most users won't define.  I'm assuming that the errors popping up were due to missing inputs.  You'd probably be best off removing the try/catch, then defining the missing inputs - even if you don't necessarily need them.  You can see a list of available inputs in the Settings Manager.
  • Would it be an option to query the inputs in a "start" method and create the list of available inputs from these? Then no errors would be thrown anymore and users don't have to define a gazillion dummy inputs. Is there a case that inputs are modified at runtime? AFAIK Unity does not support that, does it?
  • edited July 2015
    Unsure.  There's food for thought there, at least.
  • edited May 2016
    I had the same issue, removing the try catch and defining the missing inputs in the inputmanager was a great solution. A significant speed up of around 10 FPS!...

    I also noticed that StateHandler.Update() is quite demanding (12.4% of total) anyone know any obvious optimisations for this ? Looks like it does lots of raycasts, but Im assuming they're needed perhaps for seeing if hotspots should show or for setting the proximity: hotspot.SetProximity (true);. I wonder if not using "mouse over" would speed anything up ? Im tired now just thought id see if there was any ways I oculd speed things up a bit, going to get into LODing tomorrow :)
  • Since my last post, there is an option in the Settings Manager labelled Assume inputs are defined? that bypasses the try/catch.

    The StateHandler's Update function is pretty much the only Update function in AC - all other script updates get called from this, so it's doing the bulk of the work.  The SetProximity function is only called if you have Highlight Hotspots based on cursor proximity? checked.
  • By the way, is there a way to use the Assume inputs are defined? option when using Rewired? Even if it needs some coding? As I've never used it before, I'm not quiet sure what It means, but I'm assuming that it's about having all inputs properly setup in the unity inputs...

    Isn't there a way to explicitly communicate the actions created in Rewired directly in AC? Or is it possible to use it if I've made sure to define all of the actions/inputs? (cause I have...)

  • When unchecked, AC wraps each input check around a try/catch statement, so that the game still runs even if not all available inputs are defined.  When checked, the try/catch is bypassed.

    To integrate Rewired into AC, you would override the input checks completely, so the option wouldn't actually have an effect.  Tony, the creator of Dialogue System, wrote a code snippet here.
  • edited May 2016
    Ah, so by using the delegates you are already bypassing the try catch? or is it just not useful then? 
    And actually I have a more complete version of the script, which I made from that very example  :)>-, maybe someone will find it useful, it seems to work perfectly.


    -------------------------------------------------------
    using UnityEngine;

    public class ACInputRewired : MonoBehaviour
    {

    public int playerId = 0;
    private Rewired.Player player;

    void Start()
    {
    AC.KickStarter.playerInput.InputGetButtonDownDelegate = CustomGetButtonDown;
    AC.KickStarter.playerInput.InputGetButtonUpDelegate = CustomGetButtonUp;
    AC.KickStarter.playerInput.InputGetButtonDelegate = CustomGetButton;
    AC.KickStarter.playerInput.InputGetAxisDelegate = CustomGetAxis;
    player = Rewired.ReInput.players.GetPlayer(playerId);
    }


    private bool CustomGetButtonDown(string buttonName)
    {
    return player.GetButtonDown(buttonName);
    }

    private float CustomGetAxis(string AxisName)
    {
    return player.GetAxis(AxisName);
    }

    private bool CustomGetButton(string buttonName)
    {
    return player.GetButton(buttonName);
    }

    private bool CustomGetButtonUp(string buttonName)
    {
    return player.GetButtonUp(buttonName);
    }

    }
    -------------------------------------------------------------------
  • I'm sure that would go down well in the Extending the Editor forum, @Alverik!
  • Sorry to resurrect this old thread but I'm having some performance issues with my current AC game and I came by it while searching the forum for a solution.

    Has any thought been given to 10FingerArmy's suggestion to query the inputs in a Start method and create the list of available inputs from these? I'm asking because I tried checking the "Assume inputs are defined?" setting to increase performance but then realized I now have to define each and every input manually which is quite a pain. More so, even if I was inclined to define them, I cannot define the Horizontal and Vertical inputs because I don't want AC to handle the first person movement at all and renaming these inputs was the only way I could find to bypass AC's first person movement (the reason is not really related to the current topic but in short, I found that the current first person movement is too jerky for a VR game when repeatedly colliding with a collider).

    Bottom line, could it be possible to bypass the try/catch without the need to define unneeded inputs?
  • Not that I'm aware of - hence the introduction of the checkbox.  I appreciate that it can be a pain to have to define the inputs, but it does at least prevent the possible introduction of further issues - and only needs doing the once.

    The Horizontal and Vertical can still be added - you can use the Player: Constrain Action to disable player-driven movement.
  • edited January 2018
    Hey sorry to dig up this old thread but I've found it while searching around the forum for StateHandler.cs taking up a lot of CPU power in my project. So I found out here that there is a checkbox in AC settings called "Assume inputs are defined?", after clicking it in runtime I've notice a huge fps leap, from like 50 to 80, but those errors started poping up for input definitions. After I just randomly defined these 5 inputs that were giving me errors the StateHandler.cs was just back up causing the same amount of trouble with CPU power as it was before I ticked that checkbox. So I guess my question is did I do something wrong and made that checkbox useless when it's ticked? Do I need to define somehow differently these inputs?

    Here is a screenshot of how I defined all of them (InteractionA has the same settings as all of them):

    Inputs
  • The StateHandler having a larger CPU than others is to be expected, as it is used to call all of AC's Update etc calls manually, so as to do without the performance hit of each AC script having its own Update/LateUpdate etc.

    Have you expanded the Profiler to show more detail about specifically where in the StateHandler the expense is?  Keep in mind that the AdvGame.GetMainViewSize() method, which you may find inside its hierarchy, is a main contender of performance hits but only when running in the Editor.

    The "Performance and optimisation" chapter of the Manual covers more points on boosting performance.
  • It's StateHandler.Update()\FindObjectsOfType

    Didn't know about that chapter, will go through it, thanks.

    So it doesn't matter how I define those inputs as long as they are defined somehow?
  • edited January 2018
    Ummm... I think it would be better to have each AC class add itself to a public/static list or dictionary on the StateHandler, on Awake or OnEnable. Having the objects register/de-register themselves to/from a list would avoid having to use the really, really, slow Find methods, specially in loops (which should be avoided at all cost). That would also simplify or make the GatherObjects() method mostly obsolete. I know classic adventure games require little performance, but if you want to add extra stuff on top, specially in 3D, then performance is key (In my case I love AC's actionlist system, so I use it for everything, not just standard adventure games). Also It would probably be better to have each hierarchy folder use a tag script or have it register itself similarly on Awake or OnEnable. Or at least have some of those calls cached... I haven't seen the code in the newer versions of AC, but it was like this in the older version I'm using for VR:

    //when looking for the _Sound folder on scene start
    if (GameObject.Find ("_Sound") && GameObject.Find ("_Sound").transform.parent == null)
    {
    musicOb.transform.parent = GameObject.Find ("_Sound").transform;
    }

    Even if it's not in a loop, GameObject.Find is called 3 times... when it could have been cached on the first call, then checked for null... AC is superb and I love it, but it really needs a through performance pass. Some objects were even using FindObjectsOfType( ) in specific methods which are usually called on all of the objects of that class at the same time, so the more objects you have of that type the more of a performance hit you will get (since they're all calling for a FindObjectsOfType separately instead of using a unified cached list). In my opinion all Find method variances which are looking for AC made classes should be removed entirely from the runtime only code (specially the "plural" versions) and instead should use a static/public list or dictionary in the State Handler. That would save some cycles (and garbage), which could then be used elsewhere.
  • Point taken.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.