Player pushing boat by walking into it


As seen in this video, when I walk into a wall on my boat, it pushes the boat in whichever direction the player is walking.

I’ve tried:

  • Increasing the density of the boat, but that causes it to sink.
  • Using BodyPosition, but this has tons of side effects that aren’t worth it. This includes flinging and unrealistic collisions.
  • Moving the mass of the boat underneath the boat – as I’ve seen in other suggestions. This yielded no results.

Any suggestions on how I can prevent this? I’m hoping to make it so the boat can still be pushed by other boats or even if there’s enough players pushing the boat at once.

Thanks guys.

4 Likes

Honestly I’m pretty stumped on how you would fix that without side effects.

One potential fix I can think of is writing code to set the walkspeed to a low value when the character is standing on the boat and not moving relative to the boat while having a non-zero move direction.

The other would be to increase the density of the boat a lot then add a VectorForce to counter act the extra weight. The buoyancy force is proportional to the amount of water displaced, so if you increase the density then counter the extra gravitational force it would be the same as before (but your boat would have more inertia and be harder to get moving).

3 Likes

Thanks for replying.

I might give that second one a try, as it seems promising. My only concern is that with more inertia, there’s more chance of flinging.

One other thing I might try is doing all my boat movement and physics simulation in one collision group, and all my character collisions in another collision group. That way, I can just have a mesh that acts as the collisions for the boat and set the CFrame of that to be in the right location. Then to keep the player synced with the momentum of the boat, just use a similar system to jailbreak’s train system.

I’ll let you know what I find. Thanks for the help and brainstorming this.

4 Likes

Oh that’s quite clever. I bet that would work!

You could have the mesh be created+updated on each client for it to be very accurate. If you use a AlignPosition + AlignOrientation you could also have the character still “stick” to the boat (if you only use CFrame the character won’t move with the boat when the boat moves).

4 Likes


I tried CFrame and got momentum working on it. However, it was jittery. So I moved to your suggestion of the AlignOrientation and AlignPosition. This works, but seems to be miscalculating the forces applied to the character as seen in the video.

Any suggestions? If not, I’ll just settle for the jittering of CFrame. Thanks!

3 Likes

Got it working!! WOOO :clap:

I ended up going back to CFrame but using your suggestion of rendering the collisions only on the client. Then I used this code to sync momentum:

--BrahGames 07-27-2021 rewritten https://devforum.roblox.com/t/jailbreak-train-platform-system/236339 
--slightly edited to work with bodymovers and such /maxx

local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')

local CheckStates = true
local LastPartCFrame
local LastPart
local Function
local Function2
function CFrameLogic(Raycast, CFramePart)
	--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
	if Raycast.Instance ~= LastPart then
		LastPart = Raycast.Instance
		LastPartCFrame = nil
	end
	local Train = Raycast.Instance
	if LastPartCFrame == nil then -- If no LastTrainCFrame exists, make one!
		LastPartCFrame = Train.CFrame -- This is updated later.
	end
	local TrainCF = Train.CFrame
	local Rel = TrainCF * LastPartCFrame:inverse()
	LastPartCFrame = Train.CFrame -- Updated here.
	CFramePart.CFrame = Rel * CFramePart.CFrame -- Set the player's CFrame
	--print("set")
end
Function = RunService.Heartbeat:Connect(function()
	--------------------------------------------------------------- CHECK PLATFORM BELOW
	-- Build a "RaycastParams" object
	local HumanoidRootPart = player.Character.HumanoidRootPart
	local humanoid = player.Character.Humanoid
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Include
	raycastParams.FilterDescendantsInstances = {game:GetService("CollectionService"):GetTagged("BoatCollisions")}
	raycastParams.IgnoreWater = true
	raycastParams.CollisionGroup = "Default"

	-- Cast the ray
	local Hit = workspace:Raycast(HumanoidRootPart.CFrame.p, Vector3.new(0,-15,0), raycastParams) --Casts a ray facing down
	--------------------------------------------------------------------------------------------
	if Hit then -- Check if the ray hits and if it hits an object inside of MovingObjects
		if CheckStates then -- check if the character is jumping
			local currentState = humanoid:GetState()
			--if currentState  == Enum.HumanoidStateType.Freefall or currentState  == Enum.HumanoidStateType.Jumping or currentState  == Enum.HumanoidStateType.FallingDown then
				CFrameLogic(Hit, HumanoidRootPart)
			--else
				--LastPartCFrame = nil -- Clear the value when the player gets off.
			--end
		else
			CFrameLogic(Hit, HumanoidRootPart)
		end
	else
		LastPartCFrame = nil -- Clear the value when the player gets off.
	end
end)
Function2 = player.Character.Humanoid.Died:Connect(function()
	Function:Disconnect() -- Stop memory leaks
	Function2:Disconnect() -- Stop memory leaks
end)

It’s a slightly modified version of the code from this post.

Thanks so much for your help @BendsSpace.

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.