hello, im making a fast pace movement game and im wondering how i would make this " door break while sliding " thing
maybe whiles sliding in renderstepped detect player boundingbox in front and see if any parts are door if so fire remotevent to break them
May I ask what game this is?
Anyhow my guess is that when sliding they activate some kind of hitbox like a raycast or something, if it hits a door, well depending on how the door was made they:
- A: Destroy any welds or attachments connecting it to the wall and apply some kind of force to it
- B: They unanchored the door and apply some kind of force to it
- C: They call upon the power of maxwell and annihilate the door with his cuteness.
I hope this helps!
~ Frodev
A couple of ways:
Have a hitbox on the door and if the Touched event fires check to see if the player is sliding. If so then delete the door, or have it CFramed to an ‘open’ position for more realism.
Have a hitbox on the door and when the Touched event fires check the players velocity to see if they are actually moving fast enough to break through the door. If they aren’t then don’t open the door.
If there are issues with the player hitting the door and stopping before the door opens you may want to put a CanCollide false hitbox just before the door to give the Touched event time enough to open it before the player gets to it.
Edit, @Frodev beat me to it while I was typing…
its nicos nextbots. and i’ve tried doing a touch event, when touched it’ll apply a force but the issue is its kinda delayed so it resets the players momentum but yeah, as you and @Scottifly said, i could try and use a raycast to check if the door is close
yeah .touched
is know for being very random and strange, so probably use a raycast I’d say
i’ll try that, thanks!
thirtycharacterminimum
And @vaviizz, that’s why I suggested a separate hitbox in front of the door that could be wider.
A raycast is probably better since it would be fired from the player and recognize which door it’s hitting, then perform the break on just that door.
yeah but the issue with that is i have a lot of doors so it’d take a lot of time. but i guess you could make a seperate script that’d automatically generate them
I would:
- Continuously raycast out from the player’s HumanoidRootPart a few studs
- If:
- The raycast hits a door (you could detect what a door is based on the name or hierarchy location)
- The player’s velocity is high enough (optional)
- The player presses a button (optional)
- Then:
- Unanchor (or unweld) the door
- Give the door the velocity of the player plus a velocity in the opposite direction of the raycast normal (so the door goes backwards from the front kicked surface)
- Play a sound on the client
how would i add pulse velocity that isnt linear but is a big push, if you know what i mean
If you want to add a velocity over time, you can apply a force.
The change in velocity over a time based on a force is velocity change = force/mass * time
.
So to answer your question, if you wanted to give the door a certain velocity but over an amount of time, you’d add a VectorForce set to a force of velocity goal / time * mass
for time
seconds.
If you want to apply a velocity instantly, you can add a LinearVelocity set to velocity
for a few frames with max force, or use ApplyImpulse(velocity*mass)
.
alright, i just tried the raycast thing but the issue is it only detects when im like either close up, or a stud or two away
Could you send the code you used? It should be possible to just increase the range of the raycast.
The character model also might be getting in the way of the raycast if the code starts the cast inside the character, so it’s probably a good idea to make sure and ignore the character when doing the raycast.
i did ignore the character, and i even went as far as to increase the distance to 20 studs
function kickDownDoor(door, humanoidRootPart, lookVector)
if door.Parent:FindFirstChild("Weld") then
door.Parent:FindFirstChild("Weld"):Destroy()
door.Anchored = false
local direction = lookVector
local force = 100 * door:GetMass()
door:ApplyImpulse(direction * force)
task.spawn(function()
task.wait(10)
door:Destroy()
end)
end
end
game:GetService("Players").PlayerAdded:Connect(function(player)
repeat wait() until player.Character
repeat wait() until player.Character:FindFirstChild("Humanoid")
while wait() do
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local raycast = workspace:Raycast(player.Character.HumanoidRootPart.Position, player.Character.HumanoidRootPart.CFrame.LookVector, raycastParams)
if game.ReplicatedStorage.remotes.isSliding:InvokeClient(player) then
if raycast then
if raycast.Distance < 20 then
if game:GetService("CollectionService"):HasTag(raycast.Instance, "door") then
raycast.Instance.CollisionGroup = "hitDoor"
kickDownDoor(raycast.Instance, player.Character.HumanoidRootPart, game.ReplicatedStorage.remotes.getLookVector:InvokeClient(player))
end
end
end
end
end
end)
Yeah that code looks great. Here are some things that might be an issue:
This code sends a message to the client and back, which can take around 0.3-0.6 seconds. This means that the code will always be behind a decent amount, because it waits for the client to respond before responding to the raycast.
To fix this, I would have the client send an update to the server when it slides, then store the newest value from the client in a variable.
A quicker fix though it just to continuously poll the RemoteEvent in a separate loop.
Another issue is that the code only waits for the first character, which doesn’t handle new characters being added. To fix this, you can add a second event connection for CharacterAdded.
(As I’m typing this I saw this) The issue causing the raycast to be short is that the vector you used is only length 1:
Raycast(player.Character.HumanoidRootPart.Position, player.Character.HumanoidRootPart.CFrame.LookVector, raycastParams)
The player.Character.HumanoidRootPart.CFrame.LookVector
has a length of 1, so the raycast only goes 1 stud. If you multiply this by 20 for example, then the raycast looks out 20 studs.
Edit: I will include some example code in a second
oh wow, i never even thought about that, tysm
got it working tysmm
thirtycharacterlimit
Nice! Here is the example code I wrote that added some things to your code:
local KICK_DISTANCE = 8 -- How far a door can be kicked from
function kickDownDoor(door, humanoidRootPart, lookVector)
if door.Parent:FindFirstChild("Weld") then
door.Parent:FindFirstChild("Weld"):Destroy()
door.Anchored = false
local direction = lookVector
local force = 100 * door:GetMass()
door:ApplyImpulse(direction * force)
task.spawn(function()
task.wait(10)
door:Destroy()
end)
end
end
local RunService = game:GetService("RunService")
game:GetService("Players").PlayerAdded:Connect(function(player)
-- Start up the code for every new character
player.CharacterAdded:Connect(function(character)
local hrp = character:WaitForChild("HumanoidRootPart")
local isSliding = false
local lookVector = hrp.LookVector -- Just an initial value
-- Poll the values we want from the client
local connection1 = RunService.Heartbeat:Connect(function()
isSliding = game.ReplicatedStorage.remotes.isSliding:InvokeClient(player)
-- You might want to just use the hrp.LookVector, I'd assume they're pretty similar and it avoids waiting for the response latency
lookVector = game.ReplicatedStorage.remotes.getLookVector:InvokeClient(player)
end)
-- Check for a door every physics update
local connection2 = RunService.Heartbeat:Connect(function()
if isSliding then
-- Do a raycast
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local raycast = workspace:Raycast(player.Character.HumanoidRootPart.Position, player.Character.HumanoidRootPart.CFrame.LookVector * KICK_DISTANCE, raycastParams)
-- If the raycast hit something and it was a door
if raycast and game:GetService("CollectionService"):HasTag(raycast.Instance, "door") then
raycast.Instance.CollisionGroup = "hitDoor"
kickDownDoor(raycast.Instance, player.Character.HumanoidRootPart, lookVector)
end
end
end)
-- Once the character dies we stop the loops
player.CharacterRemoving:Once(function()
connection1:Disconnect()
connection2:Disconnect()
end)
end)
end)
I would double check that your code works after the player dies. I think it should need to have a CharacterAdded connection to get the most up-to-date character, but it also uses player.Character so it might work fine.
Good luck with your game!
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.