UnityEvent, where have you been all my life?

Ya @JoeStrout in respect to your sons hack n slash game, it reminds me of working with goldsrc engine and worldcraft(old hammer) before I could code. I was able to create new gamemodes just using the maps IO system provided in the editor on entities. This IO system is really just a UI to choose receivers for events.

Really if you use UnityEvent and create a few logic and trigger components you can get a lot done with no code. At work I plan on making a large library of logic and trigger components for envirmeant artists to add logic to scene with out code.

1 Like

I’m thinking the same. Perhaps we should collaborate? The community could come together and make a large collection of simple, one-task components that you can snap together via UnityEvents to make a game without code.

For example: at the school where I’ve been volunteering, one of the kids has been working for the last week on a “flappy bird” style game (except instead of a bird it’s a cube; he calls it “flappy cube”). He’s got physics turned on, and has a script that moves the block forward at a constant velocity, and when the spacebar is pressed, applies a 500-newton upward force. Nothing happens yet when you collide with obstacles but he has ideas of making that trigger a game-over state.

OK, so how would you build this out of events and components? I’m thinking something like:

  • ConstantSpeed: lets you specify a velocity vector and which axes to apply to; smart enough to work with or without a Rigidbody.
  • InputTrigger: lets you specify an input type (e.g. KeyDown) and input (e.g. KeyCode.Space), and invokes an event.
  • ApplyForce: specify a force vector and duration; public Apply method adds that amount of force over that many seconds.
  • CollisionTrigger: specify the collision mask; invokes an event.
  • PlaySound: actually may not need to make this; I think an AudioSource can probably be triggered by an event already!

So there you’d go: use ConstantSpeed on the X axis to get the continuous forward motion; InputTrigger set to invoke the ApplyForce to get the upward push whenever you hit the spacebar, and also play a flapping sound; and CollisionTrigger to detect hitting obstacles and do whatever you want — disable the ConstantSpeed component and play a death sound for example.

Jeez, as a teacher, this gets me excited — not only would kids get very rapid success snapping these games together like Legos, but when they want to peek under the hood, each of these components is going to be short and easily understood.

Maybe I should start a new thread over in the teaching forum… though such a library wouldn’t be just for teaching; as you said, it’d be great for environment artists too.

1 Like

You can basically already do that with playmaker. Or other “visual scripting” packages.

Yep. But that’s not how I’m interested in doing it. (I can elaborate on the reasons if you like, but I feel like it’d be repeating much of my previous post.)

This is all new to me, and I’m now very excited to go try it out. Thanks for bringing it to my attention, @JoeStrout !

1 Like

@JoeStrout ya those to start but also some pure logic components, like logic case which would be like a switch statement, and logic relay which can be used to fire off a bunch of events at once when triggered or in sequence with timers. Also maybe a basic math component as well. A component that can make descions based on tags as well would be great.

Also a modified inspector preview window that can display what is subscribed to a component so you see at a glance what triggers a component and what they component triggers.

Those logic components are a very interesting idea. I’m going to have to give that some more thought.

As for the inspector preview, I’m not quite sure I follow you. The UnityEvent inspector already shows you what is subscribed (i.e. all receivers). Did you mean the other way — some way to see what events a method is currently set up to be invoked by?

Yes exactly, be nice at a glance to see what it invokes and what can invoke it.

Great idea, @JoeStrout !

I’d really like another inspector UI for the OTHER way round also. ie Listeners subscribing themselves (in addition to the current UnityEvent of the invoker having the listener references)
I’m thinking the same little + button (maybe next to the help icon on components, or part of the cog icon, “Add listener”).
This would then add similar UI blocks at the bottom. You’d then drag in a GO containing a UnityEvent, select the specific component and actual event. Then you’d finally select the function/property from the current Component, much like you do now (without the component selection)
NOW you’d be able to click together a properly decoupled game without code.

ps Supporting static events by dragging in RAW C# CODE or PREFABS would rule. Or just displaying them anyway regardless of any actual use in the instances.
pps It seems UnityEvent doesn’t display all properties and functions. Why not? eg Transform’s Rotate function.
ppps Why can’t I add custom parameters without defining a whole new class? This seems messy to me. I expected to be able to do something like
public UnityEvent OnEventWithInt;
I guess you can’t do that in C#?

With reflection and a custom inspector you can do pretty much whatever you want.

Yeah, but @Vectrex is right, UnityEvent and the built-in editor aren’t quite as powerful as one would like. But it’s (almost) the first release; perhaps we’ll see more development of it in future releases.

Personally, I’d be happier now if there were some easy way to select the current object as the recipient of the event. Instead I have to go find it in the Hierarchy list, or use the object browser — this feels like unnecessary work when I’m already inspecting the object I want to select!

They probably didn’t imagine that this would be common, but I’m finding it so, even with UI things like Button. For example, I have a scene switcher component with a public Load(sceneName as String) method. When I have a scene selection menu or a Back button, I simply throw this component onto each button, and invoke it via the button event. This makes my buttons fully self-contained, so I can copy one and paste it into another scene for example.

Does anybody know a shortcut I’m missing for assigning an object reference to itself in the editor?

Can’t you just drag that component into the field?

Drag it by what? I can’t find any place on a component that’s draggable. Nor can I find anything draggable at the top of the inspector that would represent the whole object (though this wouldn’t be very convenient anyway, since often I’d have to scroll to reach the top, then scroll back down to reach the field I’m trying to fill in).

I usually just drag the component name into the field:

1 Like

I think the most important thing to add is clearer documentation. As it stands you have little choice but to learn about UnityEvent by trial and error, or forum posts by this one. And I’m not even certain of the extent of its capabilities (on account of this documentation dearth), so it’s hard to make further feature requests without that.

However, I can make one: The ability to call static functions. The interface for this might be tricky to create without being overly cumbersome, but it’d be well worth the trouble. We could bypass OP’s EventLogger script and call Debug.Log directly. We could make our level’s enemy call functions for the Player object, or the UI, even if those things are in different scenes until the game is running.

3 Likes

The static thing could be solved by allowing you to drag and drop the script into the object field. As of now, you can do that, but the only thing you get available is the script’s name.

By the way, this means that you can have buttons in your game change the name of your scripts. THIS IS PROBABLY NOT A GOOD IDEA.

EDIT: just checked, it doesn’t actually work. Which is probably a good thing.

2 Likes

Well I’ll be dipped in spaghetti. It works! I had no idea you could drag the component name; I was always trying to grab the icon instead. This is a serious time-saver!

Tony, you da man. If we ever bump into each other, I’ll buy you a beverage of your choice!

3 Likes

Well, there it is. Interface problem solved.

1 Like

That doesn’t help with messy extra components cluttering up the place. I actually do that now with C# events using the component “ZZSignalSlot” on the asset store. I had to bug fix it, but it works nicely. But the extra components in the inspector get really messy and hard to keep track of things, so an integrated solution is always going to be better.

Hmm, can we ADD our own inspector UI stuff to ANY component?