[ZScript] Actor Only Non-Cube Collision

Handy guides on how to do things, written by users for users.

Moderators: GZDoom Developers, Raze Developers

Forum rules
Please don't start threads here asking for help. This forum is not for requesting guides, only for posting them. If you need help, the Editing forum is for you.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

[ZScript] Actor Only Non-Cube Collision

Post by Major Cooke »

Before starting, I must warn you that this isn't advised when using lots of actors at once. Graf has stated this may cause slowdowns, potentially. Make sure you use with care!

Also, this does not work with level geometry (walls, floors, ceilings, etc). Sorry, but there's no way around that. This is actors only.

Now onto the good stuff.

This is code for cylindrical collision, for example.

Code: Select all

override bool CanCollideWith(Actor other, bool passive)
{
    if (!passive)
    {
        if (!other)    return false;
        return (Distance2DSquared(other) <= (other.radius ** 2));
    }
    return true;
}
I will post more in good time once I come up with them. Here's a hint though... One can go spherical if they use Distance3D instead of 2D (additional adjustments may be needed).

Bear in mind the following:
  • CanCollideWith activates last, after all the other internal collision checks pass and find an actor to collide with. I.e. all the THRU flags (species, ghost, NOINTERACTION, etc). If any of those happen to dismiss the actor as non-collideable, naturally the function won't trigger.
  • The function only triggers if the two actors are actually touching.
  • 'passive' means the actor that's NOT doing the collision check.
  • It's unclear if normal actors are always forced above/below standard geometry if trying to force move them below ground or above the ceiling.
  • There are plenty of caveats to using this -- sliding along actors for one goes down the toilet, mostly. You'll have to come up with your own bouncing algorithm of things that impact it.
  • The actor's box is still a square, and is still AABB. You are only changing collision with other actors.
  • This is for actor to actor collision only.
  • This doesn't affect map geometry.
  • This doesn't affect map geometry.
  • This doesn't affect map geometry. Just to make sure this note's clear as mud.
Last edited by Major Cooke on Fri Jun 21, 2019 11:37 am, edited 1 time in total.
User avatar
Rachael
Posts: 13789
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her

Re: [ZScript] Actor Only Non-Cube Collision

Post by Rachael »

One thing that *might* help speed it up (but requires testing/profiling) is to simply do something like:

Code: Select all

if ((self.x-other.x)*(self.x-other.x) + (self.y-other.y)*(self.y-other.y) < (self.radius+other.radius)*(self.radius+other.radius)) return true;
The idea here is to prevent a square root calculation, but it might not actually help considering the number of lookups this requires.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: [ZScript] Actor Only Non-Cube Collision

Post by Major Cooke »

Graf optimized the hell out of the square roots. But I'll let him comment on which is faster.
Last edited by Major Cooke on Thu Jul 27, 2017 11:41 am, edited 1 time in total.
User avatar
Rachael
Posts: 13789
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her

Re: [ZScript] Actor Only Non-Cube Collision

Post by Rachael »

Okay, nevermind then. Your's should be fine.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49182
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [ZScript] Actor Only Non-Cube Collision

Post by Graf Zahl »

A native function call with a sqrt inside is still a lot faster than 11 math operations in script code - not to mention this needs to be portal-aware which Distance2D takes care of.
User avatar
kodi
 
 
Posts: 1355
Joined: Mon May 06, 2013 8:02 am

Re: [ZScript] Actor Only Non-Cube Collision

Post by kodi »

Does this work when attempting to stand on an actor? Like a barrel for example.

Edit: Oh and a wild idea: if it happens to work with hitscan somehow, you could warp an invisible "spherical" actor with the player's head and measure the angles of invisible hitscan puffs aimed towards it relative to the center. That could perhaps allow cheap world->screen ray tracing until/if such functions are implemented natively.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: [ZScript] Actor Only Non-Cube Collision

Post by Major Cooke »

You can have it work with standing on something yes.

You can try a hitscan but that needlessly increases the complexity when you can just do a special distance check based on if it's a certain type of actor or not. Much cheaper to do that than spawning/destroying puffs.

Return to “Tutorials”