Wall stick/Gravity Controller

So i’ve been working more on my game and i found a new problem setting the CFrame of the player also doesn’t work

Imagine this in VR, it would be terrifying :grin:.

1 Like

You have to use the Set method to do this.

2 Likes

SetPrimaryPartCFrame? Or just that. Or how excatly do you do it.

This would legit help my racing game since a lot of the maps will have twists and turns and their own gravities. I’d pay robux for this cause you deserve your hard work.

1 Like

No there’s a method on the wallstick object itself called Set

2 Likes

Now it might just me being stupid but i can’t seam to find it in any of the scripts so i know which to required. But could you show an example or something maybe. I know i am dumb but i am only 15 and haven’t been programming in roblox for very long

local WallstickClass = require(ReplicatedStorage:WaitForChild("Wallstick"))
local Wallstick = WallstickClass.new(game:GetService("Players").LocalPlayer)

-- Updside down baseplate teleported to (0, -300, 0)
Wallstick:Set(workspace.Baseplate, Vector3.new(0, -1, 0), CFrame.new(0, -300, 0))
3 Likes

So i am now getting an error but i think it might be because that i am using the scripts from the playground.rbxl file instead of the other scripts, i have noticed that it is slightly different. The error is

16:46:15.572  PlayerScripts is not a valid member of Player "Players.patfre"  -  Server - Camera:19
16:46:15.572  Stack Begin  -  Studio
16:46:15.572  Script 'ReplicatedStorage.Wallstick.CharacterModules.Camera', Line 19 - function new  -  Studio - Camera:19
16:46:15.573  Script 'ReplicatedStorage.Wallstick', Line 42 - function new  -  Studio - Wallstick:42
16:46:15.573  Script 'Workspace.Folders.Maps.Spawn.Portals.Tundra.Portal.Teleport', Line 11 - function onTouched  -  Studio - Teleport:11
16:46:15.573  Stack End  -  Studio

Also i think i found a problem with the other download thing that isn’t a rbxl file because i’ve found that the scripts don’t work properly and 2 scripts expects the same file in 2 places.

So i managed to fix the error but now i got a new problem the players just falls right through everything after it
robloxapp-20210216-1150037.wmv (966.3 KB)

EDIT: You don’t have to help anymore i found a solution that sets the wall-stick to None so it doesn’t do it and then do the Set you showed and then i just set the wall-stick to Boots so that it is enabled again and now it works

EDIT2: Now there’s invisible walls instead after teleporting

1 Like

Did you figure this out? I’m having the same issue with vector forces. No movement at all

1 Like

I have made a hacky method for doing this.
I have looked into the code and added a downward force to some of the position updates.
Sorry i cant send the script sadly as it contains some code from my project.

1 Like

I followed the code a little and saw the shadow physics world EgoMoose described. I injected a CustomPhysicsUpdate callback into the wallstick update cycle.

Basically, all the forces I had on my character couldn’t do anything because the normal player humanoid is cframe animated. During the callback, I copy all the forces that were placed on the player character to the wallstick physics character after translating to the object space of the rotated physics character orientation.

It mostly works, but has sent me flying in the wrong direction a couple of times now when moving between states. I will probably have that under control soon.

It works and I can move forward on my game. EgoMoose’s work on the controllers is amazing, but I feel a little uneasy about how much work it takes to accomplish what doesn’t seem like a big ask from the standard character and camera APIs

EgoMoose, thank you so much for this amazing creation. I’m trying to use it wrong, so I’m not surprised it’s not working quite right.

I am replicating a rotated physics force to the wallStick.Physics.HRP, but the result is not quite right.
What I want is something close to wallstick where the character aligns to the surface it is walking on if that surface is below the character’s local upvector.

The force that is sometimes quite wrong comes from this code in my wallstepCustomPhysicsStep function that transforms the VectorForce direction (which is relative to world space) looks like this:

		local playerCFrame = playerGravForce.Attachment0.CFrame
		local localGravVector = playerCFrame:VectorToObjectSpace(playerGravForce.Force)
		local wallstickGravVector = physicsHRP.CFrame:VectorToWorldSpace(localGravVector)
		gravForce.Force = wallstickGravVector

If the translation between the local grav vector and wallstick vector was correct, well… I would always be sent toward the ground.

for context, that function is in one of my modules called by wallstick

local function wallstepCustomPhysicsStep(wallstick)
	local Physics = wallstick.Physics
	local physicsHRP = Physics.HRP
	local gravForce : VectorForce = Physics.PlayerGravForce

	-- some code that removes the VectorForce when it needs cleanup
	(removed for brevity)
	
	if gravForce == nil and physicsHRP then
		print("Creating new sim gravity force for wallstick physics HRP")
		gravForce = attatchVectorForce(physicsHRP, "PlayerGravForce")
		Physics.PlayerGravForce = gravForce
	end
	
	local playerGravForce = AcornClient.PlayerGravForce
	if playerGravForce and gravForce then
		local playerCFrame = playerGravForce.Attachment0.CFrame
		local localGravVector = playerCFrame:VectorToObjectSpace(playerGravForce.Force)
		local wallstickGravVector = physicsHRP.CFrame:VectorToWorldSpace(localGravVector)
		gravForce.Force = wallstickGravVector
	end
end

that is called inside of Wallstick.characterstep

local function characterStep(self, dt)
	local move = self._control:GetMoveVector()
	
	if self.Mode ~= "Debug" then
		-- (code removed for brevity)
		self.Physics.Humanoid:Move(move, false)
	else
		self.Physics.Humanoid:Move(move, true)
	end
	
	-- mgmchenry call to custom physics injection
	if self.CustomPhysicsStep then
		self.CustomPhysicsStep(self)
	end
	
	local physicsHRPCF = self.Physics.HRP.CFrame
	self.HRP.Velocity = self.HRP.CFrame:VectorToWorldSpace(physicsHRPCF:VectorToObjectSpace(self.Physics.HRP.Velocity))
	self.HRP.RotVelocity = self.HRP.CFrame:VectorToWorldSpace(physicsHRPCF:VectorToObjectSpace(self.Physics.HRP.RotVelocity))
end

So, I would have expected that to make the character moving to local gravity correct.
Aligning to local gravity and sticking to the surface normal to local gravity was done like this in the boots tool:

local function raycast()
	local part = isFalling and workspace.Terrain or wallstick.Part--
	local normal = isFalling and Vector3.new(0, 1, 0) or wallstick.Normal

	-- EgoMoose boots seach for a new surface using the current wallstick normal:
	local worldNormal = wallstick.Part.CFrame:VectorToWorldSpace(wallstick.Normal)
	-- But I want to use my local up vector instead.
	local gravNormal = AcornClient.GetPlayerUpVector(wallstick)
	worldNormal = gravNormal
	local result = workspace:Raycast(wallstick.HRP.Position, -getCastHeight() * worldNormal, params)

	if result and result.Instance.CanCollide and not Players:GetPlayerFromCharacter(result.Instance.Parent) then
		part = result.Instance
		normal = part.CFrame:VectorToObjectSpace(result.Normal)
	end

	return part, normal
end

There may have been a method to get the forces into the wallstick physics HRP and maybe that’s where I went wrong.
Any advice?

Sorry I’m not clear exactly what you’re attempting to do here. Could you try explaining differently or maybe attaching a diagram?

I understand that you’re including a force in the physics HRP, but I’m not quite clear what you’re trying to achieve w/ that force?

2 Likes

I have a ring station kind of like an o’neil cylinder with structures on the inside surface of the ring. Workspace gravity is set to zero and each physics assembly in the ring has a VectorForce attached to it’s rootpart that pushes everything toward the “ground”.

The constraint chasis off-road vehicle I made two years ago drives around it just fine without modification. The VectorForce instances operate relative to world space, and while people wouldn’t notice if that vector force wasn’t updated often, to it’s updated every step anyway.

Player characters have a VectorFore aatrached to their HRP, updated by the client.
Without a custom character controller, if you drive to the top/+y side of the ring, when you get out of the vehicle, your character model is pushed +y into the ground.
Your character is now doing a headstand.

I used one of your custom camera controllers to make the camera aware of the current correct UpVector, and that worked great. But still headstand characters.

I swapped the camera for the wallstick controller.

As you know, a VectorForce in the character HRP will do nothing in the wallstick controller. I inserted a line in the wallstick update function to call my fuction that makes sure the wallstick.Physics HRP has a VectorForce attached updated to the correct orientation.

This does work on the bottom/-y side of the ring. Before I added this VectorForce in the wallstick PhysicsWorld, the character model would drift if I jumped off the ground.

If I put wallstick in debug mode, at the -y side of the ring, the VectorForce points -y and keeps the character on the ground. If I reduce gravity to zero and jump, when the character hits the +y side of the ring, the character feet now face the upside down ground as I would hope, but when I turn gravity back on, the character shoots in the wrong direction.

I’ll take some screenshots of the debug world vector force later. When I looked earlier I thought they were ok.

[Edit:I figured it out]
I was using the Attachment CFrame, which is 0 because it’s relative to the parent Part. I changed the code to use the HRP CFrame instead and it’s fine.

		--local playerCFrame = playerGravForce.Attachment0.CFrame
		-- ^^ Incorrect. Attachment CFrame is not the correct point of reference
		-- Use the VectorForce parent, which is the HRP:
		local playerCFrame = playerGravForce.Parent
		local localGravVector = playerCFrame:VectorToObjectSpace(playerGravForce.Force)
		local wallstickGravVector = physicsHRP.CFrame:VectorToWorldSpace(localGravVector)
		gravForce.Force = wallstickGravVector
1 Like

I’m not really too sure if it’s a bug because Roblox broke it or if it was intentional for the shiftlock in the gravity controller to not act the same way as normal shiftlock. The player only seems to move in the direction of the mouse once they’re actually walking instead of the mouse locking their direction at all times. Is there a way to fix this? I’ve only messed around with Camera Modules a bit in the past, could someone help me figure this out? :sweat_smile:

1 Like

That sounds like a bug w/ the controller. Can you specify which controller you’re using and where you got the source from?

3 Likes

I’m currently using the Gravity Controller from https://www.roblox.com/games/4597506405/Gravity-Controller
I also tested shiftlocking directly inside of the game to make sure it wasn’t something I accidently broke and it seemed to occur there too.

2 Likes