You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Quake movement
-
What is the issue? Character instantly dies and wont respawn
-
What solutions have you tried so far? Trying to dig into the code to find what would cause it
Attempted port of https://github.com/WiggleWizard/quake3-movement-unity3d/blob/master/CPMPlayer.cs
--Movement stuff
local friction = 6;
local gravity = 20
local moveSpeed = 7.0; -- Ground move speed
local runAcceleration = 14.0; -- Ground accel
local runDeacceleration = 10.0; -- Deacceleration that occurs when running on the ground
local airAcceleration = 2.0; -- Air accel
local airDecceleration = 2.0; -- Deacceleration experienced when ooposite strafing
local airControl = 0.3; -- How precise air control is
local sideStrafeAcceleration = 50.0; -- How fast acceleration occurs to get up to sideStrafeSpeed when
local sideStrafeSpeed = 1.0; -- What the max speed to generate when side strafing
local jumpSpeed = 8.0; -- The speed at which the character's up axis gains when hitting jump
local holdJumpToBhop = false;
local grounded = true
local playerVelocity = Vector3.zero;
local playerFriction = 0
local moveDirectionNorm = Vector3.zero;
local wishJump = false;
local _cmd = {
forwardMove = 0,
rightMove = 0,
upMove = 0
}
local dt = 0
local function getAxisVert()
local move = 0
move = move + (userInputService:IsKeyDown(Enum.KeyCode.W) and 1 or 0)
move = move - (userInputService:IsKeyDown(Enum.KeyCode.S) and 1 or 0)
return move
end
local function getAxisHoriz()
local move = 0
move = move - (userInputService:IsKeyDown(Enum.KeyCode.A) and 1 or 0)
move = move + (userInputService:IsKeyDown(Enum.KeyCode.D) and 1 or 0)
return move
end
local function SetMovementDir()
_cmd.forwardMove = getAxisVert()
_cmd.rightMove = getAxisHoriz()
end
local function QueueJump()
if (userInputService:IsKeyDown(Enum.KeyCode.Space) and not wishJump) then
wishJump = true
end
if not (userInputService:IsKeyDown(Enum.KeyCode.Space)) then
wishJump = false
end
end
local function Accelerate(wishdir , wishspeed , accel )
local addspeed = 0;
local accelspeed = 0;
local currentspeed = 0;
currentspeed = fix(playerVelocity:Dot(wishdir))
addspeed = fix(wishspeed - currentspeed)
if(addspeed <= 0) then
return;
end
accelspeed = fix(accel * dt * wishspeed);
if(accelspeed > addspeed) then
accelspeed = fix(addspeed);
end
playerVelocity = Vector3.new(playerVelocity.X + accelspeed * wishdir.X, 0 ,playerVelocity.Z + accelspeed * wishdir.Z)
end
local function AirControl(wishdir , wishspeed )
local zspeed;
local speed;
local dot;
local k;
-- Can't control movement if not moving forward or backward
if(math.abs(_cmd.forwardMove) < 0.001 and math.abs(wishspeed) < 0.001) then
return;
end
zspeed = playerVelocity.Y;
playerVelocity *= Vector3.new(1,0,1)
-- Next two lines are equivalent to idTech's VectorNormalize() */
speed = playerVelocity.magnitude;
playerVelocity = playerVelocity.Unit;
dot = playerVelocity:Dot(wishdir);
k = 32;
k *= airControl * dot * dot * dt;
-- Change direction while slowing down
if (dot > 0) then
playerVelocity = Vector3.new(playerVelocity.X * speed + wishdir.X * k, playerVelocity.Y * speed + wishdir.Y * k, playerVelocity.Z * speed + wishdir.Z * k)
playerVelocity = playerVelocity.Unit;
moveDirectionNorm = playerVelocity;
end
playerVelocity = Vector3.new(playerVelocity.X * speed, zspeed, playerVelocity.Z * speed)
end
local function AirMove()
local wishdir = Vector3.zero
local accel = 0
SetMovementDir()
wishdir = Vector3.new(_cmd.rightMove,0, _cmd.forwardMove)
local wishspeed = wishdir.Magnitude;
wishspeed *= moveSpeed
wishdir = wishdir.Unit
moveDirectionNorm = wishdir
local wishspeed2 = wishspeed;
if playerVelocity:Dot(wishdir) < 0 then
accel = airDecceleration;
else
accel = airAcceleration;
end
if(_cmd.forwardMove == 0 and _cmd.rightMove ~= 0) then
if(wishspeed > sideStrafeSpeed) then
wishspeed = sideStrafeSpeed;
end
accel = sideStrafeAcceleration;
end
Accelerate(wishdir, wishspeed, accel)
if(airControl > 0) then
AirControl(wishdir, wishspeed2);
end
playerVelocity += Vector3.new(0, gravity * dt, 0)
end
local function ApplyFriction(t)
local vec = playerVelocity; -- Equivalent to: VectorCopy();
local speed;
local newspeed;
local control;
local drop;
vec *= Vector3.new(1,0,1)
speed = vec.magnitude;
drop = 0.0;
-- Only if the player is on the ground then apply friction */
if(grounded) then
control = speed < runDeacceleration and runDeacceleration or speed
drop = control * friction * dt * t;
end
newspeed = speed - drop;
playerFriction = newspeed;
if(newspeed < 0) then
newspeed = 0;
end
if(speed > 0) then
newspeed /= speed;
end
playerVelocity = Vector3.new(playerVelocity.X * newspeed, playerVelocity.Y,playerVelocity.Z * newspeed)
end
local function GroundMove()
local wishdir = Vector3.zero
-- Do not apply friction if the player is queueing up the next jump
if (not wishJump) then
ApplyFriction(1.0);
else
ApplyFriction(0);
end
SetMovementDir();
wishdir = Vector3.new (_cmd.rightMove, 0, _cmd.forwardMove);
--wishdir = transform.TransformDirection(wishdir);
wishdir = wishdir.Unit;
moveDirectionNorm = wishdir;
local wishspeed = wishdir.Magnitude;
wishspeed *= moveSpeed;
Accelerate(wishdir, wishspeed, runAcceleration);
-- Reset the gravity velocity
playerVelocity = Vector3.new(playerVelocity.X, -gravity * dt, playerVelocity.Z)
if (wishJump) then
playerVelocity = Vector3.new(playerVelocity.X, jumpSpeed, playerVelocity.Z)
wishJump = false;
end
end
local endTime = os.clock()
local startTime = os.clock()
function update()
dt = math.abs(endTime-startTime)
QueueJump()
if (grounded) then
GroundMove()
elseif (not grounded) then
AirMove()
end
p.Character.Humanoid:Move(playerVelocity)
end
runservice.Stepped:Connect(function()
startTime = os.clock()
if p.Character and p.Character:FindFirstChild("Humanoid") then
grounded = not (p.Character.Humanoid.FloorMaterial == Enum.Material.Air)
update()
end
endTime = os.clock()
end)
Adding on to this, when relativeToCamera is set to true it doesnt die and it just gets stuck at the negative 32bit integer limit