I’ve been trying to script a horse that you can call, mount, and ride around, but I’ve been experiencing multiple problems while doing this.
(This horse model is just a dummy to give me some visual help for when I add the scripts to the proper one. I do not usually build like this xD)
Ideally I would like the horse to be a humanoid you can ride, so what I did was attach a function to a key to spawn in a horse, another one for mounting/dismounting the horse and one for despawning it after too much time has passed. This is the server side script code that does all of the above:
local players = game:GetService('Players')
local replicatedStorage = game:GetService('ReplicatedStorage')
local callFunction = Instance.new('RemoteFunction',replicatedStorage)
callFunction.Name = 'CallFunction'
local mountEvent = Instance.new('RemoteEvent',replicatedStorage)
mountEvent.Name = 'MountEvent'
local despawnEvent = Instance.new('RemoteEvent',replicatedStorage)
despawnEvent.Name = 'DespawnEvent'
local function call(player, horse)
if horse == nil then
local horse = replicatedStorage:WaitForChild('Horse'):Clone()
horse.Parent = workspace
horse:SetPrimaryPartCFrame(player.Character:WaitForChild('HumanoidRootPart').CFrame*CFrame.new(20,0,0))
horse:WaitForChild('Humanoid'):MoveTo(player.Character:WaitForChild('HumanoidRootPart').Position + Vector3.new(6,0,0))
players.PlayerRemoving:Connect(function(plr)
if plr.Name == player.Name then
horse:Destroy()
end
end)
player.Character:WaitForChild('Humanoid').Died:Connect(function()
horse:Destroy()
end)
return horse
else
horse:SetPrimaryPartCFrame(player.Character:WaitForChild('HumanoidRootPart').CFrame*CFrame.new(20,0,0))
horse:WaitForChild('Humanoid'):MoveTo(player.Character:WaitForChild('HumanoidRootPart').Position + Vector3.new(6,0,0))
return horse
end
end
callFunction.OnServerInvoke = call
despawnEvent.OnServerEvent:Connect(function(player, horse)
horse:Destroy()
end)
mountEvent.OnServerEvent:Connect(function(player, horse, isOn)
if horse ~= nil then
local playerHRP = player.Character:WaitForChild('HumanoidRootPart')
local horseHRP = horse.HumanoidRootPart
if isOn == false then
playerHRP.Anchored = true
horseHRP.Anchored = true
playerHRP.CFrame = horseHRP.CFrame * CFrame.new(0,2.5,0)
local weld = Instance.new('WeldConstraint',playerHRP)
weld.Name = 'HorseWeld'
weld.Part0 = horseHRP
weld.Part1 = playerHRP
playerHRP.Anchored = false
horseHRP.Anchored = false
else
local weld = playerHRP:WaitForChild('HorseWeld'):Destroy()
playerHRP.CFrame = horseHRP.CFrame * CFrame.new(7,0,0)
end
end
end)
However, all the horse movement and features I want to implement such as walking on uneven terrain, jumping, etc. I can’t really figure out, and I’m not sure whether all that should be within the player’s local script or not. I’m currently disabling the player controller script when mounted and assigning new functions to WASD, Shift (to gallop) and Space (to jump).
For the W and S keys I’m using the Humanoid:Move(Vector3.new(0,0,-1, true) command to have the horse move forward and backwards when the respective keys are pressed, and this works fine. However, I’d like to make it so if you only hold down either the A or D keys, the horse rotates indefinitely, without going forward until you let go (constant rotation), but after using both BodyVelocity and BodyGyro, I’ve experienced no success, unless I rotate my camera and press W again. Humanoid.Jump does not work either, while shift to gallop does.
Lastly, I want to make the horse be able to adjust itself on uneven terrain, so it doesn’t just walk on flat ground. I have no idea how to do this and would really appreciate some suggestions.
Thank you very much for reading, and I hope you can help me in this endeavour!