Hello, So I am working a fast open sea game where I am working on an oxygen system but I have ran into a problem my system takes away oxygen even if the player is floating at the top of the water.
Takes away oxygen here when it’s not meant to.
I have tried thinking of ways around this but no of them seem to work.
Here is my script.
local bar = script.Parent.BarBG.Bar
local maxOxygen = 100
local currentOxygen = maxOxygen
local timePerLoss = 0.3
local isSwimming = false
local hum = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
hum.StateChanged:Connect(function(oldState, newState)
isSwimming = (newState == Enum.HumanoidStateType.Swimming)
end)
while wait(timePerLoss) do
if isSwimming then
currentOxygen = math.max(currentOxygen - 1, 0)
else
currentOxygen = math.min(currentOxygen + 1, maxOxygen)
end
if currentOxygen < 1 then
hum.Health = 0
end
bar.Size = UDim2.new(currentOxygen / maxOxygen, 0, 1, 0)
end
Any help is appreciated.
Many Thanks for any help!
You could raycast downwards from the head (or mouth) and see if the ray intersects with the water surface to determine if the player is still breathing. Use it in conjunction with the method you already have.
It really shouldn’t. I’ve been able to do thousands of raycasts per frame without lag. You would only need to do one raycast per frame for this scenario.
local lp = game:GetService('Players').LocalPlayer
local char = lp.Character or lp.CharacterAdded:Wait()
local head: BasePart = char:WaitForChild('Head')
local hum: Humanoid = char:WaitForChild('Humanoid')
lp.CharacterAdded:Connect(function(ch)
char = ch
head = ch:WaitForChild('Head')
hum = ch:WaitForChild('Humanoid')
end)
local mouthOffset: CFrame = CFrame.new(0, -0.25, -1) --Offset the origin position to near the mouth
local raycastDir: Vector3 = Vector3.yAxis * -5 --the raycast will only be 5 studs long
local rcp: RaycastParams = RaycastParams.new()
rcp.FilterDescendantsInstances = {workspace:WaitForChild('Terrain')}
rcp.FilterType = Enum.RaycastFilterType.Whitelist
rcp.IgnoreWater = false
game:GetService('RunService').RenderStepped:Connect(function()
--check if the player is swimming but NOT breathing (which is when the raycast is nil)
local isSwimming: boolean = hum:GetState() == Enum.HumanoidStateType.Swimming
and not workspace:Raycast((head.CFrame*mouthOffset).Position, raycastDir, rcp)
char:SetAttribute('IsSwimming', isSwimming)
end)