Playmaker Forum

PlayMaker Updates & Downloads => Share New Actions => Topic started by: dudebxl on December 02, 2015, 07:43:05 AM

Title: ArrayList Find GameObjects Inside Collider
Post by: dudebxl on December 02, 2015, 07:43:05 AM
Add to an array all the objects (3d or 2d) which are inside a collider. Extension to http://hutonggames.com/playmakerforum/index.php?topic=11673.0

Filter by tag (obligatory) then optionally by layer.

2 actions:
- ArrayList Find GameObjects Inside Collider
- ArrayList Find GameObjects Inside Collider2D

on ecosystem or https://snipt.net/dudebxl/
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: foxdeltagames on December 02, 2015, 11:01:26 AM
nice! this can come in handy :)
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Acavodo on July 15, 2017, 03:52:47 AM
Hi! Im trying to use this action for bomb effect.

Here's capture for my setting.


it is not finding any object which I tagged correctly.

I think "Collider Target" needs its own collider component right?

help !
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: omgitstri on October 16, 2017, 10:34:05 AM
Hello,

I think I found a small bug about the action, it seems like the Root GameObject requires to have a Mesh Renderer for this action to add it to the Array List.

Right now I have a gameobject (Tile) within it I have a child gameobject (Mesh) so I could easily swap out the placeholder in the future and this is causing it to not add the Tile into the Array List.

A work-around that I'm using now is to add a MeshRenderer on the root gameobject with nothing in it so the action could detect it.

Tri Nguyen
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: jeanfabre on October 16, 2017, 11:29:23 PM
Hi,

 I checked the action and yes, it's a requirement, is that a problem for your case?

 Bye,

 Jean
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: omgitstri on October 17, 2017, 07:47:33 AM
Hello,

Maybe it's just my workflow that makes me think it's a bug.
I usually have the Root contain all the scripts/FSM and have its Child be the mesh, that way i could always update the mesh whenever I want to without having to add the script/FSM again. Because of this, my Root gameobject don't have a mesh renderer and that causes the action to not work.

Tri Nguyen
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: omgitstri on October 18, 2017, 09:58:55 AM
Hello,

The action does not seem to work if it is on a prefab that gets instantiated.
I tested this by:

Tri Nguyen
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Deek on March 11, 2018, 08:36:59 AM
I've created two new actions based on dudebxl's derivations to be found on the Ecosystem:
"List Game Objects Inside Collider" and "List Game Objects Inside Collider 2D".
They differ in that they rely on the target GameObjects to have Collider/Collider2D components instead of Renderer/Sprite components, the 'Collider Target' variable only allows the right component to be inserted, the 'Tag'-variable only shows the existing tags as a drop-down list instead of a string input and is set to 'Untagged' by default; they optionally store the result in an FsmArray, store the amount of entries and update every frame.

I would also propose, that the actions by dudebxl actually say that the target GameObjects need to have a Renderer component and for the 2D version a Sprite component somewhere, because they are otherwise confusing and don't seem to work if you don't know that.
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: krmko on April 11, 2018, 12:28:24 PM
I've created two new actions based on dudebxl's derivations to be found on the Ecosystem:
"List Game Objects Inside Collider" and "List Game Objects Inside Collider 2D".
They differ in that they rely on the target GameObjects to have Collider/Collider2D components instead of Renderer/Sprite components, the 'Collider Target' variable only allows the right component to be inserted, the 'Tag'-variable only shows the existing tags as a drop-down list instead of a string input and is set to 'Untagged' by default; they optionally store the result in an FsmArray, store the amount of entries and update every frame.

I would also propose, that the actions by dudebxl actually say that the target GameObjects need to have a Renderer component and for the 2D version a Sprite component somewhere, because they are otherwise confusing and don't seem to work if you don't know that.

Am i doing this right?

(https://s26.postimg.cc/x4o8ynwnt/screenshot_171.png)

I don't seem to be getting anything :(
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: DanielThomas on April 13, 2018, 10:05:10 AM
Just wanted to say I get the same problem as krmko, nothing shows up. Anyone who can confirm they got it to work?
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Deek on April 13, 2018, 03:25:30 PM
Yup, that was a mistake on my part.
In the original actions the GameObjects in the scene got searched by tag with the function "GameObject.FindGameObjectsWithTag()", which requires a tag to be specified and doesn't seem to allow the 'Untagged'-tag.
Since I naively assumed that it would just work to set the 'Untagged'-tag by default and only tested both actions with a specific tag, I didn't think 'Untagged' would cause any trouble.

I fixed this problem, which means you'd need to re-download the actions from the Ecosystem. Sorry for the inconvenience.

I also re-worked both actions to not only allow to filter by 'Untagged'-GameObjects but also made that tag filter completely optional, meaning you now can set the tag to 'None' and it ignores that tag filter, resulting in listing every GameObject regardless of the tag. The layer-filter is unaffected and can be used in conjunction with the tag-layer to narrow down, which GameObjects to capture.
Additionally, I implemented an error check when the collider target wasn't set and that when toggling the tag from 'None' to the tag-list it shows 'Untagged' instead of an empty entry (uses OnGUI so it might not always do that, but that would be just a minor inconvenience if not).


P.S.: If anyone is interested to know how any of these actions work (for clarity or performance reasons), here a short rundown:
- the action searches for each active GameObject in the scene (dudebxl's versions directly by tag, which is slightly more performant but forces you to define a tag, while mine search for any Object of type GameObject; in either case these actions should be repeated/used as scarcely as possible to reduce that overhead of constantly going through all GameObjects in the scene);
- it checks for each found GameObject if it matches the specified tag and layer;
- skips any GameObject that doesn't contain an appropriate collider component;
- gets the bounds of each collider, sees if it intersects the bounds of the user-defined collider and only lists the GameObjects that match all these criteria
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: agelvik on February 18, 2019, 02:50:35 PM
I've created two new actions based on dudebxl's derivations to be found on the Ecosystem:
"List Game Objects Inside Collider" and "List Game Objects Inside Collider 2D".
They differ in that they rely on the target GameObjects to have Collider/Collider2D components instead of Renderer/Sprite components, the 'Collider Target' variable only allows the right component to be inserted, the 'Tag'-variable only shows the existing tags as a drop-down list instead of a string input and is set to 'Untagged' by default; they optionally store the result in an FsmArray, store the amount of entries and update every frame.

I would also propose, that the actions by dudebxl actually say that the target GameObjects need to have a Renderer component and for the 2D version a Sprite component somewhere, because they are otherwise confusing and don't seem to work if you don't know that.

Hey,
The script works well except when the collider gets rotated.

Seems like the action doesn't list objects accurately when it's rotated which results in undesired results... Instead of listing objects according to the colliders shape, it translates to this square shape and list objects that are expected to be outside of it.
I'm using "List Game Objects Inside Collider" btw, don't know if same applies to the 2D version

Would be awesome if this could get fixed!
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Deek on February 20, 2019, 01:26:03 PM
@agelvik

Yea..., apparently the Bounds.Intersects() method I used in both actions doesn't play nicely with rotated objects since it uses the root rotation instead of the local one. You can actually find a few posts on the Unity forum mentioning this behavior, but it seems to be like that by design.
I've found a few possible solutions involving Raycasting to detect overlapping areas, so I will try to implement them on the weekend.
If one of them work, I either replace the current behavior or add a checkbox to use the Raycast version for detecting rotated objects accurately, as it is usually less efficient. I also remember creating a script that checks if NGUI sprites are in view by using the camera's frustum, so that might also be an option for this.

I didn't know of this behavior so thanks for pointing it out and I'll see if I can find a fix or better solution for that.
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: agelvik on February 21, 2019, 08:43:39 AM
Much appreciated, thanks!!
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Deek on February 23, 2019, 05:07:33 PM
I now improved both versions to more accurately detect colliding GameObjects even with a rotated source GameObject. The 2D version is way more accurate in regard to box colliders, since it uses a built-in function for detecting overlapping colliders and on the 3D version I had to manually adjust the extents of the collider, which means that there can still be a small gap between two colliders in which the second one gets recognized (and judging by your screenshot, you probably should use 2D colliders anyway  ::)).
Each should be a bit more performant, because they don't go through each GameObject in the scene anymore. On top of that, I also added a filter to ignore triggers and removed the "Incl Layer Filter" checkbox by making the Layer field start as 'None', as well as other minor improvements.

They have been updated in the Ecosystem and are also available in the attachments.
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: agelvik on February 24, 2019, 08:11:17 AM
Tested both of them and the 2D action by far gives the best and most accurate results! :D I didn't notice much of a difference with the 3D tho. Made some gifs to show it on my end:

3D action
https://www.dropbox.com/s/xr6tahiotwtn3im/hitbox_issue.gif?dl=0

2D action
https://www.dropbox.com/s/7m2i3g9em1wf54s/hitbox_2d.gif?dl=0


Also got some errors after I imported the 2D action. In line 104-110 there were some converting issues. I simply removed the if-else-endif lines and only kept:

Collider2D[] results = new Collider2D[99];
col.OverlapCollider(filter, results);

Worked fine after that!

I guess I'll do a combination of 3D and 2D physics, it seems to work to have Rigidbody on-top of the hierarchy and Rigidbody2D further down lol. Even tho it's a 2D game I feel I have a lot more control and flexibility when using 3D components haha.

Here's the full message from console btw, in case you want the full thing:

The best overloaded method match for `UnityEngine.Collider2D.OverlapCollider(UnityEngine.ContactFilter2D, UnityEngine.Collider2D[])' has some invalid arguments
error CS1502: Assets/PlayMaker Custom Actions/ArrayMaker/ListGameObjectsInsideCollider2D.cs(106,8)

Argument `#2' cannot convert `System.Collections.Generic.List<UnityEngine.Collider2D>' expression to type `UnityEngine.Collider2D[]'
error CS1503: Assets/PlayMaker Custom Actions/ArrayMaker/ListGameObjectsInsideCollider2D.cs(106,32)

Using unity version 2018.2.10f1
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: Deek on February 24, 2019, 09:01:28 AM
To improve the accuracy of box colliders on the 3D version is quite a pain, though it did improve a bit from the previous version. Maybe someone could point out how to do it better, but for now I think it's okay enough, since it only affects the area around the corners when rotation the GameObject.

I added these define conditions to the 2D version when I realised that using lists for the built-in function OverlapCollider() is only available in a later Unity version, but because the Unity docs don't say which version added that feature, I was hoping that it was somewhere after 2017 and added backwards-compatibility by providing a big empty array (being less performant and more limiting than a list). It seems to have been added somewhere between Unity 2018.3 and the 2019 beta, which I used when trying to improve these actions.

It might be a good idea to stick to either 2D or 3D physics for your game, to prevent any problems down the line, and I think there isn't that much that you can do with the 3D components that you can't do with the 2D ones. You actually have more options on 2D colliders for example, that are also more catered to the world of 2D, just like the behavior of 2D Physics. Also you would need to maintain both the 'Physics' and 'Physics 2D' Project Settings when making changes to the general parameters and collision matrices. Just a tip to remove the headache when you one day wonder why those two colliders don't react to one another.  ;)

Your game/prototype looks awesome by the way, I really like the hit effect on the enemies and bounciness of the character!

I'm just gonna fix that error on the 2D version by specifying a higher Unity version and call it a day. Maybe I'll improve upon the 3D one in the future.
Title: Re: ArrayList Find GameObjects Inside Collider
Post by: agelvik on February 24, 2019, 01:05:47 PM
Yeah can understand it's a bit tricky to get it fixed, but right now the 2D action works just fine for what I need which is what matters. :) Thanks for giving it an update in such a short notice, especially since this thread is like 1 year old haha.

Thanks for your tips & kind words about the game btw!