Completely rewritten player movement and camera control system, without physics

(If anyone knows any better ways to upload videos I’d appreciate it)

I have completely removed the default roblox player and rescripted all movement and camera stuff. Not only does this make it so that your camera rotates with your body on rotating platforms, but also allows you to walk on walls and roofs!
This is still very WIP so I can’t make it open source yet :‎(

You can upload it to https://streamable.com

would it show up as just a link or a video frame?

it should yeah

Character limit was reached (ignore)

okay, I’ll try it soon

…character limit lol

yoooo this is sick, i’d be interested to know a little more on how this actually works. consider adding a little insight into how you made this?

and whats going on lol

1 Like

Okay… Here’s the code in the localscript:

RS = game:GetService("RunService")
UIS = game:GetService("UserInputService")
UGS = UserSettings():GetService("UserGameSettings")

Player = game.Workspace:WaitForChild("Player")

Camera = game.Workspace.CurrentCamera
Camera.CameraType = Enum.CameraType.Scriptable
Camera.CameraSubject = Player

MoveSpeed = 0.3

local xRot = 0
local yRot = 0

local rx,ry,rz

RS.PreRender:Connect(function()
	if game.ReplicatedStorage.CameraMode.Value == 0 then
		UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
		UIS.MouseIconEnabled = true
		local delta = UIS:GetMouseDelta()
		yRot -= delta.Y
		yRot = math.clamp(yRot,-80,80)
		xRot -= delta.X
		Player.CFrame = Player.CFrame * CFrame.Angles(0,-math.rad(delta.X),0)
		local NewCFrame = CFrame.new()
		rx, ry, rz =  Player.CFrame:ToOrientation()
		NewCFrame = NewCFrame * CFrame.Angles(math.rad(yRot),0,0)
		Camera.CFrame = Player.CFrame:ToWorldSpace(NewCFrame)
	elseif game.ReplicatedStorage.CameraMode.Value == 1 then
		UIS.MouseBehavior = Enum.MouseBehavior.Default
		UIS.MouseIconEnabled = true
	else
		UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
		UIS.MouseIconEnabled = false
	end
end)

local FloorCollisionRayParams = RaycastParams.new()
FloorCollisionRayParams.IgnoreWater = true
FloorCollisionRayParams.RespectCanCollide = true
FloorCollisionRayParams.FilterType = Enum.RaycastFilterType.Exclude
FloorCollisionRayParams.FilterDescendantsInstances = {Player}

local LastCollisionPart:Instance
local LastCollisionCFrame:CFrame
local rayresult
RS.Heartbeat:Connect(function()
	if game.ReplicatedStorage.CameraMode.Value ~= 0 then return end
	local MoveCFrame
	MoveCFrame = Player.CFrame.Rotation
	local FloorCollisionRayDir = Player.CFrame.UpVector * -30
	rayresult = game.Workspace:Raycast(Player.Position,FloorCollisionRayDir)
	if rayresult and LastCollisionPart == rayresult.Instance then
		if LastCollisionCFrame ~= rayresult.Instance.CFrame then
			local Rel = LastCollisionCFrame:ToObjectSpace(Player.CFrame)
			Player.CFrame = rayresult.Instance.CFrame:ToWorldSpace(Rel)
		else
			local IntersectionPoint = rayresult.Position
			Player.Position = IntersectionPoint + Player.CFrame.UpVector*Player.Size.Y/2
		end
	end
	if UIS:IsKeyDown(Enum.KeyCode.LeftShift) then
		MoveSpeed = 0.5
	else
		MoveSpeed = 0.3
	end
	local Grounded = not not rayresult -- Weird lua stuff ;)
	if UIS:IsKeyDown(Enum.KeyCode.W) and Grounded then
		Player.CFrame = Player.CFrame + MoveCFrame.LookVector * MoveSpeed
	end
	if UIS:IsKeyDown(Enum.KeyCode.S) and Grounded then
		Player.CFrame = Player.CFrame + MoveCFrame.LookVector * -MoveSpeed
	end
	if UIS:IsKeyDown(Enum.KeyCode.D) and Grounded then
		Player.CFrame = Player.CFrame + MoveCFrame.RightVector * MoveSpeed
	end
	if UIS:IsKeyDown(Enum.KeyCode.A) and Grounded then
		Player.CFrame = Player.CFrame + MoveCFrame.RightVector * -MoveSpeed
	end
	rayresult = game.Workspace:Raycast(Player.Position,FloorCollisionRayDir)
	if rayresult then
		LastCollisionPart = rayresult.Instance
		LastCollisionCFrame = rayresult.Instance.CFrame
	else

	end
end)

Note that CharacterAutoLoads is also turned off for this.
First, we just do the basic setup stuff like defining variables etc.
Next, we make a function that will run before each frame is drawn on the screen (PreRender).
In the script, we:

  • Check if the CameraMode value is 0, which is used for making cutscenes etc.
  • We then do some cursor setup to set it to the correct configuration.
  • We then get the Mouse Delta and subtract the Xrot and Yrot values by the respective Delta Values. (xRot isn’t actually needed anywhere, its just a remenant of some old code.) We also clamp the yRot value from -80 to 80.
  • We then rotate the player’s Y axis by the math.rad of the mouse delta.
  • Just ignore the next two lines, again remenants of other stuff :confused:
  • We then make a CFrame that is just the yRot and nothing else (its in the X position of the CFrame because of how CFrames work.)
  • We finally set the camera’s CFrame to the player’s CFrame multiplied by the CFrame we made in the previous step.

That was the camera function. By the way, I apologise if any of this code is messy, I was practically having an emotional breakdown trying to make this, look at my recent posts D:

I’m quite busy right now so I might be able to tell you how the movement script works later, but not right now, sorry. Also, there isn’t wall collision yet, I’m working on it though.

Thank you for having a look at this by the way :Dㅤ

1 Like

Also, even though its not complete, I can try to give the file to you so you can have a more detailed look if you want, I can send you the game link so you can copy it