I want to implement custom characters + movement for a game.
- The camera - not the player - keeps glitching backwards when the player is rotated.
- There is a small delay on input and when the player moves. Why?
I have identified the problematic line. The majority of code is in two scripts:
One Local Script:
--Consts
local MAX_SPEED = 20
local ACCELERATION = 1
local FD_ACTION = "Forward"
local BD_ACTION = "Backward"
local LT_ACTION = "Left"
local RT_ACTION = "Right"
--Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
--Locals
local player = Players.LocalPlayer
local character = workspace.Players:WaitForChild(player.Name)
local humanoid = character:WaitForChild("Humanoid")
local camera = workspace.Camera
local velocity = Vector3.zero
local armModel = game.ReplicatedStorage.Assets.Character.__ARM_MODEL__:Clone()
repeat wait() until player.Character
local shirt = player.Character:FindFirstChildWhichIsA("Shirt"):Clone()
camera:GetPropertyChangedSignal("CFrame"):Connect(function()
local pitchX, pitchY, pitchZ = camera.CFrame:ToOrientation()
game.ReplicatedStorage.Remotes.CameraChanged:FireServer(pitchX, pitchY, camera.CFrame.Position)
armModel:PivotTo(CFrame.new(camera.CFrame.Position) * CFrame.Angles(0,pitchY, 0))
end)
RunService.Heartbeat:Connect(function(dTime)
local keysDown = UserInputService:GetKeysPressed()
for i,v in pairs(keysDown) do
keysDown[i] = v.KeyCode
end
velocity = Vector3.zero
if table.find(keysDown, Enum.KeyCode.W) then
velocity -= Vector3.zAxis
end
if table.find(keysDown, Enum.KeyCode.A) then
velocity -= Vector3.xAxis
end
if table.find(keysDown, Enum.KeyCode.S) then
velocity += Vector3.zAxis
end
if table.find(keysDown, Enum.KeyCode.D) then
velocity += Vector3.xAxis
end
velocity = velocity.Unit
humanoid:Move(velocity, true)
end)
armModel.Parent = workspace
shirt.Parent = armModel
And one server side script:
--Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local InsertService = game:GetService("InsertService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
--Consts
local DEFAULT_CHARACTER = {13902494655, 13902489990, 13901896422, 13901862002} --pants, shirt, hair, face. Face and hair must be a model.
local BASE_CHARACTER_MODEL = ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Character"):WaitForChild("__DEFAULT__")
local CHARACTER_DATASTORE_KEY = "AashesGame0_Characters_76b5h"
--Locals
local characters = {}
local inventoryDatastore = DataStoreService:GetDataStore(CHARACTER_DATASTORE_KEY)
function GetCharacter(player)
local success, character = pcall(function()
return inventoryDatastore:GetAsync(player)
end)
if success and character then
return character
else
return DEFAULT_CHARACTER
end
end
function LoadCharacter(charInfo, player)
local char = BASE_CHARACTER_MODEL:Clone()
char:TranslateBy(Vector3.new(4,0,0))
char.Parent = workspace.Players
char.Name = player
local charFolder = ReplicatedStorage:WaitForChild("Assets"):WaitForChild("Character")
charFolder:WaitForChild("Pants"):FindFirstChild(charInfo[1]):Clone().Parent = char
charFolder:WaitForChild("Shirts"):FindFirstChild(charInfo[2]):Clone().Parent = char
charFolder:WaitForChild("Hair"):FindFirstChild(charInfo[3]):Clone().Parent = char
charFolder:WaitForChild("Face"):FindFirstChild(charInfo[4]):Clone().Parent = char
return char
end
Players.PlayerAdded:Connect(function(player)
local charInfo = GetCharacter(player.Name)
local charObj = LoadCharacter(charInfo, player.Name)
for i,v in pairs(charObj:GetChildren()) do
if v:IsA("BasePart") then
v:SetNetworkOwnershipAuto(false)
v:SetNetworkOwner(player)
end
end
player.CharacterAdded:Connect(function(char)
if not char.Parent then
char:Destroy()
end
player.Character = charObj
ReplicatedStorage.Remotes.ChangePlayerCharacter:FireClient(player)
end)
end)
ReplicatedStorage.Remotes.CameraChanged.OnServerEvent:Connect(function(player, pitchX, pitchY)
local char = workspace.Players:FindFirstChild(player.Name)
if char then
char.Head.Neck.C0 = CFrame.new(char.Head.Neck.C0.Position) * CFrame.Angles(pitchX, 0, 0)
char.HumanoidRootPart.CFrame = CFrame.new(char.HumanoidRootPart.CFrame.Position) * CFrame.Angles(0, pitchY, 0)
end
end)
The camera issue:
The player only glitches when it is pointed diagonally, not forwards, backwards or side to side. It always glitches if I move the camera while the player is moving
