PhysicsCharacterController | Mover Constraints based character controller

Alright, I’ll work on fixing the issue myself. Thanks for the info!

I tried using this, and It completely breaks my already set up startercharacterscripts, including my move set script.

I have no idea why its doing this, and I haven’t found any solution. I’m also curious on how I can remove the slide and the other extra things you added to this module.

If you’re talking about humanoid.Running a reason why it didn’t run is because this module instead uses custom state machine, mine also got the same problem and i haven’t found where it is stored in the module itself.

Disabling shouldn’t be that hard, check this topic here PhysicsCharacterController | Mover Constraints based character controller - #39 by bluric_64bit

Yes, humanoid.Running completely doesn’t work anymore.

Roblox should really give us more tools to use, because there’s gotta be an alternative to this.

Hi

Thanks for creating this awesome module!
I’m using it on a custom character that isn’t R15. Everything works fine on my machine, but some players are reporting a bounce that keeps getting stronger and stronger until they eventually get flinged off the map. I think this is because the force values are finely tuned for an R15 character, and they don’t work that well on other AssemblyMasses.

Is there a recommended value of these forces? (one that is preferably a function of the rootpart’s AssemblyMass)

I have a suspicion it’s the player’s framerate that causes these glitches, but I’m not sure.

Any help is greatly appreciated, thanks!

1 Like

Hey there thanks for the compliments.

I will also CC @JoyfulFlowerMary and @coolerthanbatman123 as they were discussing this issues as well.

Here is a video of the issue.

Your suspicion is right. Just found out about this fps plugin controlling tool which is very useful.

From the video I can conclude that it is caused by the dampening not being sufficient while the spring force is very high which is done to mimic humanoids.

        self._vectorSpringDragForce.Force  = Vector3.new(0,-rootPart.AssemblyLinearVelocity.Y*damping,0)

I will try to implement a physics sub step algorithm similar to the video below. I believe it explains the issue more clearly.

2 Likes

Oh! That would be a great update to PhysicsCharacterController! The main issue that I’ve had with it is the bouncing when the frame rate drops (which mainly affected some people that visited my experience, though it sometimes happened when I’d start testing in Studio).

Weeks ago, I stopped using PhysicsCharacterController because of this and managed to make similar smooth character movement without it, but when I tried adding it back, I noticed a problem.

I added a rolling ability to my game, which changes the player’s state to Physics and activates collision on an invisible ball welded to them. It works when PhysicsCharacterController isn’t enabled, but when it is, it stops my character from tilting forward with the ball, breaking it. Here’s the post about rolling:

Is there a way to tell PhysicsCharacterController to temporarily allow the built-in character to change to the Physics state, only taking over again once the humanoid tries to leave it?

Hey nice to see you on this project again. I think all you have to do is clamp the forces so that you don’t get any unusually large forces.

For my own custom controller, which I started on so long ago now @_@ (thanks again to yours as it was a great help). I gave up on the spring and instead set gravity to 0 in the workspace. Then I apply gravity to the player whenever he’s not grounded. I know this isn’t suitable for every case, but it worked for my needs.

I’m curious to see how you might manage to solve the issue because I’d still be very interested in using springs for things like cars in the future.

1 Like

I believe I have done it from my testing.

Still believe there are definitely more bugs such as one I found when using the slide component during low fps.

Also some jumps still bounce you into the sky but now it can go on the lowest possible fps setting in the testing plugin.

Both GitHub and the place file is updated.

List of changes:

  1. More accurate hipheight
  2. Low fps fix through substepping
  3. Removal of suspension attribute, now calculated using gravity and hipheight values

On a side note, the code is more of a mess now and trimping/ramp sliding is nerfed due to less suspension overall. Still pretty interesting and shows the substep algorithm from the video worked.

3 Likes

Awesome!
Can confirm the bounce when the player stands still is fixed. However there’s still an issue when the WalkSpeed changes on lower framerates. It’s probably the same thing, where the force instantly updates and gets set way to high. I’ll see if I can fix it in the same way you fixed the falling.

1 Like

I copied the latest version of PhysicsCharacterController to my experience (and swapped its Animate script with my own, which was adapted to work with a previous version of it so that isn’t the issue), and when I test it, my character is stuck in the air and this error is spammed every frame to output.


What’s wrong here? Is it the missing WalkSpeed attribute? I tried adding one to the character model but that didn’t stop the errors.

I think it’s the xzdragcoefficient you’re missing.

Oh… I guess it was that. Actually, I had it set up so a loading screen script selectively enables scripts based on if they have a “EnabledForStandard” attribute set to true, which for some reason broke PhysicsCharacterController, which appears to only work if it’s initially enabled (like, the built-in “enabled” property). Once I did that, it worked.

The only reason why I’m returning to PhysicsCharacterController from my own movement scripts is because Roblox’s going to inevitably force their new character controller on all experiences once it’s out of beta, like unfortunately they do with most things. PhysicsCharacterController seems to be unaffected by the new character controller, so if I use it, my experience’s movement won’t break when that happens.

Well, at least basic running and jumping don’t break… My custom rolling ability is broken, and I don’t know OOP enough to even think of recreating it as an add-on to PhysicsCharacterController.

2 Likes

Hi again
Is there a way to make the HipHeight’s upwards force more responsive?

When my character walks up a slope (at pretty high speed), it’s legs are clipping through the ground. When I stop running the character correctly gets to the correct height, it’s just not responding fast enough when it’s target height constantly changes.

I tried reducing the dragforce, but that makes the character bounce. Is there a way to improve the responsivity while keeping the character stable?

I’m sure there’s an obvious solution to this, but I can’t figure it out…

2 Likes

Hey there, this problem is more complex then you think.

I do not know, other than the spring method I used has it’s flaws here as you described.

One idea is to take some notes from another humanoid replacement module luanoids, Perhaps you can take notes from their equations in walking.lua to get the upwards force.

I believe I also unconsciously took notes from their module organization as each state is a module script similar to mine. I studied it a couple times before but was also confused by the OOP structure similar to @JoyfulFlowerMary lol. This prompted me to make my own which is this module so in all I definitely recommend you create your own.

Luanoids method:
			-- counter gravity and then solve constant acceleration eq
			-- (x1 = x0 + v*t + 0.5*a*t*t) for a to aproach target height over time
			local t = POP_TIME
			aUp = Workspace.Gravity + 2*((targetHeight - currentHeight) - currentVelocity.Y*t)/(t*t)

			-- Don't go past a maxmium velocity or we'll overshoot our target height.
			-- Calculate the intitial velocity that under constant acceleration would crest at the target height.
			-- Humans can't really thrust downward, just allow gravity to pull us down. So if we go over this 
			-- velocity we'll overshoot the target height and "jump." This is the physical limit for responsiveness.
			local deltaHeight = math.max((targetHeight - currentHeight)*1.01, 0) -- 1% fudge factor to prevent jitter while idle
			deltaHeight = math.min(deltaHeight, HIP_HEIGHT)
			local maxUpVelocity = math.sqrt(2.0*Workspace.Gravity*deltaHeight)
			-- Upward acceleration that would cause us to achieve this velocity in one step
			-- Would /dt, but not using dt here. Our dt jumps is weird due to throttling and the physics solver using a 240Hz 
			-- step rate internally, not always the right thing for us here. Having to deal with not having a proper step event...
 			local maxUpImpulse = math.max((maxUpVelocity - currentVelocity.Y)*60, 0)
			aUp = math.min(aUp, maxUpImpulse)

I was also looking into CFrame based methods similar to the source engine where they used some collision tracing and set the position to make characters stay on the ground

Source engine method
void CGameMovement::StayOnGround( void )
{
	trace_t trace;
	Vector start( mv->GetAbsOrigin() );
	Vector end( mv->GetAbsOrigin() );
	start.z += 2;
	end.z -= player->GetStepSize();

	// See how far up we can go without getting stuck

	TracePlayerBBox( mv->GetAbsOrigin(), start, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace );
	start = trace.endpos;

	// using trace.startsolid is unreliable here, it doesn't get set when
	// tracing bounding box vs. terrain

	// Now trace down from a known safe position
	TracePlayerBBox( start, end, PlayerSolidMask(), COLLISION_GROUP_PLAYER_MOVEMENT, trace );
	if ( trace.fraction > 0.0f &&			// must go somewhere
		trace.fraction < 1.0f &&			// must hit something
		!trace.startsolid &&				// can't be embedded in a solid
		trace.plane.normal[2] >= 0.7 )		// can't hit a steep slope that we can't stand on anyway
	{
		float flDelta = fabs(mv->GetAbsOrigin().z - trace.endpos.z);

		//This is incredibly hacky. The real problem is that trace returning that strange value we can't network over.
		if ( flDelta > 0.5f * COORD_RESOLUTION)
		{
			mv->SetAbsOrigin( trace.endpos );
		}
	}
}

I would try both of these methods but I don’t have the time and well default humanoids also do the job fine for now unless you go into custom movement. My game needs other aspects such as UI which I haven’t learnt yet.

Good luck.

2 Likes

NVM, I got reinterested in this topic and updated it.

The luanoid method through the acceleration equation works great!

However had to rework the raycasting and also add physics substepping in order to solve the core issue with luanoids hipheight which also made it bouncy at low fps.

Trimping works great now and reaches greater heights.

Now the next bug to solve is the drag force for normal movement which also requires physics substepping.

3 Likes

Nice! I like the recent improvements to PhysicsCharacterController, especially since I feel I really have no choice but to use it again, since it ensures the new character controller won’t ruin my experience. (It’s still so ironic, I started using this so I could get an idea of what Roblox’s new controller would do, but over time, started realizing how better this custom controller is compared to it.

The only downside is that I’ll have to import the scripts, edit the default attribute values (since I make most body parts massless), and change that one signal-firing line to be “Signal:Fire(true)” (which really should be added to PhysicsCharacterController itself since it improves compatibility with custom Animate scripts like mine.

Without that, signal presumably sends “false” to my OnJumping, OnFreefalling, and other functions, which messes up my jump animation. (The initial jump animation never plays, and the landing animation is played as the player enters the falling state instead of when exiting it.)

2 Likes

That’s a good thing to hear, although i appear to noticed something off with my old game “UBILS” now i wasn’t sure where the custom state is to make walking sound and arm bobbing works because of your module blocking the built-in events preventing it running. (other ones such as landing for this viewmodel still works as it uses velocity to trigger)

and sometimes playing it, has a collision issue which makes your character fly whenever looking up on the sky or roof, wasn’t sure if this is my stuff but tools wouldn’t be causing like this as they also occur with no tools.

But for now how would i get this to work with other humanoid events like Running? was leaving it behind after my old game cuz i cannot find where the custom state is.

1 Like

You can access it using _StateSignals key in the object. This is how I replace the default animation events in the animation module.

Let me know if you find another FSM module that can handle events and has similar syntax to :ChangeState().

    local stateSignals = characterController._StateSignals
    local connection2 = stateSignals.Jumping:Connect(onJumping)

Send a repro file or I can only guess that it’s due to hipheight module with the raycasting hitting the viewmodel.

For @JoyfulFlowerMary I plan on creating another module script to edit the default modules, organization its not good to have to go into every module script to change every default module.

Also I recommend forking the GitHub via Rojo and making your modifications there so you can receive updates as well.

I plan to work on the next physics substep drag force bug fix and fun thing like airstrafing and bhopping.

2 Likes

I only feel that it’s intended to be used for Modules only when that was called inside, How about using it for LocalScript outside??

also here’s the file from another game which has the same viewmodel system (it kinda got nerfed but it’s still bouncing character only when walked)
RFPS.rbxl (252.3 KB)