Custom Character Controller made to learn OOP!

For the past day, I’ve been learning how to use OOP.

I decided, for some reason, the best way I could learn it was by making a custom character controller, so that’s what I did!

Here’s a clip of the current module in action:

Right now, it’s a little jank, primarily in vertical movement. It can easily go up slopes, but can’t climb and can not use stairs, which I’m still trying to solve, but only so much can be expected from only 1 day of development.

Right now, the entire module is only 190 lines of code, and includes the basic features you’d expect from a character controller.

I’d really like to see what you all think of it and get any suggestions for what I should add!

I’m also not entirely sure what I should use this system for at all, so if you’d like to give any ideas, go ahead.


Here’s what the system currently has:

  • Movement for PC only.
  • Jumping
  • Coyote Time (0.15s)
  • Wall detection to avoid “sliding” down walls slowly when jumping into them

(As I’ve said, just the basic stuff)


If you’d like to try it out, you can check it out here!


Planned additions
  • Accel speeds for each direction (so movement isn’t so snappy)
  • Toggles to enable/disable accel speeds (in-case someone doesn’t like slippery movement)
  • Adjustable “slipperiness”
  • Quake-like air movement
  • Making this system use parallel because why the hell not
  • Eventual Open-Sourcing if I can make it good enough to replace Humanoids.

Other Stuff

The entire character model:

Entire code snippet to load and use a character:

local replicatedStorage = game:GetService("ReplicatedStorage")
local characterMain = require(replicatedStorage:WaitForChild("characterMain"))

local rig = replicatedStorage.characterMain:WaitForChild("addCharacter"):InvokeServer()
local character = characterMain.createNewCharacter(rig)

character:setCamera(workspace.CurrentCamera)
character:bindInputs()

character:bindConnection(
	game:GetService("RunService").PreRender:Connect(function(dt: number)
		character:positionCamera(dt)
	end)
)
character:bindConnection(
	game:GetService("RunService").PreSimulation:Connect(function(dt: number)
		character:updateMovement(dt)
		character:Step(dt)
	end)
)
--// And yes, there are methods to fully delete a character, they just aren't in use here.

And why am I making this? The answer is simple. I don’t like Humanoids.


Thanks for reading!

4 Likes

nice! you should add spacebar-holding to control your jumps, like the Super Mario games.

4 Likes