I’m trying to make a tool place a Liferaft on Roblox terrain water. Pretty much what kni0002 does in his sinking ship simulator. I have an idea on what I have to not, but I’m not sure how to do it. So my idea is to clone the Liferaft (a model named Liferaft) from ServerStorage and place it where the mouse cursor is. But here’s the hard part. The Liferaft should not go below Roblox terrain water (as it’s supposed to float) and the Liferaft has to be removed on the player placing it death. How do I make this? I’m a terrible scripter and want to learn so please include examples and explanations.
Thanks in advance.
This is going to be a really simple solution and might bring up more problems, but you could probably use a body position to get you up to the correct position. First off, if you wanted to do this, you have to change the max force to where only the Y axis is affected, and X and Z don’t have a force. You would do this by changing the max force to Vector3.new(0,force,0) (force being the strength) Now, you have to get the Y axis of the surface of the water, by using a part for reference and getting the height. Now, you should get the position of it and insert it into the body position’s position. Now, put the body position into the generated raft. If you’ve done this right, you should get a life raft that moves you up onto the top of the water if you got the position correctly.
This is what it should act like. (The part is supposed to be the raft)
As for deleting it on death, I would add a creator object value to the raft, set it to the player who created it through the value, and get the player’s humanoid’s Died event. Heres an example:
“raft” will be the raft the player created. “creator” will be the object value for the raft’s creator.
Using Raycasting we can find the position of the terrain water’s surface from the mouse’s current position. to find what the ray has hit, we use the workspace:FindPartOnRay() funtion. it returns a number of values, one of which is the material, which we can use to make sure the mouse is over water. We can make sure that the ray does not ignore water via the fourth argument parameter, which we will set to true.
Heres a code example:
localscript inside tool:
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local tool = (example tool)
local range = 50 -- how far away we can place raft
local ray = Ray.new(tool.Handle.Position, (mouse.Hit.p - tool.Handle.Position).Unit*range) -- cast the ray
local hit, position, surfacenormal, material = workspace:FindPartOnRay(ray, player.Character, false, false) -- find the part or terrain that it hit, and get the position
if hit then
if material = Enum.Material.Water then -- check if we hit water
tool.PlaceRaft:FireServer(position) -- ask server to create raft
server script inside tool:
local tool = script.Parent
local event = tool:WaitForChild("PlaceRaft") -- a RemoteEvent inside the tool
event.OnServerEvent:Connect(function(player, position) -- create raft on server when client tells it to
local raft = game.ReplicatedStorage.Raft:Clone()
raft:SetPrimaryPartCFrame(CFrame.new(position)) -- place raft at position
raft.Parent = workspace
This code will cast a ray from the tool’s position to the mouse’s position, check for terrain water, and send the position to the server so that the server can create the raft and put it in the position.
RemoteEvents are good for this since they send data from the client to the server.
(the mouse position is only found on the client, thats why we need to use a RemoteEvent to send the data)
If you end up using this code, don’t forget to add extra security to the remote, as an exploiter could easily spam this remote and create infinite rafts at will. You could check if the player hasnt made a raft already, and to create it if they haven’t. If they do have a raft, then just ignore the remote call.
Right, it definitely could use more security.
The code examples were only to show the concept of placing the raft from a tool via rays and remotes.
heres some security checks I can think of:
you could have a server variable for the player’s currently spawned rafts, and check if the amount is too high.
on the server, check the magnitude between the tool and the position to make sure they arent placing it farther than they should be.
implement a server cooldown, to make sure they arent spam placing/ spam removing their rafts.
After looking at the suggestions and after getting some help from someone in Hidden Developers I managed to find a solution. I will not provide the raw scripts due the fact I’ll be using it in my game but I’ll tell how I did it for anyone interested.
Inside the tool itself there’s a local script. The local script checks if the mouse.Target is pointed at water (Enum.Material.Water). If it is and the person use the left mouse button then the local script will fire a remote event providing the mouse.Target position. The life raft is then cloned from ServerStorage to said position. I also considered @ndrwcswll feedback on security and implemented a max spawn distance and a max rafts at a time (one). I also remove the raft once the character leaves, respawns or dies (CharacterRemoving). While @OsterDog didn’t give me a suggestion on how to spawn the life raft he did give me an idea on how to keep the life raft floating correctly.