Getting into this Unity Way...

Hey folks.

I am slowly (a bit here… a bit there) trying to get my head into the Unity way of doing things.

I think I need to make a major shift in my mindset in order to pull this off. Things that I find simple to do if I wasn’t using Unity seem overly complicated in Unity. It has always been this way to me. And I am sure it has to be because I am just not getting it.

Here is an example of something I expected to be super easy.

Say you are making a top down view game and there are two things in this game world:

A player cube you can move around.
A building made up of several cubes (done this way so there is an opening for a doorway to enter & exit the building).

  • When the player gets near to the building you want the player know that.
  • When the player enters the building you want the player to know that.
  • When the player exits the building you want the player to know that.
  • When the player moves away past the “near zone” of the building you want the player to know that.

I have it working as far as actually detecting Entering and Exiting in both cases (the “near zone” of the building as well as entering / exiting the building itself) and sending that info to the Player. That part was easy.

And this is how I approached it…

I put two colliders on the building and set both as Triggers:

  • First a larger one that covers entire building extending past the building outside for a couple of player cubes worth of distance. This represents the “near zone” and is used to detect the player entering & exiting the near zone of the building.
  • The second collider is inside the building and is used to detect the player entering and exiting the building.

The problem is in the script attached to the building I have no way of knowing which collider has fired. The only information the OnTrigger events receive is the otherCollider and there seems to be no way of knowing which collider on this side was involved in the collision.

Am I missing something?

Is there a way to find out which of the two trigger colliders has fired?
Or am I just approaching this completely the wrong way for Unity?

Like I said I am trying to wrap my head around how people actually use this thing. lol

Thanks!

Have them call different functions on collision?

1 Like

That would be the logical way to do it or to pass some kind of reference in to the function to identify which of the two colliders is triggering.

But as far as I know there is no way to specify a custom function to call. We only have the OnTriggerEnter, Stay, Exit functions and they only pass in the otherCollider that triggered one on this side.

Sure I could then in my code that receives the event on the player side have the player do a cast to figure out which of the triggers it ran into but that just seems… silly. So I think there has to be something I am just not getting.

Either there is a way to know which of the two triggers is firing OR I am just approaching it completely wrong for Unity.

It really would be sweet if the colliders themselves could have scripts attached to them. :slight_smile:

The only thing I can think of is that even for a simple case like this I am supposed to add an empty game object and put one of the two colliders on that empty object and then have its own script.

And maybe that is the Unity way of doing it? But I don’t know it just seems kind of wasteful and strange doesn’t it? lol

It does seem like I remember having a discussion with someone on here at some point and they mentioned the way to do things in Unity is just using GameObjects for anything and everything.

I think it is just so different from any way I have ever developed software games or otherwise it seems alien to me. I look at it like what a huge waste to be plastering GameObjects all over the place when I already have colliders on the building. All I need is a way to find out which collider is firing. But I think I am approaching it from that view because logically that is what you would normally do.

It’ll be interesting to hear what others do in such a case but I am guessing it is “add another GameObject and add a script and move one of the colliders to that new empty GameObject”

I typically move the colliders to child GameObjects. Then you can check which GameObject you intersected with, or you can put seperate collision handling scripts on the various child GameObjects.

A GameObject is hardly expensive. It’s a list of components, plus a Transform. If you need a more efficient system, there are other ways to do this. But it’s likely not worth your time to optimise.

3 Likes

Thanks! Yeah I think this is the fundamental obstacle I’ve always had with Unity. These damn GameObjects. lol :stuck_out_tongue:

I’m sure they are just a kind of light container perhaps even just logical not really existing beyond a tiny object with a list of components.

It just seems odd to be able to add multiple colliders to a GameObject but to have no identifying information for the colliders. And to have a set of OnTriggerxxxx functions that only pass in the otherCollider. I think that is the most strange thing of all. Like why wouldn’t they pass in both colliders. The fact they don’t do that tells me it must not have crossed their minds that someone would have more than one trigger collider on a single GameObject that need to be processed differently.

Okay, I just need to change my view of this model. Seems sloppy to me. lol Like we have to scatter everything around. Instead of having one central place (a single GameObject) that has the colliders and everything else… we need to have multiple GOs. Which to me just seems more complicated. Not sure why it is done this way instead of a more straightforward way.

I will try to keep this in mind going forward. Use GOs for anything and everything. When something seems overly complex (or outright impossible) the solution is almost certainly to add one or more additional GOs.

Maybe I just have a different perspective, but it seems logical to me to have each collider on a separate gameobject, since a collider is a separate entity with its own properties in the game world such as position, rotation. Adding it all to one object seems like it would just hide this fact, and the hierarchy makes it clear what it ‘belongs’ to.

I definitely see the confusing thing about having stuff like manager scripts being on a ‘physical’ gameobject in the game world, and that’s one reason why I’m starting to use static references more, because it seems like a better way to access that sort of thing.

3 Likes

If you’re trying to place multiple colliders on one gameobject, this is not the right idea. Move them to separate gameobjects if you need to know which is which.

I would not attach scripts to buildings, but to colliders themselves (meaning colliders would be placed on an empty gameobject). This makes job of the script very simple, and there’s no need to figure out which one of them fired.

Documentation mentions that the message is sent to both rigidbody and the trigger collider, by the way. GameObject to which the collider is attached can be accessed via .gameObject field.

Also… make sure that OnTriggerEnter/Leave are reliable now. I remember when they weren’t reliably triggering, and number of Enter events did not match number of Leave events.

8 Likes

Well… how would they do that? Allocate a collection? Have multiple functions for different numbers of parameters?

The passed Collider is so you know which one the contact was with. You then have access to the others via the GameObject. You don’t need to have them explicitly passed.

A (set of) Collider(s) represents the physical shape/volume of a GameObject. You can add multiple Colliders together to represent more complex shapes. I suspect that is all it’s meant for (and until recently you couldn’t do that - you could only have one Collider per GameObject). What you’re trying to do is represent different physical shapes/volumes which can be simultaneously interacted with. Having multiple GameObjects is the intended method of doing this.

2 Likes

Thanks for the replies! I’m glad it seems logical to the rest of you.

I don’t understand why it seems unreasonable for the OnTrigger methods to pass in the trigger (or array of triggers) that caused the firing of the event in the first place. To me that is expected behavior. But that’s because in any other model other than using GameObjects for everything it would be expected.

I’m thinking this is definitely the part of Unity that has been a barrier to me. Generally what I did first time around a few years back is look at this stuff and thought “why are they making everything so complicated and bloated?” and that would lead me to writing my own replacement systems. But I don’t want to do that this time around.

I am sure once I get to relying on GOs more and more like for this case and so on it will start to feel more natural to me. I just need to keep in mind GOs are for everything period. They are for representing actual game objects such as player and enemies. They are a way to hook in meta data. They are a way to solve problems such as separating colliders, etc. Everything.

So from this perspective I can start to see the logic in it. Basically these GameObjects are the core of the Unity model. A person needs to fully embrace using them heavily.

1 Like

Glad to see you finally coming around :p, although I’m genuinely interested in what was wrong with your prior setup?
It seemed to me from reading your threads and conversing, you seemed to have worked out quite nicely, your own system working within Unity, even though you were pretty much using the engine for rendering purposes only (simplified view).
Is this more about utilizing the tool and efforts of others - to look into developing a more complex game in the future?

1 Like

@theANMATOR2b The way I normally develop games does work fine for me and works well in any game api I have used. I can develop very quickly that way.

Basically I want to understand how this is intended to be used because (a) I just would like to understand it. I know there has to be some logic to it despite it always seeming illogical and making things harder than they need to be.

And that goes along with (b) I see people (even completely new to programming) knocking out things in less than a week. That tells me there has to be something I’m not getting. Because doing it outside of Unity or in Unity using my custom approach sure I could get it done quickly but doing it the Unity Way it would take me much longer.

So I want to learn what it is these new people are seeing and doing that I do not see and do.

Actually on lunch break I redid my project using two more GOs for the colliders and it works beautifully. I am starting to appreciate it more now and slowly getting my mind into using the GameObjects in this manner. See I wasn’t really looking at GOs as just containers to be used for anything & everything. I saw GOs as like a building, a player, an enemy, etc.

1 Like

IIRC when rigidbody colliders (i.e. attached to rigidbody) are involved, the set of colliders is “collapsed” into one compound collider. So it is possible that the engine might not be even discerning between different colliders on rigidbody at all.

Documentation implies that OnTriggerEnter is passed to both objects - the trigger and the object.

Also… you need to understand that GameObject is treated as pretty much an equivalent of a base class in a gui framework, except that message/event handlers are added via composition and not inheritance.

In a gui framework, standard behavior is ThisObject::onMessageReceived(OtherObject messageSender), and not MessageMap::messageHandler(Object receiver, Object sender)

I think the first approach is used pretty much everywhere, while the second one … I think it only ever appeared in MFC (not sure about it, though, might be wrong).

1 Like

@neginfinity Thanks. Yeah that is the fundamental thing I am wrapping my head around. I made a lot of progress on lunch break today toward seeing the light.

You are exactly right the issue was kind of not seeing the forest for the sake of the tree. Although I kind of knew it wasn’t the case (because I use them for organization “folders” in project and as high level containers in scene) I mainly didn’t view them as just ultra lightweight generic containers of components which is all they really are. I saw them more as a player, an enemy, a building, etc. Actual GAME objects as in objects in the game. lol

Okay, I had another play around with this.

I get it now. These GOs are the key to everything. And now I understand why everyone loves working in the Editor so much… because well that is where we add all of these GOs for whatever is needed.

I’ve attached a little example project just the very early start of prototyping an RPG. Not much to it of course, more it was just playing around wrapping my head around using Unity the way it is intended to be used instead of me writing everything from scratch. lol

I kept everything very straightforward & simple still but I think this is the Unity Way or at least will probably be my Unity Way.

Just use the Arrow keys to move the cube player around. Again, there is not much to see. Just a basic foundation.

I must say it is nice the light came. lol Now I can see why projects always have so many GOs plastered around… for everything. I always thought people did that because they had no idea of how to do it any other way… no programming background. :wink:

Anyway, it is good stuff.

3010839–224635–SimpleRPG.zip (61.7 KB)

1 Like

OH… you have both triggers on the same object.

I would never do that. It’s so natural to me that “an object only has one trigger,” that when you said “I have two triggers on the building” I just naturally assumed the building had a child GameObject containing each trigger. I always inherently consider “multiple triggers on one object” to equal “the CSG sum of all triggers,” because that’s what you get - it’s like having one trigger with a really complex shape.

You know, the whole “Unity way” thing. I wrestle with that a lot, too. You have to learn the rain dance for specific things before you can make them work, and then you forget it’s a dance and not just how those things are done.

1 Like

Yeah I’m used to a code way of doing things. And I wouldn’t add overhead of “stuff” just to manage multiple colliders on an object.

If I was just programming this all I would have my own collider class and then just add a colliders array to the building object. Then at startup, population of the world when those are created they’d get two colliders. I still don’t know much of Unity specific stuff. Like I am not sure how I’d figure out the size for automatically sizing the colliders in Unity if I was to do it all programmatically. I imagine there is something in the API some place to do that. But it is all of that extra work of learning their specific way of doing things that also put me off. It’s generally just faster to write it all yourself instead of having to stop constantly and refer to reference material or use the (dot) to find the list of potential candidates.

But I am trying to get into the whole just embrace the Editor and visual way. Because I can see already this is where Unity really shines. Of course, I dread using the Animator again. I hated that thing. I think this stuff is great for people trying to make like pro level quality games but is way overkill for the majority of use cases in my opinion. Plus I always thought that whole SetBoolean and other stuff way of working with animations was really a weird way of doing things. lol But I will probably check it out again.

Using the dedicated child GOs works very well. Embracing the GOs is a big change for me. And it does make it easier. Just slap them on, mess with the numbers in the Inspector until get the size to a “good enough” and it is done with.

Contrast that to a few months after getting into Unity I spent about a week trying to find a way to create a class that could just manage a list of Renderers and use them directly because I thought why in hell do these damn GOs anyway?! I never could get that to work though.

Ha ha. It is definitely unique. But I am having fun with it now. It’s like I can use more of the programming experience I have by using Unity in this way. Before I had thrown not only Unity proprietary stuff out as much as I could but also threw out interfaces… actually all of OOP in general and went completely procedural.

I would make an empty GameObject and call it “Near Building Region”, then I would give it a box collider, cube mesh filter and a mesh renderer, and give it a translucent purple material.

Then, I would place it where I wanted it in 3D space.

Then, I would add a script called “Trigger Region”, and inside I would code it up to expose some values to the editor, like a filter for which tags are allowed to trigger it, etc. then I would script up some options for how this trigger region responds to being triggered, such as shooting a message to a specific game object/script, or calling a script, or even destroying another game object. All of this would then be easily able to be slapped on various regions throughout the level that when triggered, do different things.

So you can easily use this same TriggerRegion script to create a goal region which sends a message “ReachedGoal” to a level manager object, or a TriggerRegion which sends a message “TrapActivate” to another script, which then releases a rolling boulder.

And I do everything like this. Generalized components that can perform flexible tasks.

. . .

It helps to think of all of your game objects as being independent of one another. They can talk to each other, but what they do with the information they receive is up to their individual behavior, which is defined by the scripts you put on them. These objects don’t have intimate knowledge of one another, don’t rely on each other to function, but they aren’t completely in the dark either, they have a sort-of protocol on how to talk to each other.

You can do so many interesting things when you build your Unity project this way.

Comparing this to a more linear, procedural, game-loop style of script, your objects need intimate knowledge of how to talk to other objects and also the prerequisites for talking to other objects, and each object in a way needs to know what all the other objects are doing.

With component architecture, you should be able to delete any object at any time and not crash the game. Just create unpredictable results.

GameObjects are whatever you want them to be.

They are managers, they are emitters, they are character, actors, they are hinge points for doors, they are position markers, they are at their core nothing more than a 3D transform with an unlimited number of components you can add to them.

The “unity” way is really the fulfillment of the class-architecture paradigm, these objects are literally independent, atomic.

You will find that its actually extremely easy to do things in Unity if you embrace it.

2 Likes

Yeah I used to love the composition approach. I just had a real hard time getting into Unity. A few different reasons for that I think. The Editor and the strong focus on GameObjects (that I never really got until just today), the Animator, and just the massive amount of framework in general.

But I am just going to have fun with it. I had a real light bulb moment when the whole GameObjects are for anything you need them for concept clicked today.

I am actually finding myself enjoying the Editor now that I am working in it more instead of trying to get out of as fast as I can. I am still happy with procedural programming approach as well. Any approach is fine really as long as I can get things done.

I notice the GameMaker Studio code seems to be entirely procedural oriented. And you know there is a real beauty to that. It simplifies things and makes it much quicker to just get the job done instead of engineering “proper” OOP systems and so forth.

1 Like

There’s a place for

Whatever gets the job done and doesn’t drive you crazy.

1 Like