基本上,我的横向卷轴游戏中有一个射击机制,我让它与零件一起工作,让它们有生命值。
我希望这些部件是非锚定的,并且我已经在没有射击它们的情况下测试了它们,并且它们作为非锚定部件工作得很好。
问题是当我射击支撑顶部零件的一个零件时,当你完全摧毁我游戏中的一个零件时,我使用
part:Destroy()
移除零件,顶部的零件漂浮在半空中并像其滞后一样移动??看这个视频。
我真的不知道如何尝试解决这个问题,这就是我将其发布在这里的原因。
有几点需要注意:
这是在一台新电脑上运行的东西,如真人快打1和埃尔登戒指等,所以我不认为它的性能。
我在这台电脑上的工作室由于某种原因有很多问题,尤其是动画。
我尝试在 roblox 播放器中加载实际游戏,但没有成功。
这是我的射击代码(它位于 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)
通常,奇怪的物理错误往往是由网络所有权问题引起的。
服务器是所有对象、它们的位置、属性等一切的真实来源。但是,您正在删除客户端上的对象并尝试运行生成的物理模拟。客户端试图移动对象,但服务器(服务器不知道这些更改已经发生,因为客户端更改没有复制到服务器)坚持认为这些对象没有移动。
因此要解决此问题,您需要:
我将解释选项 B。所以你会...
ShootEvent
所以在你的 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)
然后在你的服务器脚本中...
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)
希望这有帮助!