Horse not working properly

Hello there,

I have this error in this custom horse my friend gave me, which works in test mode but has an error when I play the game. If anyone knows how to fix this problem, please let me know. Any help is greatly appreciated.

The Error

image
image

What the Error does

image

What it should do

image

The Script

local player = game.Players.LocalPlayer
local Camera = game.Workspace.CurrentCamera
local mouse = player:GetMouse()
local running = true

local InputService = game:GetService("UserInputService")
local keysDown = {}


InputService.InputBegan:connect(function(input,processed)
	if processed then return end
	
	keysDown[input.KeyCode] = true
end)

InputService.InputEnded:connect(function(input,processed)
	if processed then return end
	
	keysDown[input.KeyCode] = false
end)


--Where it begins
local UIS = game:GetService("UserInputService")
local Key = Enum.KeyCode.F

UIS.InputBegan:connect(function(Input,GPE)
    if not GPE then
        if Input.KeyCode == Key then
	if player.Character:FindFirstChild("HumanoidRootPart") ~= nil then
		local target = mouse.Target
		if target and (mouse.Hit.p-player.Character.HumanoidRootPart.Position).magnitude < 10 and mouse.Target.Parent.Name == "BrownHorse" or "WhiteHorse" or "BuckskinHorse" or "GreyHorse" or "BlackHorse" or "ChesnutHorse" then
			game.ReplicatedStorage.Events.Mount:InvokeServer(mouse.Target.Parent)
		end
			end
end
end
end)



----------------------------------------------------------------------------

while wait() do
	player.PlayerScripts.ControlScript.Disabled = player.Horse.Value ~= nil
	
	if player.Horse.Value then -- Horse Control
		player.Character.Humanoid.AutoRotate = false
		local horse = player.Horse.Value
		local settings = require(game.ReplicatedStorage.HorseSettings)
		local gait = 1
		local oldgait = 0
		local rotate = 0
		
		local x, y, z = horse.HumanoidRootPart.CFrame:toEulerAnglesXYZ()
		
		if math.abs(z) > 0.1 then
			y = -y
		else
			y = math.pi+y
		end
		
		local gaitDebounce = false
		local sitAnim = player.Character.Humanoid:LoadAnimation(game.ReplicatedStorage.Animations.HorseSit)
		sitAnim:Play()
		
		while player.Horse.Value and player.Horse.Value:FindFirstChild("HumanoidRootPart") do
			
			if gait ~= oldgait then -- Horse animations
				oldgait = gait
				if gait == 1 then
					spawn(function()
						game.ReplicatedStorage.Events.Animate:InvokeServer(game.ReplicatedStorage.Animations.HorseBreath,horse)
						for i = 0, 2, 1/30 do
								wait()
								if not player.Horse.Value then return end
							end
						while wait() and gait == 1 and player.Horse.Value do
							local a
							local list = {}
							
							for i, k in ipairs(settings.IdleAnimations) do
								for j = 1, k.Weight do
									list[i+j-1] = k
								end
							end
							
							local a = list[math.random(1,#list)]
							
							game.ReplicatedStorage.Events.Animate:InvokeServer(a.Anim,horse)
							
							for i = 0, a.Length, 1/30 do
								wait()
								if not player.Horse.Value then return end
							end
						end
					end)
				else
					local a = settings.Gaits[gait].Animation
					game.ReplicatedStorage.Events.Animate:InvokeServer(a,horse)
				end
			end
			
			local speed = settings.Gaits[gait].Speed
			
			if keysDown[Enum.KeyCode.A] then
				rotate = math.min(rotate + 6/speed,60/speed)
			elseif keysDown[Enum.KeyCode.D] then
				rotate = math.max(rotate - 6/speed,-60/speed)
			elseif rotate ~= 0 then
				if math.abs(rotate) < 0.2 then
					rotate = 0
				else
					rotate = (math.abs(rotate) - 6/speed) * rotate/math.abs(rotate)
				end
			end
			if keysDown[Enum.KeyCode.W] and not gaitDebounce then
				gait = math.min(gait + 1,#settings.Gaits)
				gaitDebounce = true
				spawn(function()
					wait(0.3)
					repeat wait() until not keysDown[Enum.KeyCode.W]
					gaitDebounce = false
				end)
			end
			if keysDown[Enum.KeyCode.S] and not gaitDebounce then
				gait = math.max(gait - 1,1)
				gaitDebounce = true
				spawn(function()
					wait(0.8)
					repeat wait() until not keysDown[Enum.KeyCode.S]
					gaitDebounce = false
				end)
			end
			
			if speed < 1 then
				rotate = 0
			end
			
			y = y + math.rad(rotate)
			
			speed = (settings.Gaits[gait].Speed*15) / (15+math.abs(rotate))
			
			if gait >= 3 then
				speed = speed * horse.Speed.Value
			end
			
			speed = (speed + horse.HumanoidRootPart.BodyVelocity.Velocity.magnitude*9)/10
			
			local dir =(CFrame.Angles(0,y,0)*CFrame.new(0,0,1)).p
			
			horse.HumanoidRootPart.BodyVelocity.Velocity = dir * speed
			horse.HumanoidRootPart.CFrame = CFrame.new(Vector3.new(),dir) + horse.HumanoidRootPart.Position
			
			
			wait()
		end
		
		sitAnim:Stop()
		player.Character.Humanoid.AutoRotate = true
	end
end
2 Likes

Are you sure this is the right script? I checked line 34 and it seems like it’d be the Server script returning the error. Do you think you could post the OnServerInvoke function here?

3 Likes
game.Players.PlayerAdded:connect(function(player)
	local horse = Instance.new("ObjectValue",player)
	horse.Name = "Horse"
	local folder = Instance.new("Folder",player)
	folder.Name = "Horses"
	
	player.CharacterAdded:connect(function(char)
		char.Humanoid.Died:connect(function()
			if horse:IsA("ObjectValue") and horse.Value then
				horse = horse.Value
				player.Horse.Value = nil
				
				for _, k in pairs(horse.Humanoid:GetPlayingAnimationTracks()) do
					k:Stop()
				end
				
				wait()
				player.Character.HumanoidRootPart.CFrame = horse.HumanoidRootPart.CFrame * CFrame.new(2.5,0,0) * CFrame.Angles(0,math.pi/2,0)
				setHorseNetworkOwnership('Auto', horse)
				horse.HumanoidRootPart.Anchored = true
			end
		end)
	end)
end)
	

function setHorseNetworkOwnership(player, horse)
	for i,v in ipairs(horse:children()) do
		if v:IsA'BasePart' and v.Anchored == false then
			if player == 'Auto' then
				v:SetNetworkOwnershipAuto()
			else
				if v.Anchored == false then
					v:SetNetworkOwner(player)
				end
			end
		end
	end
end

game.ReplicatedStorage.Events.Animate.OnServerInvoke = function(player,anim,horse)
	if horse:FindFirstChild("Humanoid") == nil then return end
	setHorseNetworkOwnership(nil, horse)
	for _, k in pairs(horse.Humanoid:GetPlayingAnimationTracks()) do
		k:Stop()
		k:Destroy()
	end
	if anim then
		local a = horse.Humanoid:LoadAnimation(anim)
		a:Play()
		a.KeyframeReached:connect(function(name)
			if name == "Step" then
				local sound = Instance.new("Sound",horse.HumanoidRootPart)
				sound.SoundId = "rbxassetid://362849763"
				if anim.Name == "HorseWalk" then
					sound.Volume = 0.1
				else
					sound.Volume = 0.4
				end
				sound.Pitch = 0.8
				sound:Play()
				game.Debris:AddItem(sound,1)
			end
		end)
	end
	setHorseNetworkOwnership(player, horse)
end

function getMounted(horse)
	for _, k in pairs(game.Players:GetPlayers()) do
		if k.Horse.Value == horse then
			return k
		end
	end
end

function dismount(player)
	local horse = player.Horse.Value
	player.Horse.Value = nil
	if horse:FindFirstChild("Saddle") == nil then
		return 
	end
	if horse.Saddle:FindFirstChild("Weld") ~= nil then
		horse.Saddle.Weld:Destroy()
	end
	for _, k in pairs(horse.Humanoid:GetPlayingAnimationTracks()) do
		k:Stop()
	end
	
	wait()
	player.Character.HumanoidRootPart.CFrame = horse.HumanoidRootPart.CFrame * CFrame.new(2.5,0,0) * CFrame.Angles(0,math.pi/2,0)
	setHorseNetworkOwnership('Auto', horse)
	horse.HumanoidRootPart.Anchored = true
end

game.ReplicatedStorage.Events.Mount.OnServerInvoke = function(player,horse)
	if horse and player:DistanceFromCharacter(horse.Torso.Position) < 14 and not getMounted(horse) then
		horse.HumanoidRootPart.Anchored = false
		setHorseNetworkOwnership(nil, horse)
		local weld = Instance.new("Weld",horse.Saddle)
		weld.Part0 = horse.Saddle
		weld.Part1 = player.Character.HumanoidRootPart
		weld.C0 = CFrame.Angles(0,-math.pi/2,0) * CFrame.new(0,1,0)
		
		player.Horse.Value = horse
		
		setHorseNetworkOwnership(player, horse)
	elseif player.Horse.Value then
		dismount(player)
	end
end



This is the server script
1 Like

Here’s the error (from the local script):

if target and (mouse.Hit.p-player.Character.HumanoidRootPart.Position).magnitude < 10 and mouse.Target.Parent.Name == "BrownHorse" or "WhiteHorse" or "BuckskinHorse" or "GreyHorse" or "BlackHorse" or "ChesnutHorse" then

That’s a long line, you should really try to avoid that. Anyways, the problem comes from checking the name. With conditional statements, anything that’s not (nil or false) is treated as true.

local x = 5
local y = nil

if x then
	print("This was true!") -- prints
end

if y then
	print("This was true!") -- doesn't print
end

Now, the name check can be rewritten as follows:

(mouse.Target.Parent.Name == "BrownHorse") or "WhiteHorse" or "BuckskinHorse" or "GreyHorse" or "BlackHorse" or "ChesnutHorse"

From that, it becomes clear that each or is a seperate case. As described above, anything that’s not nil or false will become true. So, it practically evaluates to:

(mouse.Target.Parent.Name == "BrownHorse") or true or true or true or true or true

You could come up with a few solutions, I’ll post two (hope there is no errors).

local horseNames = {
	BrownHorse = true,
	WhiteHorse = true,
	BuckskinHorse = true,
	GreyHorse = true,
	BlackHorse = true,
	ChesnutHorse = true
}

local name = mouse.Target.Parent.Name

if horseNames[name] then
	print("This is a valid name!")
end

--------------------------

local name = mouse.Target.Parent.Name

if name:find("Horse") then
	print("This is a valid name!")
end

Solution one has the benifit of you know what should be sent, the problem is if you add more horses you’ll have to add the new names manually.

Solution two would automatically do this for you, but you might run into naming issues.

Finally, you should always check what was sent to the server. Here it’s not a problem, it’d just throw an error and the game will run fine. Sometimes this is not the case.

3 Likes

Thanks! I am going to try this right now.

1 Like