最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

lua - Physics broken for unanchored parts when i use :Destroy() - Stack Overflow

programmeradmin1浏览0评论

Basically I have a shooting mechanic in my side scroller game and I made it work with parts, having them have health.

I wanted these parts to be unanchored and I have tested them without shooting them, and they work fine as unanchored parts.

The issue is when I shoot one of the parts holding up a part on the top, when you fully destroy a part in my game i use part:Destroy() to remove the parts, the part on the top floats midair and moves like its laggy?? see this video.

I don't really know what to try to fix this problem, which is why I'm posting it on here.

A few things to note:

  1. This is on a new pc which runs stuff like mortal kombat 1 and elden ring etc so i don't think its performance.

  2. My studio on this pc is quite buggy for some reason, especially with animations.

  3. I tried loading the ACTUAL game up in the roblox player to no avail.

    here is my code for shooting (it goes in starterplayer.startercharacterscripts):

    local player = game.Players.LocalPlayer
    local mouse = player:GetMouse()
    local gui = player.PlayerGui:WaitForChild("GameGui") 
    local targetImage = gui:WaitForChild("Target") 
    local bulletSpeed = 70 
    local damageAmount = 25 
    local shootCooldown = 1 
    local lastShootTime = 0 
    
    
    targetImage.Visible = false
    
    
    local function unanchorBreakableParts()
     local breakableFolder = workspace:WaitForChild("Breakable")
     for _, part in pairs(breakableFolder:GetChildren()) do
         if part:IsA("Part") then
             part.Anchored = false 
         end
     end
    end
    
    
    local function fireBullet(startPosition, targetPosition)
     local bullet = Instance.new("Part")
     bullet.Size = Vector3.new(1, 0.5, 0.5) 
     bullet.Material = Enum.Material.Neon
     bullet.BrickColor = BrickColor.new("Bright yellow") 
     bullet.Position = startPosition
     bullet.Anchored = false
     bullet.CanCollide = false
     bullet.Parent = workspace
    
    
     local direction = (targetPosition - startPosition).unit
    
    
     bullet.CFrame = CFrame.lookAt(startPosition, startPosition + direction)
    
    
     local bodyVelocity = Instance.new("BodyVelocity")
     bodyVelocity.Velocity = direction * bulletSpeed
     bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge) 
     bodyVelocity.Parent = bullet
    
    
     local connection
     connection = bullet.Touched:Connect(function(hit)
         if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
             local humanoid = hit.Parent:FindFirstChild("Humanoid")
             local character = player.Character
    
    
             if humanoid.Parent ~= character then
                 humanoid:TakeDamage(damageAmount)
                 bullet:Destroy() 
                 connection:Disconnect()
             end
         elseif hit and hit.Parent and hit:FindFirstChild("Health") then
    
             local health = hit:FindFirstChild("Health")
             if health then
                 health.Value = health.Value - damageAmount 
    
    
                 if health.Value <= 0 then
                     hit:Destroy() 
                 end
             end
    
             bullet:Destroy() 
             connection:Disconnect()
         else
    
             bullet:Destroy()
             connection:Disconnect()
         end
     end)
    
    
     game:GetService("Debris"):AddItem(bullet, 5)
    end
    
    
    mouse.Button1Down:Connect(function()
    
     unanchorBreakableParts()
    
    
     local currentTime = tick()
     if currentTime - lastShootTime < shootCooldown then
         return 
     end
    
    
     local mousePosition = Vector2.new(mouse.X, mouse.Y)
     targetImage.Position = UDim2.new(0, mousePosition.X - (targetImage.Size.X.Offset / 2), 0, mousePosition.Y - (targetImage.Size.Y.Offset / 2))
     targetImage.Visible = true
    
    
     task.delay(0.3, function()
         targetImage.Visible = false
     end)
    
    
     local ray = workspace.CurrentCamera:ScreenPointToRay(mouse.X, mouse.Y)
     local rayTarget = ray.Origin + ray.Direction * 500
    
    
     local raycastParams = RaycastParams.new()
     raycastParams.FilterDescendantsInstances = {player.Character} 
     raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    
     local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 500, raycastParams)
     if raycastResult then
         rayTarget = raycastResult.Position 
     end
    
    
     local character = player.Character or player.CharacterAdded:Wait()
     local rightArm = character:FindFirstChild("ShootPart")
     local startPosition = rightArm.Position
    
    
     local humanoid = character:FindFirstChild("Humanoid")
     local shootAnim = character:FindFirstChild("Animations"):FindFirstChild("Shoot")
    
     if humanoid and shootAnim and shootAnim:IsA("Animation") then
    
         local loadedAnim = humanoid:LoadAnimation(shootAnim)
    
    
         loadedAnim.Priority = Enum.AnimationPriority.Action3
    
    
         loadedAnim:Play()
     else
         warn("Humanoid or Shoot animation not found!")
     end
    
    
     fireBullet(startPosition, rayTarget)
    
    
     lastShootTime = currentTime
    end)
    
    

Basically I have a shooting mechanic in my side scroller game and I made it work with parts, having them have health.

I wanted these parts to be unanchored and I have tested them without shooting them, and they work fine as unanchored parts.

The issue is when I shoot one of the parts holding up a part on the top, when you fully destroy a part in my game i use part:Destroy() to remove the parts, the part on the top floats midair and moves like its laggy?? see this video.

I don't really know what to try to fix this problem, which is why I'm posting it on here.

A few things to note:

  1. This is on a new pc which runs stuff like mortal kombat 1 and elden ring etc so i don't think its performance.

  2. My studio on this pc is quite buggy for some reason, especially with animations.

  3. I tried loading the ACTUAL game up in the roblox player to no avail.

    here is my code for shooting (it goes in starterplayer.startercharacterscripts):

    local player = game.Players.LocalPlayer
    local mouse = player:GetMouse()
    local gui = player.PlayerGui:WaitForChild("GameGui") 
    local targetImage = gui:WaitForChild("Target") 
    local bulletSpeed = 70 
    local damageAmount = 25 
    local shootCooldown = 1 
    local lastShootTime = 0 
    
    
    targetImage.Visible = false
    
    
    local function unanchorBreakableParts()
     local breakableFolder = workspace:WaitForChild("Breakable")
     for _, part in pairs(breakableFolder:GetChildren()) do
         if part:IsA("Part") then
             part.Anchored = false 
         end
     end
    end
    
    
    local function fireBullet(startPosition, targetPosition)
     local bullet = Instance.new("Part")
     bullet.Size = Vector3.new(1, 0.5, 0.5) 
     bullet.Material = Enum.Material.Neon
     bullet.BrickColor = BrickColor.new("Bright yellow") 
     bullet.Position = startPosition
     bullet.Anchored = false
     bullet.CanCollide = false
     bullet.Parent = workspace
    
    
     local direction = (targetPosition - startPosition).unit
    
    
     bullet.CFrame = CFrame.lookAt(startPosition, startPosition + direction)
    
    
     local bodyVelocity = Instance.new("BodyVelocity")
     bodyVelocity.Velocity = direction * bulletSpeed
     bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge) 
     bodyVelocity.Parent = bullet
    
    
     local connection
     connection = bullet.Touched:Connect(function(hit)
         if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
             local humanoid = hit.Parent:FindFirstChild("Humanoid")
             local character = player.Character
    
    
             if humanoid.Parent ~= character then
                 humanoid:TakeDamage(damageAmount)
                 bullet:Destroy() 
                 connection:Disconnect()
             end
         elseif hit and hit.Parent and hit:FindFirstChild("Health") then
    
             local health = hit:FindFirstChild("Health")
             if health then
                 health.Value = health.Value - damageAmount 
    
    
                 if health.Value <= 0 then
                     hit:Destroy() 
                 end
             end
    
             bullet:Destroy() 
             connection:Disconnect()
         else
    
             bullet:Destroy()
             connection:Disconnect()
         end
     end)
    
    
     game:GetService("Debris"):AddItem(bullet, 5)
    end
    
    
    mouse.Button1Down:Connect(function()
    
     unanchorBreakableParts()
    
    
     local currentTime = tick()
     if currentTime - lastShootTime < shootCooldown then
         return 
     end
    
    
     local mousePosition = Vector2.new(mouse.X, mouse.Y)
     targetImage.Position = UDim2.new(0, mousePosition.X - (targetImage.Size.X.Offset / 2), 0, mousePosition.Y - (targetImage.Size.Y.Offset / 2))
     targetImage.Visible = true
    
    
     task.delay(0.3, function()
         targetImage.Visible = false
     end)
    
    
     local ray = workspace.CurrentCamera:ScreenPointToRay(mouse.X, mouse.Y)
     local rayTarget = ray.Origin + ray.Direction * 500
    
    
     local raycastParams = RaycastParams.new()
     raycastParams.FilterDescendantsInstances = {player.Character} 
     raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    
     local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 500, raycastParams)
     if raycastResult then
         rayTarget = raycastResult.Position 
     end
    
    
     local character = player.Character or player.CharacterAdded:Wait()
     local rightArm = character:FindFirstChild("ShootPart")
     local startPosition = rightArm.Position
    
    
     local humanoid = character:FindFirstChild("Humanoid")
     local shootAnim = character:FindFirstChild("Animations"):FindFirstChild("Shoot")
    
     if humanoid and shootAnim and shootAnim:IsA("Animation") then
    
         local loadedAnim = humanoid:LoadAnimation(shootAnim)
    
    
         loadedAnim.Priority = Enum.AnimationPriority.Action3
    
    
         loadedAnim:Play()
     else
         warn("Humanoid or Shoot animation not found!")
     end
    
    
     fireBullet(startPosition, rayTarget)
    
    
     lastShootTime = currentTime
    end)
    
    
Share Improve this question edited Jan 20 at 9:02 Toby Speight 30.7k49 gold badges73 silver badges113 bronze badges asked Jan 19 at 1:27 PiraxePiraxe 211 silver badge2 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Usually, weird physics bugs tend to be caused by network ownership issues.

The server is source of truth for all objects, their positions, properties, everything. However, you are deleting objects on the client and trying to run the resulting physics sim. The client is trying to move objects around but the server (which has no idea that these changes have happened because client changes are not replicated to the server) is insisting that these objects haven't moved.

So to fix this issue, you need to either :

  • a) Create the objects you plan to destroy in LocalScripts, or
  • b) Use RemoteEvents to destroy the objects on the server.

I'll explain Option B. So you'll to...

  1. Create a RemoteEvent in ReplicatedStorage, and name it something like ShootEvent
  2. Create a Script in ServerScriptService
  3. Move all of your bullet logic into the Script
  4. Have your LocalScript fire the RemoteEvent instead
  5. Connect your Script to the RemoteEvent to spawn the bullet the client fires the event.

So in your LocalScript...

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local gui = player.PlayerGui:WaitForChild("GameGui") 
local shootEvent = game.ReplicatedStorage.ShootEvent
local targetImage = gui:WaitForChild("Target") 
local shootCooldown = 1 
local lastShootTime = 0


targetImage.Visible = false

-- listen for mouse clicks
mouse.Button1Down:Connect(function()
    -- escape if we're on cooldown
    local currentTime = tick()
    if currentTime - lastShootTime < shootCooldown then
        return 
    end

    -- update the ui
    targetImage.Visible = true
    task.delay(0.3, function()
        targetImage.Visible = false
    end)

    -- figure out what we're aiming at
    local mousePosition = Vector2.new(mouse.X, mouse.Y)
    targetImage.Position = UDim2.new(0, mousePosition.X - (targetImage.Size.X.Offset / 2), 0, mousePosition.Y - (targetImage.Size.Y.Offset / 2))
    

    local ray = workspace.CurrentCamera:ScreenPointToRay(mouse.X, mouse.Y)
    local rayTarget = ray.Origin + ray.Direction * 500
    local raycastParams = RaycastParams.new()
    raycastParams.FilterDescendantsInstances = {player.Character} 
    raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
    local raycastResult = workspace:Raycast(ray.Origin, ray.Direction * 500, raycastParams)
    if raycastResult then
        rayTarget = raycastResult.Position 
    end

    -- play an animation
    local humanoid = character:FindFirstChild("Humanoid")
    local shootAnim = character:FindFirstChild("Animations"):FindFirstChild("Shoot")

    if humanoid and shootAnim and shootAnim:IsA("Animation") then
        local loadedAnim = humanoid:LoadAnimation(shootAnim)
        loadedAnim.Priority = Enum.AnimationPriority.Action3
        loadedAnim:Play()
    else
        warn("Humanoid or Shoot animation not found!")
    end

    -- tell the server to fire the bullet
    shootEvent:FireServer(rayTarget)

    -- reset the debounce/cooldown
    lastShootTime = currentTime
end)

Then in your server Script...

local bulletSpeed = 70 
local damageAmount = 25 

local function unanchorBreakableParts()
    local breakableFolder = workspace:WaitForChild("Breakable")
    for _, part in pairs(breakableFolder:GetChildren()) do
        if part:IsA("Part") then
           part.Anchored = false 
        end
    end
end


local function fireBullet(startPosition, targetPosition)
    -- create the bullet
    local bullet = Instance.new("Part")
    bullet.Size = Vector3.new(1, 0.5, 0.5) 
    bullet.Material = Enum.Material.Neon
    bullet.BrickColor = BrickColor.new("Bright yellow") 
    bullet.Position = startPosition
    bullet.Anchored = false
    bullet.CanCollide = false
    bullet.Parent = workspace

    local direction = (targetPosition - startPosition).unit
    bullet.CFrame = CFrame.lookAt(startPosition, startPosition + direction)

    -- make the bullet move
    local bodyVelocity = Instance.new("BodyVelocity")
    bodyVelocity.Velocity = direction * bulletSpeed
    bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge) 
    bodyVelocity.Parent = bullet

    -- listen for when the bullet hits things
    local connection
    connection = bullet.Touched:Connect(function(hit)
        if hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid") then
            local humanoid = hit.Parent:FindFirstChild("Humanoid")
            local character = player.Character
            if humanoid.Parent ~= character then
                humanoid:TakeDamage(damageAmount)
            end

        elseif hit and hit.Parent and hit:FindFirstChild("Health") then
            local health = hit:FindFirstChild("Health")
            if health then
                health.Value = health.Value - damageAmount 
                if health.Value <= 0 then
                    hit:Destroy() 
                end
            end
        end

        bullet:Destroy()
        connection:Disconnect()
    end)

    -- mark the bullet for cleanup
    game:GetService("Debris"):AddItem(bullet, 5)
end


 
-- listen for when the client says they've fired a bullet
game.ReplicatedStorage.ShootEvent.OnServerEvent:Connect(function(player : Player, rayTarget : Vector3)
    local character = player.Character or player.CharacterAdded:Wait()
    local rightArm = character:FindFirstChild("ShootPart")
    local startPosition = rightArm.Position

    fireBullet(startPosition, rayTarget)
end)

Hope this helps!

发布评论

评论列表(0)

  1. 暂无评论