#Avian Physics
1 messages · Page 30 of 1
With bitflags I really don't like that if component A requires ActiveCollisionHooks::FILTER_PAIRS, and component B requires ActiveCollisionHooks::MODIFY_CONTACTS, only one of them will be applied unless you manually add both
with separate components this is not an issue
what are they actually used for?
enabling collision hooks
for filtering broad phase pairs, and for modifying/filtering contacts computed by the narrow phase
and possibly more in the future
i tried reading rapier doc about it but i still don't get how it's different from collisionlayers
you cannot query the ECS or do any other custom logic with collision layers, nor can you use them to modify contact data
you can use contact modification hooks for one-way platforms, conveyor belts, non-uniform friction and restitution, etc.
broad phase pair filtering is a bit more limited, but you can use it for e.g. interaction groups beyond the limit of 32 layers for CollisionLayers, or for stuff like Box2D's collision groups (different from layers)
any custom logic before the collisions are handled by the solver
i took a look at PR and the reworked one-way example, and my conclusion is that you really shouldn't worry about how 1 line out of 800 looks nicer 😅
What is prediction_distance in contact_manifolds
didn't see that message, cheers for the info.
Yeh I meant how it's mean to be used/configured in Bevy as it didn't really click for me (new to rust) couldn't find an example
It's the maximum separation distance for a contact to be returned, so for example with a prediction distance of 2.0, you'd get a contact even if the shapes are separated by up to 2.0 units
this is necessary for speculative collision
yeah sorry it's clearer in contact
Wdym? Looking nicer isn't really the point for the collision hook stuff
arguably it even makes some things slightly more annoying (as opposed to using PostProcessCollisions)
i was commenting on [this](#1124043933886976171 message)
i'm saying that you already made 2 examples so you probably know which one is better, even if it doesn't look nice
Would it be a bad idea to have SpatialQuery expose its fields ? I currently have to put Position, Collider and Rotation queries in a ParamSet because SpatialQuery uses them, but doesn't expose them to the user.
Hey Bro, How do i see this world inspector?
bevy_inspector_egui
I have a really silly question
How can I make gravity of a collider relative to another collider?
I'm trying to use the 3d dynamic example and adapt the character controller to move around a sphere (planet) but gravity is -y... is setting gravity angle(?) supported?
Custom collider 2d example is what I'm looking for... but I'm not sure how to turn that into 3d
So I have a quick question. If I use cross-platform determinism does that mean I will have to sacrifice parallelism or have we found a way to make them work with it?
if it were me, I wouldn't mess with the gravity constant because each entity in your game would have a different "down" based on where they are. Instead you'd have to apply a down force that is relative to where they are
The only gravity I want is per collider vector pointing towards the center of mass of the planet… maybe I don’t want gravity at all because I don’t support jumping, just want vehicles to move across the surface of the planet
Should I disable gravity and do position manually?
Avian should be deterministic either way
There isn't that much parallelism yet (mainly narrow phase collision detection is multi-threaded) but there will be more in the future. I intend to keep determinism by default even with multi-threading though
Thank you! Will this work if say I added mountains and valley to my planet, i.e. not the simple perfect sphere I currently have?
Hello, I'm still interested if anyone knows of good 3d kinematic collision solutions (except the built-in one)
@vestal minnow I think there was some discussion on the potential of a world where big types could be assets instead of part of Collider ... What would that API look like?
Something like this?
enum Collider {
Sphere(Sphere),
Capsule(Capsule),
... // more small primitives
TriMesh(Handle<TriMesh>),
ConvecDecomp(Handle<ConvexDecomp>),
}
Trying to plan the improved SDF collider API, and I'm not sure if I should just have everything be a handle to an SDF tree, or make an enum that special-cases the optimized shapes
Makes sense to just pick whatever approach avian would go with given the same situation 🤔
hmm is this normal? if i load the rigid body and collider as components on a bundle it doenst show on PhysicsDebugPlugin

wydm
That said I don't think bundles should be breaking the debug plugin ... Maybe nested bundles are broken or one of your bundles is actually a Component instead of a Bundle 🤔
the sad thing is that i cant modify the default values from #[require]
how
yes
and have nothing aobut it
or iam blind lol
thanks guys
Probably something like that, yeah... The details of what the new Collider type would look like depend on what ends up being the most optimal in terms of runtime perf and memory usage though, so it's hard to say what exactly it'd look like before we actually have an implementation
Also I don't love the shape name repetition for the API, like Collider::Sphere(Sphere::new(0.5)), but we already have Collider::from(Sphere::new(0.5)) and even Sphere::new(0.5).collider() which is alright. I'm not entirely sure if we want to keep all of the current constructors like Collider::sphere(0.5) on Collider, or embrace the primitive shape APIs more, probably the latter
We also need to handle scaling, which is why the current representation has both the scaled and unscaled version, similar to bevy_rapier
pub struct Collider {
shape: SharedShape,
scaled_shape: SharedShape,
scale: Vector,
}
There's probably a smarter way to do this though. We should probably just store only the scaled version, even if that could technically be lossy when scaling at runtime, and have some optional component to entirely disable automatic scaling with transforms. People who need "lossless" scaling can always cache the unscaled version and manually handle scaling for the rare cases where that does matter
(an example of "lossy" scaling would be if you have an animation that scales the collider from a scale of zero to one, but the scale of zero erased all information about the size and proportions of the actual shape)
do you have any plans for how working with colliders will look like in the editor?
asking that because in unity i never even had to touch the API
Ideally similar to Unity or Godot, add a Collider component and have a dropdown where you can set the shape and its properties
If we have shapes like meshes as assets, you can load or drag and drop that for the shape (handle)
You just define the unscaled collider's shape in the editor, and the transform scale is applied to that
since the editor edits mostly BSN, that can just store the unscaled shape
then at startup (and in the viewport) it applies scale probably
I'm thinking that I might make Friction and Restitution only affect the collider they're on, not child colliders 🤔 I'm pretty sure they're currently our only components whose behavior propagates to child colliders (unless explicitly specified for those entities) which is a bit inconsistent
it's also kind of a pain internally to have the "collider -> body -> global default" priority chain for them
this is so ugly lol
// Get combined friction and restitution coefficients of the colliders
// or the bodies they are attached to. Fall back to the global defaults.
let friction = collider1
.friction
.or(body1.friction)
.copied()
.unwrap_or(default_friction.0)
.combine(
collider2
.friction
.or(body2.friction)
.copied()
.unwrap_or(default_friction.0),
);
let restitution = collider1
.restitution
.or(body1.restitution)
.copied()
.unwrap_or(default_restitution.0)
.combine(
collider2
.restitution
.or(body2.restitution)
.copied()
.unwrap_or(default_restitution.0),
);
oh right CollisionMargin is like this too
and SpeculativeMargin 🙃
mhhh I'll keep it the way it is for now, though it's making things more annoying for me rn
you could just make a constructor on parent
so users will only need to deal with 1 component that propagates to every child on spawn
wdym by constructor
I'd prefer if component propagation was first-party like here
https://github.com/bevyengine/bevy/pull/17575
Objective
add functionality to allow propagating components to children. requested originally for RenderLayers but can be useful more generally.
Solution
add HierarchyPropagatePlugin<C, F=(...
- i still think Mass should be renamed to something like IndependentMass to avoid confusion
- i can't understand how easy it would be to propagate to joints instead of children, otherwise the generic propagation seems almost perfect
- combining friction+restitution+density into one "material" makes the most sense to me,
unity and godot basically do this but without density - i still think that it'd make more sense to spawn a group of objects using only the final mass and create a material based on that, and i can't see if anything like it has already been done in mass rework
#3 especially makes sense when you account for gameplay where you can get frozen/petrified
not sure if propagation would work there, because you might want to freeze only 1 body part
For (3), no engine I know has density in the material type, physics materials more-so represent the surface properties than the physical material (like a wood material or whatever). Density is also not "a thing" from the POV of the physics engine, it's just an abstraction to configure mass conveniently
Combining friction and restitution could be fine, and I would do that if we make physics materials assets. But:
- It's not necessarily an ergonomics win.
commands.spawn((
PhysicsMaterial {
friction: 0.4,
friction_combine_rule: CoefficientCombine::Max,
restitution: 0.2,
..default()
},
// ...
));
vs.
commands.spawn((
Friction::new(0.4).with_combine_rule(CoefficientCombine::Max),
Restitution::new(0.2),
// ...
));
We could have constructors for PhysicsMaterial, but it'd still be a bit more verbose. Though with materials as assets, you could cleanly reuse the same material handle, which would be nice.
- You wouldn't be able to set e.g. a custom friction, while still using the globally configured default restitution, since the material component would override both. Not sure if this is really a big issue though.
not an ergonomics win when spawning new material, can be a win when spawning reusable or swapping it during gameplay
like if you swap to petrified and mass gets automatically recalculated based on volume, so the object becomes reasonably heavy
Finally opened the PR for per-manifold material properties and tangent velocity, which I used for the conveyor belt demo
https://github.com/Jondolf/avian/pull/660
split this out from the contact graph branch
After the contact graph + solver bodies, we can handle 13k+ active contacts at 60 fps in 2D on my machine
(6 substeps)
I should test how this compares to bevy_rapier without SIMD
thanks, i'm trying it out, though it is 0.14, so I have a lil upgrading to do
Avian vs. three steps of Rapier in this large pyramid test, tried to make configuration as comparable as possible
there's something wrong with my config though since Rapier is giving a lot of zeros even for stuff like contact counts
Hello, are there migration notes for 0.1 to 0.2 ?
I am specifically looking for what shape_cast's max_time_of_impact became.
It's just max_distance
thanks, that was my suspicion
Migration guide here
https://github.com/Jondolf/avian/releases/tag/v0.2.0
cool 🙂 ; I'd be curious to compare tracy runs on those, it's pure curiosity but I added some profiler annotations to rapier last year so that might give a few insights (I didn't dive much into performance investigation though)
Update: It took a while but I ported the whole thing to my game, and the kinematic collisions seem to work really well, I never clipped through the ground unlike before.
I would be curious as to what makes their implementation better, maybe it's the multi-step of the sliding or something idk.
Now I'm going to try and port the collision part back into my character controller, it's a mess
Mm I was confused about why Rapier's narrow phase is still so much faster, but I think I have an inkling why. It seems like most of our cost there might now actually be in the bit set management and allocations rather than the actual contact computation
I believe I should probably store a bit set for each worker and cache those rather than reallocating every time
(if only I knew how to do that
)
I should really get a lot more familiar with multi-threading beyond par_iter and par_splat_map lmao
way faster than current main branch, but inherently much slower than multi-threaded for collision detection
lemme try
scuffed screenshot setup lol
I think we should be able to optimize the single-threaded version of the narrow phase by a fair amount, it's currently kinda using the "parallel approach but single-threaded"
could probably have a single-threaded path that doesn't use the bit set stuff at all
@vestal minnow I just noticed that on the github light theme, the avian logo looks a bit weird and pixelated along the edges. just thought I'd let you know.
#[require(Predicted, RigidBody(|| RigidBody::Dynamic), Collider(|| Collider::from(Sphere::default())))]
The avian API sure is clunky to use with required components ... Tho I guess it's nice that Collider at least doesn't require any Assets currently 😂
Does anyone have thoughts for BigSpace integration? If you tried it, what were the challenges?
I feel like that's a browser thing, it's an SVG with a drop shadow so it shouldn't be pixelated
I'm on my phone rn but it's not that pixelated for me
Huh, maybe a safari quirk
Rigid bodies should get nicer if/when we have unit structs for the different types of bodies... Having a specific collider shape as a required component feels like a relatively niche case though
can also use a function instead of a closure if the same requirement is used for different components
jondolf the goat
Yea the function approach seems reasonable for the collider but the rigid body thing is just kinda ugly 😂
For a single floating origin it shouldn't be too bad, mainly I think you need a custom version of Avian's SyncPlugin which synchronizes Bevy's transforms with the Position and Rotation components used by physics. Someone made a branch that has this a long time ago.
For proper support, including multiple floating origins, we need the ability to run several instances of the simulation separately. This isn't currently easy to do properly, but I have a prototype for multiple physics worlds using bushrat's indexed query PR for Bevy. I haven't worked on it more yet though since that PR is currently kinda stalled
Once we do have support for disjoint simulation instances one way or another, we would probably use big_space's spatial hashing to group physics entities into those instances
I wish we could just do RigidBody::Dynamic instead of RigidBody(|| RigidBody::Dynamic), the wrapper and closure bring no value there
Maybe a silly question but won’t this accumulate endlessly?
isn't that closure unnecessary? RigidBody::default() is dynamic
I have a followup silly question… what if I always want my dynamic colliders to be grounded? Am I doing this wrong by doing it in a single system? Say I have a system for vehicle movement, I assume I need to apply the gravity acceleration to the vector of the requested movement. Sorry for these really silly questions, are the some resources you can point me to that would help me understand this better and be better able to reason about this?
I never want my vehicle colliders to not be in contact with the planet collider. All colliders should always be grounded… is that misguided?
Can you point me to some resources about this so I can educate myself on the domain a bit?
If you know of any that is
Just feel a bit lost and unable to reason about what I need to do
I want to have a capsule move along the surface of a planet which for now is just a sphere
Jumping or not either way is fine
my initial impression is 'use ExternalForce with persistent:false, and the entity_commands.entry().or_insert().and_modify() pattern'
Conceptually I’m having trouble figuring out what to do to accomplish that
I started with just trying to get a capsule spawned 50 units away from the surface to land on the surface
Oh really? What part of the camera causes problems?
I got it to land on the surface but once it lands it slides along the surface from the landing point to a fixed point
Increasing the friction on the capsule collider and the planet collider causes the capsule to wiggle around in the spot it landed
I think that code just took the normal times 100.0 from the translation of the position component and set that equal the the entity’s LinearVelocity component’s inner vector
Which is a feedback loop so never reaches a steady state
Sorry I’ll the actual code when I get home in a few hours
Awesome, will do, thanks for your help!
Apparently 0.5 ms out of the total 0.85 ms for the narrow phase here just comes from par_iter overhead 🤔 why is it so much faster for Rapier though
both are using rayon currently
is rapier running https://docs.rs/rayon/latest/rayon/struct.ThreadPoolBuilder.html#method.build_global in advance?
Used to create a new ThreadPool or to configure the global rayon thread pool.
I don't think it would matter since it only needs to be initialized once
Does avian have body position force? Like i can set a position to It move and Lock on this position, Very good to fly cause i can Lock the Y position only, while x and z can be moved
@vestal minnow In your kinematic character controller example, wouldn't it be way more efficient if you would use CollidingEntities for the Collider of the character instead of iterating all Collisions in function kinematic_controller_collisions in https://github.com/Jondolf/avian/blob/main/crates/avian3d/examples/kinematic_character_3d/plugin.rs ?
It would, yeah
Ok, just wanted to make sure that I correctly understood how Collisions and CollidingEntities work
You still need to get the contact data from Collisions but you can at least avoid iterating over all collisions
ah yes, good point
the KCC in that example is not great though, I would generally recommend more of a collide-and-slide approach using shape casts instead of raw contact data
In my hedgehog game, I implemented a hover functionality, to prevent colliding and flickering all the time, but still use the collision resolver from your example as "fallback", because I have to handle high jumps and such.
Ah one could use https://docs.rs/avian3d/latest/avian3d/collision/struct.Collisions.html#method.get with the entity (owner of CollidingEntities), and the entity inside the ColldingEntities
A resource that stores all collision pairs.
yep
There's also Collisions::collisions_with_entity which avoids having to use CollidingEntities, but that's horribly unoptimized right now since it just iterates through all collisions. It will be much better with the upcoming contact graph stuff though
Ok, so CollidingEntities, for now, is the most efficient way to find collisions of exactly one entity of interest
Yeah it should be the fastest currently
Nice! I recognized a performance boost already, because I have a lot of collisions and handling scenarios. 1. I have a wind plugin that applies external forces and torques to falling leafs to appear more natural, but disable the wind affection after colliding with the ground. 2. I use a sensor to detect nearby food on the ground to enable interaction. 3. Another sensor to detect the environment to calculate stealth of the hedgehog (if nearby to grass, it's stealthier than on plane ground). And 4. the character collisions. There are a few more cases, but currently, in every case I iterated all collisions
Outside of shapecasts I haven't done much with avian yet, so maybe this is more obvious for someone
if I add a RigidBody::Kinematic to an entity, I should be able to query for these below, and get that entity right? And then it's just a matter of manipulating these to move it?
&mut LinearVelocity,
&mut AngularVelocity,
@vestal minnow Is there a easy way to find the matching/related rigid body entity for an entity with a collider (because colliders can be inserted to children entities). For me, it often feels bloated to traverse the parents to find the matching rigid body entity. There is a new upcoming feature called Relations. Maybe we could use something like this to easily lookup a rigid body? Don't know how it would work if there are multiple collider chidren. What do you think?
edit: oh, there is a ColliderParent. sorry! 😄
Yup
Ok another question, I see Kinematic doesn't deal with collisions.
How would I implement a simple collide and slide system? Dont care about grounded state or jumping, or anything like that.
I guess I could just use a Dynamic and use external forces
trying to do this without shapecasts like I have in the past
I thought kinematic meant, conceptually, that the object is deliberately excluded from the automated physics interactions, to be used for scripted movement / cutscenes.
There is a simple example in avian3d repo
thanks I missed it
Just need to change bundle by require in case you're using bevy .15
I'm writing a networking library that has the ability to modify avian transforms and sync them between clients. What is the things I should be aware of the, the caviates, about modifying Position, Rotation, LinearVelocity, AngularVelocity ( i assume these are the components i should be modifying perhaps I am incorrect ).
Should I do these modifications in FixedUpdate or in Update? Are there other scheduling concerns or other things i should be aware of?
Is there some way I should be taking advantage of interpolation or something in order to tell the objects to move towards a location instead of just teleporting them there?
FixedUpdate or a custom schedule with const frequency I suppose since you don't want it to dependant of frame rate.
But syncing between users mean you'll need a PreFixedUpdate to compute (t-1) Transform of other clients before computing (t) physics, or to chain them in this order
And you should use velocities instead of changing transform directly to avoid teleporting
Honestly heavily dependent on your specific networking requirements ... You usually just want to apply networking updates before FixedMain, replicon for example just applies network updates in PreUpdate ... But if you don't want obvious networking artifacts, you'll need some good prediction stuff set up, and that's where all the things to worry about come in
So I've been optimizing the narrow phase a bit further. The test scene is a 2D pyramid with a base of 60 rectangles, about 4750 contact pairs in total.
By default, rayon's par_iter_mut is often faster on my machine than Bevy's par_chunk_map_mut, however this seems to be because rayon's task pool here has 24 threads (not necessarily all used) while Bevy's ComputeTaskPool has "only" 16 threads.
If I constrain rayon to 16 threads so that it's the same as Bevy, I get:
- rayon: 0.56-0.58 ms
ComputeTaskPool: 0.38-0.40 ms
So using Bevy's task pool seems faster in this case when constrained to the same number of threads. Maybe when using rayon it's fighting with Bevy's own task pool in some way, or maybe it's not using high performance cores, idk.
Interestingly, in this scene, Rapier's narrow phase is taking 0.57 ms when also constrained to 16 threads, so we're actually about 33% faster. With a larger pyramid it's closer though, and I suspect that Rapier still wins at larger scales at the moment
modifying Position will always be "teleport"? I'm trying to use bevy_tween to directly modify Position but it won't "trigger" the physics until it stopped interpolating
Getting started
if that's the case, i will try to somehow use LinearVelocity instead
now that i think about it
impl Interpolator for MovePos {
type Item = Position;
fn interpolate(&self, item: &mut Self::Item, t: f32) {
item.0 = self.start.lerp(self.end, t);
}
}
because it's just directly set the position every interpolation step, it will just keep teleporting until t = 1, even if the physics engine doing something between t = 0 -> t = 1.
so, i need a way to check if next position is "valid" then set the position. But that won't go well if, for example, t: 0.1 valid, t: 0.2 not valid, t: 1 valid. It will teleport with a huge step.
now i need a way to have a state for "this should not interpolate anymore"
i feel like i should interpolate LinearVelocity instead for physics object
Yea it will always teleport, what you really want to do here is calculate the difference to the next position you should be at, then set LinearVelocity so its there after running physics once
How did you optimize the narrow phase? Is this defualt collider specific or general improvements like when the data structure for manifolds got less nested Vecs? 🤔
Also speaking of data structures, I've noticed that Collisions is incredibly slow to clone, but it's needed for warm starting ... I wonder if this is another case of nested Vecs
or instead of lerping you could do a damped spring approach backed by avian external forces to move to a target position, depending on what exactly you want to get out of a tween. The spring approach can also have some nice emergent motion if the target position changes dynamically
you can kind of see the result in this video, though if you let avian do the integration you can skip the second half https://www.youtube.com/watch?v=KPoeNZZ6H4s
It's been a while since the last video hasn't it? I've made quite a bit of progress since the last update, and since one of the things I worked on was some procedurally animated characters, I decided to make a video about the subject. In particular, this video highlights the entire process from initial motivation, to the technical design, techni...
General improvements, a lot of them. I'll have details and results in the PR description once I make that, but:
- Use a contact graph instead of the current
IndexMap. This is needed for iterating over all contact pairs associated with a specific entity, which was previously insanely slow and seriously bottle necked some systems. Also needed for simulation islands once we implement them. - A contact pair now always exists if two AABBs intersect, even if the shapes themselves are not touching. The broad phase creates new pairs in the contact graph directly rather than collecting all pairs to a vec every time.
- All pairs are updated by the narrow phase in parallel, without any extra allocations. Previously the narrow phase basically reinserted all touching contacts and allocated a ton of vecs instead of mutating persisted data directly.
contact_manifoldsnow mutates the given vec of manifolds in-place rather than allocating a new vec every time. However, we still need some allocations and annoying conversions there because Parry uses its own contact manifold type that we can't reuse :(- Contact status changes (collision started or ended) are collected into thread-local bit vectors during parallel iteration, and combined into a global bit vector. The narrow phase then quickly iterates through set bits using bit scanning intrinsics, and sends collision events and removes contact pairs whose AABBs no longer intersect. This is done serially for determinism.
- Collision events are opt-in with a
CollisionEventsEnabledcomponent. The overhead of collision events is also way smaller since it doesn't require its own separate scan over collision pairs. - A lot of things are simpler: we can
BroadCollisionsPairs,AabbIntersections,wake_on_collision_ended, all of the awkwardduring_current_frame/during_previous_frameshenanigans... - Probably more, there's so many changes and improvements that I forget
In short:
- Contact pairs are persisted way better. Much fewer allocations and unnecessary work.
- Pair creation and removal is fast and handled more incrementally rather than creating and yeeting everything all the time.
- Updating contact data is way faster, using in-place mutation.
- Collision event overhead is way smaller.
- Hacky ugly stuff around contact pair management begone!
Nice ... Those changes are a lot more broad than what I imagined when hearing "the narrow phase" ... How big is the actual difference? 🤔
Not that huge, but the difference is larger the more contacts there are, and we're so solver-bound that it's currently hard to measure properly :P here's a rough profile of a relatively collision-heavy scene though, left is main and right is the improved one
Worth noting that collision events are included in the narrow phase timings now, so it's a bit misleading
Also the main branch's version didn't include contact removal in the narrow phase section
I don't think we're necessarily solver bound tho ... What if there are a lot of things the broad phase fails to filter?
The broad phase has been only like 10% or less of the solver's time in most of my tests, and that's if the entities are pretty densely packed in a way that makes sorting for sweep and prune more expensive
but my test scenes aren't representative of actual projects so idk
The one case where optimizing the narrow phase makes a big difference are when the AABBs overlap but the colliders never touch ... That can be incredibly rare, for example if you largely deal with barely rotated cubes, or things with relatively tight AABBs like spheres ... But then there's like trimeshes or convex decomp
Or those arc colliders in my game 😂
That will get you potentially thousands of things going trough the broad phase, when realistically only a few contacts exist
For cases like that I don't think there's really a way to avoid potentially unnecessary contact computations, beyond splitting the large shapes up into smaller shapes with their own bounding volumes
since Parry's trimeshes store BVHs for the triangles, technically we could try having some mid-phase that further filters intersections with meshes before creating contact pairs for the narrow phase
If the narrow phase is fast enough and the solver doesn't waste time on things that aren't even touching that shouldn't be a problem no? 🤔
yup
not actually relevant for my projects, but is there a good way to put a hole in a collider? eg, half-space with a hemispherical pit
Could be pretty useful to make defense field in game
maybe in @cinder summit's sdf colliders
@sleek thicket btw increasing the size of my colliders by 10,000x made the jitter go away completely
My previous colliders were a 100.0 radius sphere and a 0.3 radius 1.0 heigh capsule
that's a really strange fix
I wanted a realistically sized planet anyway so the fact that this appears to fix it works to my benefit
Hopefully it actually fixes it not just seems to
Actually not so much tiny colliders are known to be harder to detect
Issues like tunneling and precision limitation may arise
not really, in general you're just more likely to get precision and stability issues with very large or very small objects
Tunneling would be a problem if you had for example some small object moving towards a thin wall very fast, but scaling the whole scene up doesn't inherently fix anything assuming you also scale the velocities. But yeah stuff like just making the wall thicker would help a bit
CCD also "fixes" tunneling so it shouldn't be too big of a concern in general
Hello, I can't seem to get kinematics collision working great with my usecase (I have complex procedurally generated colliders from a mesh) as my characters keep falling through the map.
I tried the kinematic character example, but it would fall through very often.
I also tried this one: https://github.com/UndefinedBHVR/vidar, which worked better but still falls through quite often.
I am considering going with a rigidbody based controller as I imagine it would have more robust collision stuff with CCD.
Is that a good call ?
yup, you can just switch to kinematic once you actually need it
I can't really switch back if I make my whole character controller around a rigidbody though. It's a commitment
it's not, but the other way around is
and I don't understand the "once you actually need it"
most games don't need the extra control from using kinematic rb
that is a pretty hot take I believe, the industry disagrees afaik
what exactly are you doing that needs it
I think my project can work without, though only time will tell.
Can someone help me figure out what's wrong with the physics here? An impulse is being applied to the blue ball in the direction the green line is pointing. When it rolls along the surface and over the edge it bounces in to the air. The corner it's rolling across is clean, there's just one vertex there. The collider it's rolling on is a polyline but I see the same behavior with trimesh colliders. I thought it might have something to do with restitution but I see the same behavior when restitution is turned down to 0 on both bodies.
looks like a ghost collision
Like a problem with the speculative collision detection?
it's just a classic problem with collision detection but idk, it might be involved too
Hmm, yeah, setting SpeculativeMargin(0.0) and SweptCcd::default() seems to resolve it in some quick tests. I thought I'd tried that but I guess not.
Yeah, if that didn't completely fix it it made it almost unnoticeable. Hard to say if it's completely gone. Thanks!
i haven't try it yet but that's simple and very useful
but now im interested in this because I've watched the video a while ago and didn't understand it really well, but just now i rewatch it and i might be able to use this now
it's so fun doing anything other than finishing the game itself
what makes a rigidbody entity implicitly have Position and Rotation?
you can also just google "damped spring" and you will find results that have the same concept written specifically in terms of forces or acceleration (which is good for avian)
though in most cases, the "anticipation" motion from that video is not part of a "damped spring"
but basically it's just:
force = spring_strength * (target_position - current_position)
- damping_strength * velocity
but you can use the equations from the video to control this in terms of zeta and f, which is more intuitive to control. Though you will need to incorporate the rigid body mass as well, except if you are able to set it's mass to exactly 1.
my guess is that they are required components for RigidBody
though I can't find them here: https://docs.rs/avian3d/latest/avian3d/dynamics/rigid_body/enum.RigidBody.html#impl-Component-for-RigidBody
maybe they are pulled in by one of it's requirements?
Curious, if there are multiplee collision at the same, is there a chance that the Collisions event might die before I can consume it? If so, how can one ensure he never skips a collision
.
So I know how I would make a rocket league arena with SDF colliders, but what would be the most sensible approach with the default collider? 🤔
the easiest would probably just be a trimesh
with fixed internal edges
convex decomp could maybe work too, but I'm not sure if it'd produce perfectly consistent or smooth enough results in comparison to a hand-authored thing
Yea especially since the arena would be big ... Maybe if I flipped some meshes a couple of times, but at that point just doing rectangles might be easier 😂
This took me way too long to figure out but I wanted to share here in case it was useful for someone else because I couldn't find very many complete 2D top-down examples. I made an Avian 2D top-down kinematic character controller that doesn't get stuck on corners. Feel free to suggest any changes if you find a bug https://gist.github.com/komodo472/527de60a3d2ee07c4d5ca18c3d14087c
It's based on these two papers
Bevy Avian 2D Top-Down Kinematic Character Controller - client.rs
Hey nice, I use the same looping technique, taken from Quake 1, works in 3D too (I loop 4 times)
Hey so I have a weird issue where colliders are not following the entity.
Note that I am using lightyear, and I have a feeling it's probably related to how it handles interpolation. Not sure what to do, I'm thinking maybe its needing to manually set the Position or something.
i will try to implement this later, it's so interesting but i don't need it right now. Thanks for the help!
i really don't know because one of my object somehow has them without me inserting it, but not for the other
I'm trying to write a very basic breakout game and my setup is very simple, but I'm running into issues that I think should be trivial and could use help with. 1) The ball doesn't reflect off the objects at the expected angles. 2) The ball starts speeding up (or slowing down?) and I can't tell why. The paddle is a kinematic body, the ball is a dynamic body, and the walls are static bodies. Restitution for everything is 1.0. Can provide code if needed, but I have a clip
did you lock rotation?
and those walls might be causing ghost collisions, try making them out of just 4 colliders
kk will give it a shot
update: making them 4 large colliders solved both the acceleration and the angle problems. thanks!
I think I found a bug. I have an entity with multiple colliders as children - one "real" collider, and some sensors. As soon as my real collider collides with another collider (which also isn't a sensor), the is_sensor field in Contact is true (https://docs.rs/avian3d/latest/avian3d/collision/struct.Contacts.html#structfield.is_sensor) which isn't correct.
I also validated it with a Query<Has<Sensor>> for both - entity1and entity2 fields in the Contact. The query also returns false for both entities. I can't imagine that this behavior is intentional?
I use the latest release version 0.2.1.
All contacts between two colliders.
just in case - I opened an issue. If it`s intentional, for whatever reason, we can close it: https://github.com/Jondolf/avian/issues/664
using avian2d. how could i generate a collision mesh and then use it as a static body's collider?
in my particular case, i'm just gonna be generating triangles.
I think this is probably the easiest way if you mean a triangle mesh: https://docs.rs/avian2d/latest/avian2d/collision/collider/enum.ColliderConstructor.html#variant.Trimesh
A component that will automatically generate a Collider at runtime using Collider::try_from_constructor. Enabling the collider-from-mesh feature activates support for computing the shape dynamically from the mesh attached to the same entity.
There's another variant for just single triangles too.
thanks!
does avian have this problem?
the red circles are misaligned lol but i think its a problem people making tile-based games in modern engines will be familiar with
im working on a solution / meshing algorithm. finds edges (and their normals), and creates triangles from them. then maybe i could do something where the corners are filled in (only half-way to the inset points, due to an edge case that is hard to explain via text) to prevent weird corner behaviour.
yep, it also has problems with corners if you're not using cuboid
This is rather inspired!
inspired?
Making inward-pointing triangles to have a single face per edge. I think the idea is neat.
oh, thanks!
does it matter whether or not my points are defined in a CW/CCW order? i couldnt find any mention of this on the page.
im going to assume avian corrects for non-CCW triangles internally? since creating a collider from a single triangle does so.
Not sure. I've never thought about it and haven't had a problem, so either it doesn't matter or I've gotten lucky.
only for Collider::triangle
and only in 2D
I'm not sure if this would fix ghost collisions at the corners, the edge of the triangle still exists so you might be able to bump into it
The way to properly fix ghost collisions is to have a shape that uses adjacency information to detect and prevent hits against internal edges. Trimeshes support this with TrimeshFlags::FIX_INTERNAL_EDGES enabled, and it should also be possible to support it for polylines, but I'm not sure if Parry does. Box2D has a chain shape for this
Also see Erin Catto's article on ghost collisions
https://box2d.org/posts/2020/06/ghost-collisions/
Dealing with ghost collisions is a challenging problem in game physics. The basic idea comes from motion across a flat surface. You may have several shapes joined together to make a flat surface, like a triangle mesh in 3D or a chain of edges in 2D. Convex shapes can hit the internal connections and have their motion blocked. This is undesirable...
oh, thanks!
I have a very large object, moving very fast - and it seems to be "jittery". I thought it was the bevy_panorbit_camera not keeping up, but after looking more, it seems that other static objects (like the small trees) are smooth. I'm reeeasonably sure I'm not manually updating the stone anywhere else - any suggestions on what I might check? Thanks!
what's your physics tickrate?
I went to reply "just using whatever is in PhysicsPlugins::default()", which lead me to actual read the docs. Upping the substeps to around 20 fixed the issue I was seeing. Not sure that's the best way - but I'll now read the rest of the docs and make sure I'm not doing anything else stupid. Thanks!
[Edit, well - fixed it with debug on, but still jittery without it... but I'll try more settings and hopefully sort it out]
[Final edit! Reading the docs really pays off... who would have thought? Adding the TransformInterpolation component to my stone as recommended in the very clearly-titled "Why does movement look choppy?" question in the FAQs - makes everything buttery smooth]
Are collisions reported twice?
If A intersects with B do I get both an (A,B) event and a (B,A) event?
no
Interesting
Which one is the first then?
either one.
Meaning that if I have two different queries I need to check twice each time?
What do you mean? Can you send a code example?
#1124043933886976171 message
one system sorts all collisions, and the subsequent systems know exact order and type
I see
there's also no issues with race conditions unlike the usual approach
But that means that they're all in the same place
If I wanted them to be more independent I'd have to send another collision-sorted event which would flood the system
How much should we expect TrimeshFlags::FIX_INTERNAL_EDGES to help with ghost collisions? I'm still seeing them with that set unless it turn on SweptCcd and fine tune SpeculativeMargin, which is what I was doing before to deal with the problem.
I think I'd just check in each query
It should fix ghost collisions against the mesh that has it set, but it of course doesn't help at edges where two different colliders meet. For example, if you had chunks of terrain represented as individual trimeshes, you could still get ghost collisions at the edges of those chunks
Hmm... I don't think that is what I saw happen. Let me experiment a little more, maybe I'm doing something wrong. These meshes shouldn't be chunked up like that.
if you tag everything instead of assuming it's environment then you could just continue, and it shouldn't flood the systems any more than each independent system doing it
@vestal minnow did anything come out of the hooks/observers that would work similar to unity/godot?
Yes, it seems to still be happening. The terrain mesh here is built with FIX_INTERNAL_EDGES on and the blue ball has the default SpeculativeMargin and SweptCcd off. An impulse is being applied in the direction the green line points and you can see that the ball rolls to the edge and then hops into the air, which I've been blaming on ghost collisions but maybe there's actually some other problem.
Sorry, that first example is my old test. Showing the same problem without FIX_INTERNAL_EDGES. The second video is the one with FIX_INTERNAL_EDGES on. The behavior is the same, or maybe slightly better in the second one but the problem is still there.
Hmm so this is 2D, I'm not sure if Parry handles internal edges properly there
Yes, 2d. Sorry, should have specified that.
I know in 3D Parry uses "normal cones" to fix contact normals using adjacent triangle geometry, but it might not do that in 2D currently
Ok. I'm actually fine using SweptCcd and the tuned SpeculativeMargin, that fixed the issue for me. I just got excited when I saw you mention FIX_INTERNAL_EDGES.
Nope not yet, but it'd be OnCollisionStarted and OnCollisionEnded events implemented using either observers or a custom API using one-shot systems.
The problem with observers is that we'd ideally only trigger the event for entities that are actually being targeted by an observer, but with current Bevy that info is not easily accessible. People might also have assumptions about global observers behaving a certain way, like getting all collision events by default, but that wouldn't necessarily be the case here
We could also just trigger the collision events for everything by default, but that could be thousands of events per frame in heavier cases, times two (one event for each entity in the collision)
A custom API more similar to bevy_eventlistener would make the API more obvious and provide a clear marker of "send collision events for this entity please" since the component lives on the entity directly, but that may also diverge a bit from what many people expect, since observers are the usual first-party thing for targeted entity events
i don't unity/godot's approach because of what happens after that,
you'll still need to look up what the other object is twice, when it could just be sorted out ahead of time
i just need to figure out a better way of doing it
In theory we could make an API where e.g. collisions.get(entity) returns the collision such that the given entity is the first entity in the collision data, but that would mean iterating through all of the manifolds and contact points and swapping everything
*in the case that it's not already the first entity
This would simplify a lot of my code.
For entity events using observers / one-shot-systems / whatever, you'd always know which entity is "self" and which entity is "other", but those events only store the entity, you still need to query the Collisions resource to get actual collision data
Related: Having body_entity on OnCollisionStarted would also be very useful. I don't have a sense for how expensive that is, maybe it's prohibitive.
@viral goblet i just realized you could just hold multiple Option<tag>s inside that component
just skip matching when tags shouldn't interact
you can split the individual sorting systems into events with just 1 tag too
The body entity is available in the place where the event is sent, so it shouldn't be too expensive in that sense, just uses slightly more memory
but two extra u64 values per event probably isn't a concern memory-wise :P
I don't know how common this pattern is in general but in the projects where I use these events I am almost always doing the lookup in the recieving system, which is certainly more expensive. Because I tend to have multiple colliders per body.
Yeah, makes sense
Sometimes I can use Collisions instead, and I do. But the events are nice.
I like how the current tuple struct looks API-wise when destructuring in stuff like loops
for CollisionStarted(entity1, entity2) in event_reader.read() {
// ...
}
but I guess this pattern wouldn't be too much worse if it was a normal struct with fields either, assuming you're using the field names directly
for CollisionStarted { entity1, entity2, .. } in event_reader.read() {
// ...
}
Yeah, I agree the tuple is very clean but the second version also looks fine.
it won't look fine if you change the name though
Yeah. But entity1:my_entity1 isn't terrible.
And the mass of code required to look up the RigidBody from the collider entity is way worse.
for a fair comparison:
for CollisionStarted(E1, E2) in event_reader.read() {
// ...
}
for CollisionStarted { entity1: E1, entity2: E2, .. } in event_reader.read() {
// ...
}
i think tuple wins 😄
If that's all you're doing I agree. But if you need the body, which I always do, you have a whole lot of other ugliness to deal with which an extra field would solve.
And that ugliness involves both the system definition, because you probably need an extra Query, as well as the code that processes the event.
Also the performance cost of doing the query lookup.
you just need 2 bodies, right? in that case wouldn't it just be...
for CollisionStarted(E1, E2, _, _) in event_reader.read() {
// ...
}
for CollisionStarted { entity1: E1, entity2: E2, .. } in event_reader.read() {
// ...
}
if you're not using them, and
for CollisionStarted(E1, E2, RB1, RB2) in event_reader.read() {
// ...
}
for CollisionStarted { entity1: E1, entity2: E2, rigidbody1: RB1, rigidbody2: RB2 } in event_reader.read() {
// ...
}
if you are?
not exactly the clearest type definition
pub struct CollisionStarted(pub Entity, pub Entity, pub Entity, pub Entity);
i guess i'm fine with both because i have it all in 1 system
you can also just... not use destructuring there if it ends up ugly, you can just call it ev if you want short names and do ev.entity1 or whatever
Might was well just [Entity; 4] at that point 
for CollisionStarted([E1, E2, RB1, RB2]) in event_reader.read() {
// ...
}

sometimes you can't make both sides equally happy, but you can always make them equally unhappy
for CollisionStarted((E1, RB1), (E2, RB2)) in event_reader.read() {
// ...
}
No see, this is fine:
for CollisionStarted(es) in event_reader.read() {
for e in es {
if collider_query.contains(e) {
// process colliders
} else if body_query.contains(e) {
// process bodies
} else { panic!() }
}
}

I actually don't hate this one. I like the named fields better but I could live with this.
why not (e, e, rb, rb)?
i think it's better when you don't care about either collider or body
(_, _, rb1, rb2) or (e1, e2, _, _)
That is a good question. The structure of the nested tuples makes the relationship between the pairs less opaque to me. To be clear, I still think it's a bad design but I think it's less unclear.
Yeah, I agree that this looks better.
vs ((_, rb1), (_, rb2)) or ((e1, _), (e2, _))
every variant is better than how unity did it though
how does Unity handle it?
collision gets rb by default, and you use .collider to get actual collider
void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.collider.name);
}
Oh god it has both body and rigidbody and they belong to different game objects
How do I prevent colliders from sticking together? I have a trimesh generated from a bevy_voxel_world chunk and a bevy_tnua capsule collider for the player.. I tried a CollisionMargin of 0.15 but it still gets stuck
sticking when idle or moving? might just be friction or something on tnua's side
What I ended up doing (after thinking about it for the entire day) is exctracting this logic into a macro, so it's use looks something like:
physical_bodies,
unchangeable_velocity_bodies,
*first_entity,
*second_entity
);
match maybe_bodies {
Some((
(LinearVelocity(velocity), Mass(mass), physical_transform, physical_entity),
(unchangeable_velocity, unchangeable_transform),
)) => {
...
}
_ => {}
}
Oh that means I can actually use if let
Look how clean this other function is now:
let maybe_damage_taker_and_causer =
get_from_both_queries!(damage_takers, damage_causers, *first, *second);
if let Some(((damage_taker, damage_taker_entity), damage_causer)) =
maybe_damage_taker_and_causer
{
if damage_taker.is_damageable_by(damage_causer) {
damage_requester.send(DamageCauseRequest {
to: damage_taker_entity,
damage: damage_causer.damage,
});
}
}
}```
(Let me know if I should share the macro here so other people may use it)
Setting friction to 0 helped, thanks
Maayyybe someone is interested in my question - not sure: https://discord.com/channels/691052431525675048/1346538529160691743
It isn't 100% related to physics.
Please don't blame me if it's not 😶
you'll probably need to revert if you run into same problem as me 😄
i needed projectiles that are damageable, but can have special interactions with each other
when it was separate, it'd trigger both the projectile_hit_damageable and projectile_hit_projectile, but i only needed the latter
so i had to query both for everything they might be, and sorting that out ended up just being a more complicated version of tag matching
[tag system](#1124043933886976171 message) would help in your case too, you'll most likely need to sort collisions later anyway, and that's where you can add environment tag with the type of environment
I have realized yes, I need to, so, I was simply syncing positions and linear velocities, but this does not work with high latency because the positions are backwards in time by the time they get to another player
I need to extrapolate out using position += velocity * delta time
Where delta time is timestamp when packet was sent - current time
This also produces weird artifacts, which is why games either accept the fact that other people's positions are in the past (and potentially use lag compensation to make sure gameplay isn't affected by it heavily), or do fully simulate what those clients would've done using rollback, like fighters or in a non-1v1 setting rocket league
try ["serialize", "f32"]
if it's this and saved then it's strange, otherwise normal
not working
and why are you showing the compile error tab when it's written in terminal anyway
what
xd
is my rigit body ir collider wrong ? cause when i try apply linear velocity he just go down lol
simple test btw linear_velocity.z += 20.0 * delta_time;
all i do is put RigidBody::Dynamic and Collider::capsule(0.3,1.0)
I have a problem.. i change LinearVelocity and AngularVelocity but it doesn't move at all. do i need to tell avian that i've changed it or something? i print it to console and numbers move and move from frame to frame
you'd fall down too if someone pushed you
?
unless you were on ice
but iam pushing?
iam just trying move it
like normal walk
i shouldnt use linear velocity so?
if you remove friction he'll slide, if that's what you want
if you lock rotation he just won't fall
character controllers are a pain and there are too many ways to deal with it
"if you remove friction he'll slide, if that's what you want" na i just want he normaly walk
okie so i need lock rotation?
it's one of the easy ways to do it if you never need to change the rotation, you can just disconnect the animations from collider
"you can just disconnect the animations from collider"?
wydm
the player walking animation?
cause the model is a child of the entity that have the collider
DOH.. FFS
then you're already halfway there
@past cargo there's also this approach
https://youtu.be/qdskE8PJy6Q?si=uy9kl57aaER_wtoX
https://www.youtube.com/watch?v=CdPYlj5uZeI
what is ffs?
for fuck's sake lol
that was the problem?
more because i did a state machine xd
now i just legit just need move it ahaha
@vestal minnow I tried making an up-to-date version of the collider context thing, added the convenience wrappers for non-context colliders, and made the param order a bit more sensible ... Was there anything else we wanted to try there?
https://github.com/NiseVoid/avian/commit/379468d384f2e5da97dd1e6dc3c4e12e0a71b9ee
Would we also want an example or test for this? 🤔
When I add a RevoluteJoint (or any joint, I think) as a component on one of the bodies it joins it seems not to work. If I spawn the exact same RevoluteJoint as it's own entity it does work. Is that Expected or a bug? It seems like it would be tidy to keep the joints close to the entities they apply to.
Hmm. If I spawn the joint as a child of the entity it effects, that also works. So maybe it's just that the joint component interferes with other components on the body? I guess having it as a child addresses my tidiness concern.
how does Shapecast works?
it casts shape 👍
BRO
IAM talking about the method
like have cast_shape_predicate
and cast_shape
what is the difference?
predicate: A function called on each entity hit by the shape. The shape keeps travelling until the predicate returns false
not for the spatial query afaik, you can just make a ray gizmo for that
ray/shapecaster should have it but i don't remember if it's enabled by default
i mean, iam trying fire a ray down the character to align it with the floor
let transform_translation = transform.translation;
let shape_hit_data = query.cast_shape_predicate(collider, transform_translation, Quat::from_rotation_y(0.0),Dir3::Z,&ShapeCastConfig{
max_distance: 20.0,
target_distance: 0.0,
compute_contact_on_penetration: true,
ignore_origin_penetration: true,
},&SpatialQueryFilter::default(),&|entity_found| {
if entity_found == entity {
return false
}
true
});
if let Some(shape_hit_data) = shape_hit_data {
controller.floor = Some(shape_hit_data.entity);
controller.floor_normal = Some(shape_hit_data.normal2)
}else {
controller.floor = None;
controller.floor_normal = None;
}
wich seens wrong
Z is down in your coords? 
iam bit confussed rn, its getting the floor yes, than iam trying alig the charactr with the floor, but
pub fn rotate_to_ground(
mut character_query: Query<(Entity, &mut Transform, &CharacterController), (With<CharacterController>)>,
time: Res<Time>,
){
for (_,mut transform,controller) in character_query.iter_mut(){
if controller.floor == None{return;}
let target_rotation = Quat::from_rotation_arc(Vec3::Y, controller.floor_normal.unwrap());
let smoothing_factor = 5.0 * time.delta_secs_f64().adjust_precision();;
transform.rotation = transform.rotation.slerp(target_rotation, smoothing_factor);
}
}

iam trying alwasy cast down the player
even if he is rotated
ok, but you're casting it in worldspace Z direction
hmm
so how do i do it to cat down the player always?
you're asking a question about basic stuff again, and i'm afraid that you're assuming people are chatGPT and the time spent time answering them is worthless =/
if you don't want to figure out anything on your own, why not just use tnua?
brother
its math stuff
i just ask small stuff here
predicate wasn't math, just 10 seconds of bothering to take a look at docs
direction down is just basic transform method but i guess if you started game dev with bevy then nothing would explain it to you 🤔
no
i am game dev since 5 years but bevy coordinates are totally different from the way i was working
like the linear velocity
oh you mean which way is up/forward?
you can just use whatever coordinate system you want, just keep in mind that for default stuff like methods and camera Y is up and -Z is forward
for some reason just _Z works
Describe the position of an entity. If the entity has a parent, the position is relative to its parent position.
A SystemParam for drawing gizmos.
idk if jondolf made any shorthand for that, it'd actually be useful
?
no
i just want alight on small angles
like when he is walking on a ramp
i don't understand why, you'd just get player to tilt
with extra issues around edges
well ia mtrying make a character controller
so i need make it dont keep falling
like this
why did you decide against locking collider rotation?
if i do it i cant do stuff lik knockback
with angular velocity
rotate axis stops angular velocity to works
you mean like that thing from very very valet tutorial?
what?
☝️
wydm on this tutorial there is nothing about it
A detailed look at how we built our physics-based character controller in Unity for our game Very Very Valet - available for Nintendo Switch, PS5, and Steam
BUY NOW!! https://toyful.games/vvv-buy
~ More from Toyful Games ~
- Animation Deep Dive mentioned in the video - https://toyful.games/blog/character-animations
- Custom Car Physics in Unity...
does it really need float?
yep, you can just add IK legs and it should be good
you'll need to do it anyway unless your levels are completely flat lmao
its not level, its a battlegrounds
ok, you'll need IK either way unless your battlegrounds are completely flat.
old games got around that issue by avoiding stairs/ramps and making elevation that you can only jump on, or adding stuff like "interact with stairs" that made you lose control
or just not allowing you or anyone else to see how characters walk up/down stairs/ramps
but these days idk the last time i didn't see IK for legs
I'm trying to detect collisions between a half space and a capsule, but it's reporting collisions on every frame no matter where that collider is. Seems to be related to this issue. Anyone know a workaround?
https://github.com/Jondolf/avian/issues/586
No scales applied. during_current_frame is always true.
I just switched to using rectangles instead of half spaces.
@sleek thicket hey bro iam trying make it float but i cant for some reason, avian does not let it happens?
i tryed move the child translation first
but just the child moves up, the collider stays on same place
i tryied than move the ColliderTransform
but nops, collider transform does not move
so i need try body Position?
nvm avian does not have body position
@past cargo all you need to do is add velocity to collider with rb
and avian does have position, but you're not supposed to change it in this case
rb?
what is rb
rigidbody
The global position of a rigid body or a collider.
Hey @vestal minnow, is this example available anywhere? I'm trying to do something similar and am dumb and can't find anything related to attractors in the Avian GitHub repo
That one is the custom_collider example, though the attractor part isn't the focus of the example
Sweet, I'll be digging into that now
@vestal minnow Mr Jondol, when you a load a scene collider from a mesh, what characteristic is usually necessary for the collider to be shaped correctly? For example, does it need UVs, tangents, normals? Or all it needs is the vertex locations
I ask because I am exporting a gltf, which it is sole purpose is to give me colliders
Only vertices and indices are necessary for trimesh colliders since they describe the actual triangles, the rest is mostly useful for rendering
Anyone know if my estimation is correct that avian will be a pain to migrate to bevy main? 🤔
this has a migration to an earlier version of main, relying on some local dependency patches
https://github.com/Jondolf/avian/commit/33d9f9eabad0c1762de40d90968ea39ad97631cd
not too bad, the biggest non-mechanical thing was probably needing to rework the AncestorMarkerPlugin to use just observers since HierarchyEvent no longer exists
but we wanted to do that anyway, it simplifies things and makes it more robust
I'll migrate Avian's main branch to Bevy 0.16 as soon as the RC is out, but that commit probably works as a base for now
I belive I owe you this info, when exporting collider only maps. From blender, one must have UVs and Normal options added
If it doesnt, it seens indices and vertex are not found, reason unknow
bassicaly the way roblox works is you insert one of those on the character
with attachments
and applie the force
its good becasue
you can insert multiplie
and have forces being applied on different parts of the body
yeah we'll most likely have a similar thing once we have joint motors
a lot of other physics engines have a similar feature too, for example Box2D has b2MotorJointDef and Bepu has a OneBodyLinearServo and OneBodyAngularServo
about the BodyPosition, that is AlignPosition now on roblox, the idea is to make the model move for the designed position you set on it, that way we can lock the model movement, like on roblox have a lot of air combat, where you punch the enemy up and both stay on air, it uses body position to lock the Y on air, so they both can get knockbacked to the sides but stay on air on same y axis
the idea is be able to select the position you want it to move
and the forces values on each axis
so if you like set force 0 on y, it wont move the y axis
same for x and z
its very usefull
idk if you get it cause my english is bad
but i can show some examples if you want later
that's basically a spring
i got confused by your LV demo
O
wiggling with a cursor doesn't communicate well what you're trying to demonstrate 😅
Btw to rotate the player can I Just transform.translatio? Or i should use Psychic stuff?
why do you need to rotate the player?
?? Well Its 3D game so she should walk on alll directions lol
So I need rotate for the direciont he gonna walk
Transform.translation is fone?
*fine
if you're rotating the collider responsible for movement you'll probably run into a bunch of bugs eventually
if it doesn't have children then it's fine, if it does then it's bad either way 😅
@vestal minnow The no_std is coming for you...
I see you started by removing the heaviest std dependency
I also love that this is now just PR 1 of bevy_heavy
Yeah I was surprised by that too lol
not many external users for a mass property crate 😂
True, but still funny haha
@vestal minnow Is this how the example is supposed to work? 🤔
is there example on how to use ExternalTorque? I tried to use it, but it doesn't do anything to the rigidbody.
Did this version actually work when you made it? I don't see why my changes would cause things to fall trough the floor 
I recall things generally working, but I'm not sure if I tried that character controller example specifically
Whats a good 3D example for collisions? 🤔
cubes I guess
Oh ... It really is just the character controllers wtf 😂
for the minimal collision setup
Or something with collider hierarchies? Since the example loads a glTF scene
That's very possible considering you changed hierarchy code 🤔
yea that's probably the most likely thing to be broken, tho iirc tests were passing
I don't need hierarchies to work anyway, so this should be fine 😂
Hmm I don't think we actually have an example for it 🤔 but make sure the body is dynamic, has angular inertia (if it has a collider then it should already have inertia by default), and the torque you're applying is large enough
especially if this is 2D and you're using pixels as length units, you might need some very large forces and torques for things to move
doesl inear velocity doenst accept negative values?
i put z= -10 and it goes forward lol
same if i put just 10
it does, wtf are you talking about
-10 Z is forward tho 🤔
is it possible to advance simulation for a specific object only?
i thought 1000 already large enough for it to have a noticeable movement, now i need 1_000_000 to even do a "slow" rotation (persistence false).
If you're only applying it once you're gonna need really high forces so that makes sense
i mean
seens not
iam setting it positive and negative and still same direciton
then you fucked up somewhere else, probably input
well no, i tested with raw values, let me show
first test 1
second test now -1
same thing

@vestal minnow what i fucked up?xd
nvm
i think i figured out
i facepalmed so hard when i saw it
bro i was sure it was * not +
i need glasses
you need adhd meds
xd

also i notice that some bugs happens if you set linear velocity fields to 0.0 @vestal minnow
i don't, probably something on your end... by now you can just safely assume that every problem is on your end, tbh
xd

yes iam having some issues here, can be due friction?after i move and stop it start comming back very slow
add a plain sphere and add movement to it, if you don't see the same problem then it's on your end
*capsule
capsule would fall over
whatever you're doing to keep it straight might be the reason for the behaviour
i just locked the axis
LockedAxes::new().lock_rotation_x().lock_rotation_z()
ok then capsule should be fine too
want take a look on code?
can be lightyear replicating maybe too idk
testing. Contribute to Kevenpvp/PowerProject development by creating an account on GitHub.
it definitely makes it harder to debug, even if it's not the cause
the issue was i need set the linear velocity to 0 when stops the movement @sleek thicket
nah that's a bandaid solution
i mean i realized that if i dont set to 0 the values keep changing like crazy
that maybe because lightyear replication system
probaly lightyear replication system
☝️
i mean that is not input because i dont set the linear velocity if the unit is not on walking state
i also printed to check
but i notice that the Y on linear velocity gets crazy when iam moving it
let me show ya
maybe its because its not floating xd
walking state is when you have velocity?
i made a state machine, walking states happens if the input direction x or z are bigger than 0.0
pub fn character_inputs(
mut commands: Commands,
mut character_query: Query<(Entity, &ActionState<CombatantActions>, &mut StatesMachine, &NetworkSide, Option<&PlayerCombatant>), (With<CharacterController>)>,
){
for (entity,action_state,mut states_machine,network_side,player_combatant) in character_query.iter_mut() {
if player_combatant.is_none() && network_side != &NetworkSide::Server{
continue;
}
let move_dir = action_state.axis_pair(&CombatantActions::Move);
if move_dir.x != 0.0 || move_dir.y != 0.0 {
if !states_machine.can_execute(StatesType::Walking) {continue;}
if !states_machine.current_states.contains_key(&StatesType::Walking) {
states_machine.execute(&mut commands,entity,network_side,StatesType::Walking,StatesInfos{
start: Default::default(),
duration: 0.0,
source: Default::default(),
in_cooldown: false,
applied: false,
values: Some(StatesValues::Walking(
Vec3::new(-move_dir.x,0.0, move_dir.y),
)),
});
}else {
states_machine.current_states.get_mut(&StatesType::Walking).unwrap().values = Some(StatesValues::Walking(
Vec3::new(-move_dir.x,0.0, move_dir.y),
));
}
}else {
if !states_machine.can_execute(StatesType::Idle) {continue;}
if !states_machine.current_states.contains_key(&StatesType::Idle) {
states_machine.execute(&mut commands,entity,network_side,StatesType::Idle,StatesInfos{
start: Default::default(),
duration: 0.0,
source: Default::default(),
in_cooldown: false,
applied: false,
values: None,
});
}
}
}
}
so when you release input, what happens?
it execute the Idle state
i can even show ya wait a bit
see
now as i said the absurds values on Y when iam moving it
may be the reason?xd
when adding input you run system that adds it to velocity and replicates it
when idle, you just don't replicate it
do i get that right?
you're not commenting anything so i have no idea what you're doing
when you press any movement input it first check if the unit can enter on walking state, if yes it set on walking state and save the direction dir
if you stop press and movement inpu
it start the idle state
that stops the moving state
on idle state the unit doenst move with inputs
but as i said, cant this be the reason?
the Y GIANT VALUE LOL
yes
isnt that 0
no?
y is being big f numbers
let me show ya xd
i dont think this should be values on y xd @sleek thicket
considering iam not changing y
damm
it's probably just 0 with floating point error
ah, i guess walking state is triggered by it so it's still a potential bug
didn't rust have a warning on comparing floats
no its not, cause i put a print when its walking
cause i move the unit here
and its not printing when its on idle state
so its not it
yep
0 FPEs to 0.0000000000000000000000000001
0.0000000000000000000000000001 != 0, so you're walking
basically you need to switch that to move_dir.length <= 0.01
or whatever the controller deadzone is
hmm but you mean the move dir is wrong when iam setting it on walking?cause its not triggering walking state when i stop input
because this if seens pretty much working
let me test it
@sleek thicket yup
its not triggering the walking state
but aftr i stop walking
the linear keeps like ths
unless i do linearvelocity = 0
maybe the move dir is a very weird value
i was just joking but if you're paying then i can actually go read your github
xd
but yes bro, the walking state is not being triggets meaning the if move_dir.x != 0.0 || move_dir.y != 0.0 { is working , i checked with the printt
the problem is when it stops moving the linear velocity keeps crazy
until i set it 0
that can mean:
1-the capsule is not floating so maybe the values are crazy cause it
2-the move dir while waking is giving weird values
3-the y value being weird as hell is influencing the z value
then the problem's in the branch where it's not moving
i mean i dont do nothing while its not moving
comment everything you're doing, i'll check your github next time if you don't accidentally find the problem yourself
well still can be the the y weird value cant it?
or because the capsule is not floating
bro you are a goat fr
@sleek thicket the problem was the Friction(|| Friction::new(50.0_f32)),

if i dont put adefault friction ,it doenst happens
Isn't friction supposed to be between 0 and 1?
xd idk
The friction coefficients should typically be between 0 and 1, where 0 corresponds to no friction at all, and 1 corresponds to high friction. However, any non-negative value is allowed.
does friction above 1 just push you in negative direction? lmao
if you dont set the velocity backs to 0 yes
either way that doesn't sound right
bt [] i think my character model seens inverse rotating, any easy way to see the look vector?
cause you guys said -z is forward
but z is being forward here xd
what
to match blender
you just have to keep in mind that for camera -Z is forward and Y is up
and X is left if i understand it correctly, idk it always makes my brain hurt
yeah, unless you add damping
and friction 1 = no slide at wall
idk how often it's done but before hovering sphere i had 2 colliders, one with friction for legs and one without friction for body, i was mostly just copying wolfire's procedural animation stuff
is this because the floor friction too?
also i've never seen that before, really cool seeing the actual prototype stuff
https://youtu.be/SAtwQa8t_3g
http://www.wolfire.com/overgrowth
I have been asked many times how the procedural animation worked in the old Lugaru 2 movement demos, so I made this video showing some of the early stages!
Check out the game site at:
wolfire.com/overgrowth
You can follow its progress on the Wolfire games blog:
blog.wolfire.com/
might be because of high speed, you want that kind of behaviour in more realistic games anyway
i guess its because floor friction too, cause so far i saw slide is calculcated basaed on both colliders friction
nvm
its the high speed as f
oh yeah you can set which one affects it
yeah you need environment to see what's actually going on
i guess is the highest speedcause i set the floor friction 1 too and still the same
reduced speed to 3
and works now
slide a bit still, what is dampening as you said?
damping just reduces velocity regardless of friction
but in this case i think you just need IK
i just set the linear velocity to 0 when stop walks
hmmm, how this would help me? isnt that just to make the feet animations move cool on terrain?
like to follow terrain, stairs etc
having prog
body would have inertia without legs looking like they're sliding
okie but i would need put colliders on the feets right?
no
?
but the mesh model
have nothing
its just visual
oooooooooooooooooooooooooooooo
you mean to show how they are sliding
for ppl
???
its my bad english
i understand what you mean
but my bad english kills me

well in some months you will see my combat game getting form, iam doing it like i did on roblxo a time ago @sleek thicket
iam specialist with combat and spells game xd
first time doing on bevy
wish me lucky
famous last words xD
well iam 5 years doing games xd
i have experience at least xd
games or roblox
games on roblox, roblox studio is a engine in lua
i work with it
but now iam trying make a game on bevy as hobby
similar to this
combat + spells
scripting
yup
Haven't read the whole conversation, but generally rigidbody colliders dont make good character controllers on their own. You need to implement specific collision handling for characters so that they behave more like legs, rather than a rigidbody
Hmmm i locked two axis
And iam moving it
What more should i do?
Yeah but going up slopes and dealing with un-even terrain won't work out too well (at least I didn't like it)
I also now iam setting the linear velocity x and y to 0 when it stops now
because normal forces and sliding, etc.
What should i do mr frog
Legs and walking don't behave like rigidbodies at all, so sliding a rigidbody around will always feel wrong
Frog senpai
Well, I've been working on a character controller in 2d. I tried Tnua which does a floating body controller, but I found it to be a bit too complicated for me. When trying to implement my own, I started off with just a rigidbody capsule as well, but ran into the numerous issues that occur when going across un-even terrain. That's about when I reaized that pedal movement doesn't really match RigidBody physics
I tried doing a circle with infinite friction and rolling that around, and that works okay
But it makes other things complicated.
So now im working on just having a capsule shape cast (I dont actually use a Shapecaster because the system ordering doesn't work out for what I want to do with it, so I do an explicit shape cast in the system I need it for) and then resolving collisions / overlaps in a way that would feel natural as a walking entity
How shape cast helps you there?
Because it doesn't apply any forces or anything. It just tells me where the overlaps are happening, then it's up to me to implement how to resolve it.
Well you could use kinematic rigid body instead
Messed around with it and I didn't end up using it. I don't reember what issues it had, but it isn't an automatic solution.
I think it was because you still dont get control over how te resolve collisions, it just forces anything that overlaps with it to get pushed out of it.
So, bassicaly, rigidbodys are no good for character controllers
To be honest you could make a rigidbody static at least so others rigidbody would collide with It @paper maple
U could try the Kinematic bodies and see how that goes
but defnitely not Dynamic bodies
in robotics doing extremely simple stuff like walking turned out to be the most difficult problem to solve
character controller is robotics where you're allowed to cheat, and everyone's failing even with that
either way i took a look at battlegrounds and i'm not even sure if it's possible without dynamic rb
Uh huh yeah except the people solving it for themselves haven't spent years studying the topic ? More like 2 weeks intermittently ? I'm not sure why you feel the need to be condescending
Condescending and dismissive. @sleek thicket
nice
Wich battlegrounds you took a look?
followed a link with same name from what you sent before
But iam not even able to make It float with dynamic rb
Roblox have default character controller called Humanoid
yeah i know, roblox devs already figured out everything for you
please don't state things you don't understand as facts
do you know what gravity is?
I tryed set the y to 0.5 every frame
I mean i tryed set the linear velocity y to 0.5 every frame
not in game dev, just tell me what gravity is
A force pushing you down
ok that's good enough, so how do birds fly irl if there's a force pushing you down that makes it impossible to fly
So you mean the linear velocity y need be the same force as the Gravity?
If its higher It Will fly
If its lower it wont fly
If its equall It Will float
what u seem to not understand is that birds are not RIGID
yeah, gravity is just velocity.y -= 10/s
but that part only matters when they actually collide with things
you can also just disable it altogether and apply it manually like how many games do it to make jumping/falling feel better
Its possible to modify the gravity on avian? And How do i see the current amount?
https://docs.rs/avian3d/latest/avian3d/dynamics/integrator/struct.Gravity.html
https://docs.rs/avian3d/latest/avian3d/dynamics/rigid_body/struct.GravityScale.html
A resource for the global gravitational acceleration.
Controls how gravity affects a specific rigid body.
@paper maple i think you could Shapecast sphere down the character like 10% bigger than current Sphere, If It find some floor you Already make it up
Hmm
it needs to be smaller because otherwise it'd hit walls
Btw just to make sure again, why It need floats?
Also How would i make something fly and stay on a determined y axis? Cause if the Y is much bigger It Will feep flying forever
And going up
Since there is no body position forces on avian
Or i would need make my own gravity for the character?
it just removes some problems other controllers have like walking on stairs in just 2-3 lines of code
VVV video explained all of it, did you end up not watching it?
im really curious why one of my game object has (Position, Rotation) without me inserting it, but not the other
both have rb
and i think rb doesn't have Position and Rotation as its required components
Looks like they're created by avian::prepare::init_transforms which looks for Added<RigidBody> so it might get skipped if you add that component after the system runs, which looks like it's in FixedPostUpdate.
i spawned both at startup in the exact same way..
it's not really a big concern right now, but it's just annoying when i think about it
match (has_rigid_body, new_transform) {
(true, None) => {
cmds.try_insert((
Position(new_position),
new_rotation,
PreSolveAccumulatedTranslation::default(),
*previous_rot.unwrap_or(&PreviousRotation(new_rotation)),
PreSolveRotation::default(),
));
}
(true, Some(transform)) => {
cmds.try_insert((
transform,
Position(new_position),
new_rotation,
PreSolveAccumulatedTranslation::default(),
*previous_rot.unwrap_or(&PreviousRotation(new_rotation)),
PreSolveRotation::default(),
));
}
(false, None) => {
cmds.try_insert((Position(new_position), new_rotation));
}
(false, Some(transform)) => {
cmds.try_insert((transform, Position(new_position), new_rotation));
}
}
https://github.com/Jondolf/avian/blob/0474c721040582caa304dc70ddce4c53faca250a/src/prepare.rs#L312C1-L338C10
also it's using try_insert but im not sure if that's actually matters
worked a bit on Peck yesterday, got rectangle-rectangle contact manifolds with SAT and clipping working I think
now I could theoretically plug this in Avian to simulate box collisions without Parry :P
I'll test that later tho
what is parry
The collision detection library that both Avian and Rapier currently use
i see
it was built primarily for Rapier, but can be used independently
pls bro make body position, will make float so much easier xd

rn i need keep controlling character gravity scale to make it float
- linear velocity y
there's Position component though?
its not body position
what do you mean by body position
even in that reference it said deprecated
also I'm not sure avian should add that kind of feature in the engine
not like i know avian long-term goal
yes because have the new ay
that does the same
but you can focus the point it will move
with a attachment
bro
this is essential to make fly for example
na bro, make it float is dumb, the math is not mathing

i will f ignore it for now until jondol make body positio
that sounds like a game engine feature and not a physics engine feature
broo
to make fly now its almost impossible with dynamic body
lot of engines have this feature so wydm
seems like i misunderstood the description
yeah that sounds useful in more cases than i thought
yup
idk if unity has it but i ended up just making it myself for grabbable objects
BodyPosition is a cursed name for that, AlignPosition is better but still not immediately obvious
if you know what it's called in other engines then link it, might be useful for future bikeshedding
we do have a DistanceJoint which could be used for a kind of similar effect, you'd have a static or kinematic body for the target position and constraint the other body to that via the joint
not quite the same as what that thing in Roblox is though
yeah, i think it affects rotation when pulling? idk about roblox though
oh nvm if it's not center then it does
roblox to affect rotation is other stuff
called AlignRotation
not aligning, just affecting
than its AngularVelocity
Yeah the distance joint only applies a torque if the attachment point is not at the center of mass
like when you try to pull head to the ground, body bends over
instead of just getting stuck
i mean the issue rn is not able to make character controller with dynamic body lol
its just over complicated
like
it's 99% netcode for you
i have a floating dynamic controller with coyote time working with alignment to custom gravity working in 10 lines of code if you don't count the boilerplate and the cursed camera, but i can't send it to you because your netcode would break it
o yes but on this case you are doing custom gravity
i wanted see the direction iam shapecasting
A SystemParam for drawing gizmos.
i don't understand why you'd need it without custom gravity though, it goes exactly where you tell it to and you're not even changing it
that's why i misunderstood it, bad name imo
distancejoint isn't perfect either, assuming it does exactly the same thing
i like Bepu's name more, but still not immediately obvious
i don't think there's a perfect name, but i just don't like BodyPosition / AlignPosition
it's more like Roblox's SpringConstraint
or Bepu's DistanceLimit
or Jolt's DistanceConstraint :P
@vestal minnow would splitting joints into required components make no sense?
every joint has 2 entities, 2 anchors, lin+ang damping, compliance and force, and position lagrange and exact same docs
and would distancejoint be any different from fixedjoint if making rest_length optional meant that it's same as distance between anchors?
and are you planning on turning joints into relationships
FixedJoint aligns both translational and rotational degrees of freedom, some engines call it a weld joint
oh, 🤔
We might extract some shared things into their own components for the user-facing API, but many constraints have properties that can't reasonably be shared across joint types. For example for a revolute joint, you might want to configure the stiffness of the point-to-point constraint and angle limit constraint separately, and they have their own forces and Lagrange multipliers, etc.
I imagine we'll also want to have a split between the user API for joints and the internal representation, since using the ECS for solver internals isn't great for perf or determinism atm
(currently joints can cause determinism issues in some cases because of query iteration order)
bro idk the math to make a capsule gizmo
idk if iam shapecasting correctly to get the floor
since the parameters are very weird compared what ik
gizmos.primitive_3d(Capsule3d
like this mask stuff
its working oposite the way it should? its black list or whitelist?
cause i made the floor Default layer
and i tryed make floor on this mask
but when i do it starts ignored the floor lol
can you read what it says in the tooltip for me
Specifies which collision layers will be included in the spatial query, wich means for me it will just get stuff inside on this layer
that doenst happens
the oposite happens lol
this make me hella confused
default is 1 so it should work.
as usual, you can safely assume it's something on your end.
?
default is 0
the floor is on Default layer
does .into() work? i don't use physicslayer at all so idk how it's done with it
so how tf you get just grounds? if i dont use physicslayer it keep getting the own character
i also need get the bottom point of the character collider to calculate the floating distance
const LITERALLY_NOTHING: u32 = 0;
const DEFAULT_LAYER: u32 = 1 << 0;
const FIRST_LAYER: u32 = 1 << 1;
const THIRD_LAYER: u32 = 1 << 3;
const LAST_LAYER: u32 = 1 << 31;
const LITERALLY_EVERYTHING: u32 = u32::MAX;
const THIRD_MASK: CollisionLayers = CollisionLayers::from_bits(THIRD_LAYER, LITERALLY_EVERYTHING);
you mutate everything as you iterate?
to be honest i wanted to know the capsule height size
@sleek thicketi but capsule just have a .radius
not .height
nvm it have
now it make all more ez
@vestal minnow something is wrong here, the floor is on transform 0,0,0, the height is 0.1, means the top of it would be y = 0.05 (that is height / 2), until now fine, but my entity collider is height 1, means to stand on top of the floor the y would need be 1 / 2 + 0.05 = 0.55, but for some reason its 0.85 to stand on top, like wtf?
or on bevy the translation is not the center?

joints are currently solved by iterating through all joints serially, but the query iteration order can be different depending on Entity IDs (and probably some other factors) which can cause problems for networking since the IDs may not be stable across clients afaik
and different constraint solve order can result in different behavior
the capsule radius is added to the height
well but iam using capsule.height and it returns me 1
the height is the height of the cylindrical part between the hemispheres, add 2x the radius to get the total height
so if the capsule has a "height" of 1 and the radius was e.g. 0.25, the actual full height is 1.5
why this approach btw?
doenst it seens unecessary?
There's a lot of reasons:
- Bevy's
Capsule2dandCapsule3dand their meshes are defined like this - You could get impossible configurations if the radius wasn't added. For example, a capsule with a height of 0.5 and radius of 0.3 would be invalid, since the radius would make the height at least 0.6.
- Mathematically, a capsule is often defined as a cylinder with hemispherical ends, or as a line segment that is expanded by some radius (using the Minkowski sum). With either of these definitions, it's pretty intuitive to represent the capsule with the height or length of the cylinder or line segment, and a radius.
- The representation is better for many calculations and algorithms
Pff, clearly capsules are defined as distance away from a line segment 
did @sleek thicket
it floats 0.1 studs
from floor
while the character model still correctly on floor standing
with dynamic body
I think often in editors like Godot and Unity it does actually use the total height of the capsule, but it's tied to the radius so that it's impossible to get those invalid configurations like a radius that is smaller than the height
okie, now i need see how iam raycasting to get the floor correctly
my plan is raycast from capsule top and goes down to get the closest floor
if the floor normal 1 is to big so its not auto step
if its small the diferecence so i auto step
well if it follows roblxo shape cast logic
it wont detect nothing that is inside the ray when its casted
so i wont have this problem
its excluded already
combatants are on a different layer
i dont want get combatants as floor lol

is that a bad idea though
i mean, i dont want ppl stand above other ppl
they should slide
