Ignore actors with a specified collision response from a trace

So, I’m using a capsule trace to determine where the player can move (there are good reasons for doing this), however, I’m having a slight issue with trigger boxes, for example. If I allow the trace to pick up objects with the collision type WorldDynamic, then the trace picks up trigger boxes, which prevents the player from walking through invisible walls that should be immaterial. I notice that the capsule trace has an “ignore actors” node, which I assume takes an array of actors that the trace ignores. This seems like the right thing to use, but to do this correctly, I need to create a list of actors with a specified collision response. I can’t find a function that will do that. Is this possible?

Hi ,

To set a custom collision, you can go into the project settings menu and find the collision submenu. In there you can set your channels. Then, when you have an object that needs this collision channel, simply set their collision to custom in the details pane, you can then set a channel in one of the menus that opens up underneath.

That’s not actually the problem I was having. My issues ia that traces, such as line trace and capsule trace, do not actuallu consider the per-channel responses of objects, just their label, so an object marked to ignore all collision would still be picked up by a trace to the channel containing it. This is sometimes desirable, but often not.

As I said in my question, I’m using a capsule trace, and while I can set it to ignore specific channels entirely, I can’t get it to ignore actors with a specific channel response. It’s not that the function isn’t working, it’s that I can’t see how to implement the functionality in the first place.

Depending on which type of trace you are running, you should have the ability to ignore specific channels, so it won’t register when the trace is run at all. Though, this makes me wonder. Are you setting the object channel for objects that have multiple components? If so are you making sure to change the root component to the specific channel?

Oh ok, I was looking at what you were saying backwards! Can you post a screenshot of your trace bp? I might be able to see what is going on and how to get it to work correctly.

Well, there’s not really much to look at, to be honest:

Obviously this isn’t the actual trace, but it’s all the relevant information. The start and end point are just the player and the point the player wants to move to, and the radius and half height are constants. The rest is the same as shown.

I’d like to add to the array of available objects all the WorldDynamic objects, but since the Trigger collision type sets the object to the WorldDynamic channel, this produces problems, since the player should be able to walk through triggers. While I could make a new collision channel to work with for triggers, I’d rather solve this issue now, if at all possible.

My two potential solutions were: a) produce an array of all actors without the channel response “block” to pawns, and feed that into the “Actors to Ignore” channel, or b) analyse the collision results and read the channel response afterwards.

The first is preferred, but there seems to be no way to find an actor’s channel response. The second would probably work, but again, there seems to be no way to actually find this information.

You can do a trace before this trace, running a Capsule trace by channel, and any channel that is supposed to ignore the user you then stick into an array for your object trace.

I’m… not sure how that’s supposed to help? I don’t care about which channel the scene actor is in, I care about what its channel responses are.

Just a suggestion… why not play with"GetOverlappingActors" to ignore “Triggers” and/or BP interfaces to specify which types should be allowed and restricted ?

Here’s a little graph with both:

I’m not sure about what you concretely need to do so that might not be what you need but I can’t see how to get the response info so.

In my example on my map I’ve put a trigger volume, an instance of a BP called “BP_DangerZone” implementing an interface called “BPI_RestrictedArea” and an instance of a BP called “BP_SafeZone” implementing an interface called “BPI_OpenArea”. To minimize the use of this I only do something when the capsule has already hit something (assuming it is large enough to not need to check further away, this might change for you and you might need another event). When hitting the trigger zone I get “Triggered allowed” as output as the cast on the “Other actor” succeeds. I then do a trace ignoring the triggers first but also all the objects implementing “BPI_OpenArea” which should not prevent movement (using only the overlapping actors as I’m assuming I would already be touching them, and trace here only one unit forward). If there is not hit on any other object then I print “Movement allowed”. If it has hit something I get all the actors implementing the “BPI_RestrictedArea” interface (could also get only the overlapping actors but it’s just for the sake of covering more possible ways of doing the work) and check if the hit actors belongs to that list. If so then I hit a restricted area and thus will print “Movement restricted”.

Hoping it somehow helps…

Now, the problem with that is that there is no capsule component overlapping the objects that the trace is testing against. This assumes that the objects are all already colliding with a capsule, but the way my code is set up, this is necessarily not the case - in fact, if it were, the trace would not really be necessary at all. The objects are most likely to be reasonably close to the player, but this is absolutely not necessary, and they could be quite far away. GetOverlappingActors isn’t particularly helpful when there’s nothing really for them to be overlapping.

As well as this, that example filters by class, not by collision response. This is a potential solution, but one I would like to avoid if possible, because it could easily cause confusion in the future.

I know I’m a bit late to this and you’ve already marked the question as answered but I ran into this and was curious… why don’t you simply create a custom trace channel, set it’s default response to Block, then in your trigger boxes set the response to ignore, and then trace via that channel? Your capsule trace should then ignore them.

I haven’t marked the question answered actually.

I can’t do that because I can’t specify a channel on which to run a trace, that’s the whole problem I’m having. The capsule trace can only block, overlap or ignore objects in a specific channel, but it doesn’t take into account the channel response of the object. I could create a new channel for objects I want the trace to ignore, but that’s time consuming, awkward, and has the potential to fail if I miss any of these objects. I’d much rather use the system already in place.

I haven’t marked the question answered
actually.

Ah, the forums can be buggy sometimes.

I could create a new channel for
objects I want the trace to ignore,
but that’s time consuming, awkward,
and has the potential to fail if I
miss any of these objects.

I don’t follow this logic. You create the channel in the editor with default to block (very simple). I will assume you have a parent class/blueprint for you pickup items where you can change the response to this new channel (very simple). Use CapsuleTraceByChannel and your things work as you want.

I’d much rather use the system already
in place.

What do you mean? If there was a “system” already in place you would be using it. The channels and collision system is the “system” in place for you to use… an array of specific actors to ignore, or an extremely robust collision system with channels that allow you to do exactly what you want very simply.

Well, I completely understand if this isn’t the solution you were looking for and you’d rather try something else. I simply wanted to suggest this solution as it’s pretty straight forward.

Edit: I also realize that it is difficult for us (other devs) to fully understand the intricacies of your project and these solutions might not fit well. Again, I just thought I would throw this possibility on here.

I’m still not completely clear on what you are trying to achieve. If I refer to the original question that said you are using a Trace to determine where the player can move. You must be handling the “Collision” stuff on your own and only using the trace to determine if your player should “collide” or move through the object. A custom trace channel with customized default collision profiles (WorldStatic, WorldDynamic, etc) will achieve the result you desire. You can modify the Trace and Object Type responses for each profile in the editor.

Technically, you could either create a new Object Channel or Trace Channel and assign a default response. Then you go through the “Preset” collision response profiles and adjust the response to this custom channel for the defaults and any other channels you created.

Some combination of this functionality should be able to get you the desired result.

I’m sorry I don’t have a definitive answer but it’s still kind of difficult to understand exactly what you are trying to do.

My issue is that CapsuleTraceByChannel only seems to give me the option of using Visibility or Camera. Reading up on it, it looks like that would do almost exactly what I want (I’ll get back to this), but only if I could treat the capsule trace as belonging to the “Pawn” channel. If I have to make a new channel type, it requires redoing all of the collision presets, which is a lot of work.

As well as that, it also doesn’t provide all the functionality I’m looking for. It seems that trace functions only get half of the functionality of the collision system. TraceByObjects deals with one half, while TraceByChannel deals with the other, but there doesn’t seem to be one that contains all of the features of the collision system simultaneously.

I’ll try to explain. If I have a capsule object, which is on the channel “Pawn”, and has a response to “WorldStatic” of “Block”, and another object, in the channel “WorldStatic” with a response to “Pawn” of “Block”, then the two objects will collide and not move through each other. If I had a third object on channel “WorldDynamic”, which the capsule responds to with “Ignore”, then they will pass through each other.

Now, replace the capsule object with a trace. If I use CapsuleTraceByObjects, I can simulate the original capsule’s collision response by testing against “WorldStatic” objects and not “WorldDynamic” objects. However, if I had another “WorldStatic” object, which had a response to “Pawn” of “Ignore”, this trace would still collide with that object, where the original capsule would not. This is what I currently have set up, and is undesirable.

If I use CapsuleTraceByChannel, I can read the collision response of objects I trace against. This is good, as it removes the issue with CapsuleTraceByObjects, but now another part of the collisions no longer works: my “WorldDynamic” object, set to “Block” for “Pawn” objects is now treated as a collision, where previously, it was ignored, as the response of the original capsule object to “WorldDynamic” was “Ignore”.

One of these systems allows me to account for the collision response of the trace, but not the channel, while the other allows me to account for the channel, but not the collision response.

What I’m looking for (and, since it seems like it doesn’t exist, requesting as a feature) is a way to consider both at once - A trace by channel that also allows me to define a collision response for the trace itself (or a trace by objects that allows me to define a collision channel for the trace).

I think I’ve got it working. I wasn’t aware you could add trace channels to the default collision profiles. I assumed I would need to change every object’s collision profile if I did it this way. This seems to be doing what I want now. Thanks!

Awesome. I’m glad I could help.

My answer from comments on original question.

If I refer to the original question that said you are using a Trace to determine where the player can move. You must be handling the “Collision” stuff on your own and only using the trace to determine if your player should “collide” or move through the object. A custom trace channel with customized default collision profiles (WorldStatic, WorldDynamic, etc) will achieve the result you desire. You can modify the Trace and Object Type responses for each profile in the editor.

Technically, you could either create a new Object Channel or Trace Channel and assign a default response. Then you go through the “Preset” collision response profiles and adjust the response to this custom channel for the defaults and any other channels you created.

Some combination of this functionality should be able to get you the desired result.

I’m sorry I don’t have a definitive answer but it’s still kind of difficult to understand exactly what you are trying to do.