Hey guys. I’m a bit curious if there is a way to avoid using the Input.GetKey outside the update function, like an Event, so it would only be in effect if a key is pressed. Is there a way?
Valda, what memory are you trying to save?
As for input events, there are non by default in Unity’s API, but if you could create an InputManager that has such events, that code would still use Input.GetKey inside an Update. I do know that low level input is still checked on the main loop of the app. So there should not be theoretically any performance or memory huge difference between the Update or an Event way of checking the input. Event based is more elegant and the performance and memory issues in Unity’s case can mainly be cause by the C# VM requirement’s and implementation on top of the low level C++ engine. The communication between C++ and C# has an extra cost, but it’s insignificant on today’s hardware (at least what most of us are targeting to use with Unity).
Something like this can give you input Events.
using UnityEngine;
using System;
using System.Collections;
public class InputManager : MonoBehaviour
{
public static InputManager Instance = null;
public delegate void KeyEvent(KeyCode key);
public static event KeyEvent KeyPressed;
public static event KeyEvent KeyReleased;
private KeyCode[] keycodes;
void Start()
{
if (InputManager.Instance != null && Instance != this)
Destroy(gameObject);
else
Instance = this;
keycodes = (KeyCode[])Enum.GetValues(typeof(KeyCode));
}
void Update()
{
for (int i = 0; i < keycodes.Length; ++i)
{
if (KeyPressed != null && Input.GetKeyDown(keycodes[i]))
{
KeyPressed(keycodes[i]);
}
if (KeyReleased != null && Input.GetKeyUp(keycodes[i]))
{
KeyReleased(keycodes[i]);
}
}
}
}
I thought I already replied to this topic but I don’t see my reply…
Anyway, what I wrote is that I appreciate the feedback and I’m now confident I can use it in the update function without feeling like I’m bogging down the system. Thank you
A bit of a thread necro, yes, but this was still near the top of the results when just searching this. I noticed recently in profiling something of potential interest.
I had an Update() in an object that was always running, i.e. not destroyed on scene change. Within it there were two Input.GetKeyDown(KeyCode) checks, as well as a call to another singleton class’s method, which was was merely a check for a third Input.GetKeyDown(KeyCode) check. E.g.
private void Update()
{
SomeManager.Instance.CheckInput();
if(Input.GetKeyDown(KeyCode.F2) { DoSomething(); }
if(Input.GetKeyDown(KeyCode.F3) { DoSomethingElse(); }
}
where SomeManager.CheckInput() looked like
public void CheckInput()
{
if (Input.GetKeyDown(KeyCode.Tab))
{
if (gameObject.activeSelf) { DoBlah(); }
else { DoOtherBlah(); }
}
}
In the profiler, if I just put the original Update checks for input wrapped in a if(Input.anyKeyDown) { }, a la
{
if(Input.anyKeyDown)
{
SomeManager.Instance.CheckInput();
if(Input.GetKeyDown(KeyCode.F2) { DoSomething(); }
else if(Input.GetKeyDown(KeyCode.F3) { DoSomethingElse(); }
}
}
I saw quite a CPU drop in the BehaviourUpdate calls. Not sure if it was a huge drop, in an absolute sense, but it certainly dropped down the usage relative to what it was at the time. And simple enough to add for cases that there are multiple KeyCode checks. Just my two cents, and could be completely just a profiler/editor thing, or some other mitigating circumstance, but I’ve since taken to using that. Is this a known workaround for others, I wonder?
Save the reference to SomeManager.Instance in your class, don’t retrieve it on every Update() call again