- Home /
Custom On(method) Functions
I want to create action buttons for a character: and was wondering if there was a better way of doing it than putting it all in the update function.
essentially this is what I would like to accomplish:
change
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Respawn")) {
Respawn();
}
if (Input.GetButtonDown("Switch Character")) {
SwitchCharacter();
}
if (Input.GetButtonDown("Use Item")) {
UseItem();
}
}
to each have their own (overridable method? Is what it would be called?)
void OnRespawnButton() {
//do stuff
}
void OnSwitchCharButton() {
//do stuff
}
void UseItemButton() {
//do stuff
}
Where would I begin to set this up, and is it even possible? note that there is a OnMouseDown() function, I am trying to create a similar functionality for all my other actions. This way it is not being called on every Update, but only when it is triggered.
Answer by Bunny83 · Aug 31, 2011 at 12:41 PM
Unity doesn't provide an event callback for keyboard input. Like in most game engines the input have to be polled each frame. Checking for some KeyDown-events is nothing bad. You should use the KeyCode version of those functions if you worry about performance ;)
btw. OnMouseDown and OnMouseUp also does a implicit raycast every frame to check the object below the cursor. On mobile those events won't fire because due to performance they removed this automatic raycasting.
ps. well, actually there is a callback for keyboard input. The OnGUI function. OnGUI should be renamed to OnEventCallback or something like that but that would just complicate the understanding of the GUI system. Every OnGUI call is bound to a specific event. The actual event can be read with Event.current.
You can check for Event.current.type == EventType.KeyDown.
edit
Oh and just another little hint:
If you want to create a base class that offers those methods so you can override them in a subclass you have to declare them as virtual and in the sub classes you have to use the override keyword:
public class MyBaseClass : MonoBehaviour { public virtual void OnRespawnButton(){ } public virtual void OnUseItemButton(){ } public virtual void Update() { if (Input.GetKeyDown(KeyCode.R)) OnRespawnButton(); if (Input.GetKeyDown(KeyCode.E)) OnUseItemButton(); } }
public class MyDerivedClass : MyBaseClass { public override void OnRespawnButton() { // Do something } public override void Update() { base.Update(); // Do your additional update stuff here } }
Bunny's answer is much better than $$anonymous$$e. ;-)
It would be better if the answer didn't start with a falsehood and later fix it with a "ps."........
Only because of Layout and Repaint events, but I get your point.
The real problem with OnGUI as a key event processor is that it's completely unconnected to the Input$$anonymous$$anager. That's what convinces me that even Unity think the Input$$anonymous$$anager is a bad design - looking up static key definitions by string every frame is dubious. The API should at least allow:
private var useItem$$anonymous$$ey = Input$$anonymous$$anager.Find$$anonymous$$eyCode("Use Item");
....
if (Input.GetButtonDown(useItem$$anonymous$$ey)) UseItem();
Or even On$$anonymous$$eyUseItem()
as the OP suggests (Unity could implement that efficiently in the same way they only send OnGUI to objects that have the function).
Thanks for the good answer and $$anonymous$$i-discussion guys. I agree the Input $$anonymous$$anager could be implemented better, It's probably just a matter of: "Is it worth the work to fix it?" for the Unity staff.
Answer by AngryMarine · Aug 31, 2011 at 07:57 AM
I don't know of any method to override monodevelop but here's how I would accomplish what you are talking about. I actually use this in my scripts.
function RespawnButton () {
// Do Respawn Stuff
} // End RespawnButton
function OnGUI () {
if(GUI.Button(Rect(across,down,length,height), "I'm a Button")) {RespawnButton();}
} // End OnGUI
That way RespawnButton() is only executed if the button is pushed and the RespawnButton() function is ignored by the Update() function. I just customize my buttons with textures to look like icons and whatnot. Hope this helps!
Thanks for the response, but when I refer to a "button" I mean a keyboard button ins$$anonymous$$d of an on-screen button. Your response does make me think that it isn't possible however, as the "OnGUI" function I would think works similar to the "Update" function and it may be impossible to cut that part of the equation out.
Answer by Waz · Aug 31, 2011 at 07:40 PM
If Unity exposed the InputManager better (vote for that here), you could easily implement such OnFooKey functions generically. But for now you have to enumerate them manually as Bunny83 describes.