I want to fling NPCs out of cannons onto a battlefield and I am launching them by changing the AssemblyLinearVelocity of their HumanoidRootParts. It works well on the server, however on the client it is very glitchy and they get stuck in the floor. I don’t even know where to start to fix this issue.
Heres my code:
local cannon = script.Parent.Parent
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
local hum = hit.Parent.Humanoid
local hmr = hit.Parent.HumanoidRootPart
hum.Sit = true
hmr.Anchored = true
hmr.CFrame = cannon.Tip.CFrame
wait(1)
hmr.Position += cannon.Tip.CFrame.LookVector*2
hmr.Anchored = false
hmr.AssemblyLinearVelocity = cannon.Tip.CFrame.LookVector * math.random(100,120)
hmr.Touched:Wait()
hmr.CFrame = hmr.CFrame
hum.Sit = false
end
end)
No clue my self what is going on. Maybe a network ownership thing? Anyway.
Your code is bad. Please take some of the following advice with you:
DONT EVER use deprecated functions/types/anything like wait, if it is deprecated then don’t use it. Use task.wait here instead.
Why are you slapping all your code within the if statement? Just have it check if there is no humanoid:
if not hit.Parent:FindFirstChild("Humanoid") then -- can also do == nil but its longer
print("No humanoid :(")
return -- exit and stop running (might not be needed but its a habit of mine)
end
-- logic for functionality here
Anyways I didn’t know that wait() was depreciated so thanks for telling me. I really work in my own bubble, I work on my own projects and never really collaborate with people so I don’t know the best practices.
That’s fine but you should practice bettering your code structure and learning common code practices. It is pretty easy to learn and understand if you understand the fundementals. Just look on the resources category or literally just lookup guard clauses and other best practices.
looks like the npcs are falling with an offset, likely from their humanoidRootPart.
Youre changing the npcs cframe by manually changing the position of the humanoidRootPart, I dont know why, but roblox doesnt like this and usaully starts to mess up the rig when you do that, maybe it doesnt update the root motor6D or something, im not too sure of an internal explaination
But use PivotTo to move the characters cframe/position around
local cannon = script.Parent.Parent
local tipPart = cannon.Tip
script.Parent.Touched:Connect(function(hit: BasePart)
local character = hit.Parent :: Model
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
local rootpart = character:WaitForChild("HumanoidRootPart") :: BasePart
humanoid.Sit = true
rootpart.Anchored = true
character:PivotTo(tipPart.CFrame)
task.delay(1, function()
character:PivotTo(tipPart.CFrame * CFrame.new(0, 0, -1)) --CFrame.new(0, 0, -1) moves the character 1 stud forwards
rootpart.Anchored = false
rootpart.AssemblyLinearVelocity = cannon.Tip.CFrame.LookVector * math.random(100,120)
humanoid.Touched:Wait()
humanoid.Sit = false
end)
end
end)
Little bit different, not much. Stops any type of false read from these two…
local hum = hit.Parent.Humanoid
local hmr = hit.Parent.HumanoidRootPart
local cannon = script.Parent.Parent
local char, db = nil, true
script.Parent.Touched:Connect(function(hit)
if not db then return end char = hit.Parent
if char:FindFirstChild("Humanoid") and db then
db = false
local hum = char.Humanoid
local hmr = char.HumanoidRootPart
hum.Sit = true
hmr.Anchored = true
hmr.CFrame = cannon.Tip.CFrame
task.wait(1)
hmr.Position += cannon.Tip.CFrame.LookVector * 2
hmr.Anchored = false
hmr.AssemblyLinearVelocity = cannon.Tip.CFrame.LookVector * math.random(100,120)
hmr.Touched:Wait()
hmr.CFrame = hmr.CFrame
hum.Sit = false
task.wait(2)
db = true
end
end
When a player or NPC touches something, it usually happens many times with multiple parts. Hit can rapidly change the outcome of hit.Parent. So you use a debounce (db). I’m not sure about the rest of it, but that part wouldn’t work as you intended, especially without the debounce. I’m sure you were getting double fires or more.
I know you used Humanoid here to make sure it was the right kind of touch but, that would be true many times, firing for each one. Place a print(hit) in there and you’ll be shocked how many times that goes off.