Page 1 of 1

[ZScript] Actor Only Non-Cube Collision

PostPosted: Thu Jul 27, 2017 11:28 am
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 allExpand view
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.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Thu Jul 27, 2017 11:34 am
by Rachael
One thing that *might* help speed it up (but requires testing/profiling) is to simply do something like:

Code: Select allExpand view
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.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Thu Jul 27, 2017 11:39 am
by Major Cooke
Graf optimized the hell out of the square roots. But I'll let him comment on which is faster.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Thu Jul 27, 2017 11:40 am
by Rachael
Okay, nevermind then. Your's should be fine.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Thu Jul 27, 2017 11:58 am
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.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Fri Sep 15, 2017 11:17 am
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.

Re: [ZScript] Actor Only Non-Cube Collision

PostPosted: Tue Sep 26, 2017 8:19 am
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.