Hello, I’ve come back to this controller due to its update with the UpDirection property (thank god), but I’m having issues controlling the character. To be honest I’m not too math savvy and I’m unsure exactly of the problem, but previously (before UpDirection) I used a VectorForce to emulate the movement forces of the controller. Now that UpDirection is enabled, theoretically I should be able to remove the VectorForce entirely and rely on the Controllers movement force. Well to some extent I can, but it seems that the force is not (relative?) to the controllers upvector and it causes strange movements. Here is a snippet of some code below for reference:
--MainModule
function GravityController:UpdateMover(Planetoid)
local Work = parallelModules["Mover"]:Work()[1]
local controllerManager = self.controllerManager
self.controllerManager.UpDirection = self.upVector
local camCF = workspace.CurrentCamera.CFrame
local desiredDirection = Work[2]
controllerManager.MovingDirection = desiredDirection
if self.Camera.CameraModule:IsCamRelative() then
controllerManager.FacingDirection = camCF.LookVector
else
if desiredDirection.Magnitude > 0 then -- Is the character currently moving?
controllerManager.FacingDirection = Work[1].LookVector
else -- Character not moving
controllerManager.FacingDirection = controllerManager.RootPart.CFrame.LookVector
end
end
end
--Parallel Module (performs calculations)
local module = {}
local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if dot < -0.99999 then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end
return function(Params, TaskIndex)-- Most of this is code is from Egomoose's gravity controller!
local CharCF, desiredDirection, upVector, isCamRelative = Params[1], Params[2], Params[3], Params[4]
local camCF = workspace.CurrentCamera.CFrame
local fDot = camCF.ZVector:Dot(upVector)
local cForward = math.abs(fDot) > 0.5 and math.sign(fDot)*camCF.YVector or -camCF.ZVector
local left = -cForward:Cross(upVector).Unit
local forward = -left:Cross(upVector).Unit
local hrpLook = -CharCF.ZVector
local charForward = hrpLook:Dot(forward)*forward + hrpLook:Dot(left)*left
local charRight = charForward:Cross(upVector).Unit
local newCharRotation = CFrame.new()
local newCharCF = CFrame.fromMatrix(Vector3.zero, charRight, upVector, -charForward)
local worldMove = forward*desiredDirection.z - left*desiredDirection.x
local length = worldMove.Magnitude
if isCamRelative then
newCharCF = CFrame.fromMatrix(Vector3.zero, -left, upVector)
else
if desiredDirection.Magnitude > 0 then -- Is the character currently moving?
worldMove = worldMove / desiredDirection.Magnitude
end
newCharRotation = getRotationBetween(
charForward,
worldMove,
upVector)
end
local charRotation = newCharRotation * newCharCF
return charRotation, worldMove, desiredDirection
end
Hi there, I noticed that having AirController.MaintainLinearMomentum off does not seem to respect ControllerManager.UpDirection. Whenever it is disabled, it stops all momentum in the y-axis–not the set up direction.
I should land in the same spot every time, but when MaintainLinearMomentum is off it offsets me each time I jump.
This feature released like 2 years ago and it is still ultra Jank, just tried it today, and at first, I thought since controllers are supposed to float above the ground to be able to climb over stairs and slopes, they didn’t apply force to the objects they were standing on (This turned out to be false).
Trying to figure out whether they applied or not force led me to find that the reason why my seesaw was not going down, is because the part goes to sleep and since our character controller cannot touch it, we can’t wake it up.
Shapecasts are useless since they do not have margins, that’s why you can’t use them yet, this makes them unreliable as hell when the origin shape has already clipped through a wall, and it is exactly the same reason why I can’t build a kinematic character controller and I am using this one instead.
If you are using a raycast to update the ground sensor perhaps you could calculate the position of the player according to the distance of the player from the ground to instantly snap it to the crouched position.
used to do this actually and it just made more issues to fix than it solved, had to cap slope steepness and step up max values and in the end people could still just clip on walls and stick to them. not to mention its also framerate based, so if you’re running it at 60 fps its gunna be harder/different than someone at 240 fps. The groundcontroller does have two values called “StandForce” and “StandSpeed” which seem like exactly what i want right now by the name, but they do nothing different when changed. I think this is a feature they had planned but never got to
I cant really explain it all to well, but is there any reason as for why the character rotates like this when setting the UpDirection?, I would assume this is how you are supposed to use it since movedirection works fine with same values
I am setting the UpDirection to be the raycast normal from under the root part, and I’m setting both MoveDirection and Facing Direction to be the movement input direction relative to the camera
The UpDirection feature is greatly needed for my project, if anyone can help me with this, I will appreciate it!
@kleptonaut are there any updates on the official Roblox implementation to replace the Humanoid? I am very interested in that and judging by this thread it seems a lot of people see the value in this.
EDIT: At the very least, could we get the default values used by the Humanoid for things like:
Seems like the default values do not create the same exact feeling in the character’s movement.
EDIT2: Setting UpVector seems to work for simple values like (1, 0, 0) and (0, -1, 0) but set it to (1, 0, 1) and it automatically gets set to (0.7, 0, 0.7) why?
EDIT3: That’s because of normalization my bad. Just use .Unit to normalize the UpDirection.
I’m currently working on a character controller system and I’ve run into an issue with my GroundController. Specifically, the Active attribute of the GroundController (which inherits from ControllerBase) is not being set to true under certain conditions, and I can’t figure out why.
AirController seems to activate with no problem.
However if I publish the place and play test it in an actual Roblox game instance it works completely fine.
I’m suspecting that a recent Roblox Studio update might have changed an interaction that I didn’t account for.
Here are my questions:
What could cause the GroundController.Active attribute to remain false even when it is set as the ActiveController?
Are there any recommended ways to debug this issue further? For example, is there a way to trace what might be preventing the Active attribute from being set to true?
To fix this issue make sure your PartSensors are Children of the RootPart of your Character.
Otherwise the physics to apply the offset or rotation of your GroundController will stay inactive.
controllerManager.GroundSensor = groundSensor
groundSensor.Parent = HumanoidRootPart --Insert your rootpart here
Hi there, somewhat major bug that was introduced in a recent roblox update, that is plaguing my game.
I noticed that if a part was destroyed below the character, the game has lag spikes and then all the balancing physics will stop, making the game unplayable until a player resets.
Yeah, that’s an issue I’ve been having. With the provided Character State localscript, the AirController gets stuck as the active controller when a part below the player suddenly gets deleted. A hacky workaround is to add a RenderStepped:Wait() on the line before cm.ActiveController = cm.GroundController
edit: this does not work consistently, nevermind.
This is a major thing that needs to be addressed soon.