You can write your topic however you want, but you need to answer these questions:
- **What do you want to achieve? ** Keep it simple and clear!
I want to create a Super Blox Bros knockback system. - **What is the issue? ** Include screenshots / videos if possible!
The knockback system was working fine, until one day the knockback was suddenly acting wonky for players. When attacking other players, the knockback is slightly offsite upwards, but on regular dummies, it worked just fine. -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I’ve been looking for solutions all evening, haven’t found any that’s helped so far.
If anyone has any idea about why this is happening, please tell me. I will provide videos if neccessary.
local bVelocity = {}
local replicated = game:GetService("ReplicatedStorage")
local eModule = require(replicated.Modules.Effects)
local KeyModule = require(replicated.Modules.GetKeyDownServer)
local waitforinput = replicated.RemoteFunctions.WaitForKeyInput
local stunModule = require(replicated.Modules.StunModule)
local RS = game:GetService("ReplicatedStorage")
local debris = game:GetService("Debris")
local function PSoundNormal(id, lifetime, volume)
local sound = Instance.new("Sound", workspace.Fx)
sound.SoundId = id
sound.Volume = volume
sound:Play()
game:GetService("Debris"):AddItem(sound, lifetime)
end
local function hWait(amount)
local i = 0
repeat
game:GetService("RunService").Heartbeat:Wait()
i += 1
until i >= amount
end
local function PSound(id, radius, lifetime, character, volume)
local sound = Instance.new("Sound", workspace.Fx)
sound.Parent = character.PrimaryPart
sound.RollOffMode = Enum.RollOffMode.Linear
sound.RollOffMaxDistance = radius
sound.RollOffMinDistance = 0
sound.SoundId = id
sound.Volume = volume
sound:Play()
game:GetService("Debris"):AddItem(sound, lifetime)
end
Code:
function bVelocity.InflictVelocity(Player:Player, Target:Model, KGB:number, BKB:number, Angle:number, Damage:number, BM:number)
--Angle is set from -360 to 360.
local Thumanoid:Humanoid = Target.Humanoid
local aprilFools = false
local visualize = false
local wasInAir = false
if Thumanoid.FloorMaterial == Enum.Material.Air then
wasInAir = true
end
-- Values.
local characterName = Target:FindFirstChild("CharacterName")
local Percent = Target.percentValue
local characterWeightValues = {
URC = 100;
Noob = 80;
Bloogis = 85;
BeachGunner = 72;
Virus = 87
}
local Weight = 85 --would be weight of the target
if characterName ~= nil then
Weight = characterWeightValues[characterName.Value]
end
local Scaling = KGB/100
local Ratio = 2.0
-- Nerdy knockback calculation.
local KnockbackCalculation = (((((Percent.Value/10 + Percent.Value*Damage/16) * 200/Weight+100 + 1.4) + 18) * Scaling) + BKB) * Ratio
if aprilFools == true then
KnockbackCalculation = 15000
end
if Target.percentValue.Value > 100 then
KGB *= 1 + ((Percent.Value - 100) / 100)
end
local LaunchSpeed = KnockbackCalculation*0.03
BM = BM or 1
LaunchSpeed *= BM
local Knockback = Instance.new("BodyVelocity")
local LForce = LaunchSpeed * 3
local LBack = 60
local HBack = 88
local diff = HBack - LBack
-- yields 28
local range = LForce - LBack
for i, v in pairs(Target.PrimaryPart:GetChildren()) do
if v:IsA("BodyVelocity") then
v:Destroy()
end
end
if Angle == 361 then
if Thumanoid.FloorMaterial == Enum.Material.Air then
Angle = 38
else
if LForce <= LBack then
Angle = 0
elseif LForce > LBack and LForce < HBack then
--[[
Creates a linear range between values, yielding a value between 0 and 1
for percent Change.
]]
Angle = 38 * (range/28)
elseif LForce >= HBack then
Angle = 38
end
end
end
print(Angle, "Angle 361 change")
-- Create a new part to calculate angles.
local newAnglePart = Instance.new("Part")
newAnglePart.Parent = workspace
newAnglePart.CanCollide = false
newAnglePart.Transparency = 1
newAnglePart.CanQuery = false
newAnglePart.CanTouch = false
newAnglePart.Anchored = true
-- Make a part at the Primary Part to launch a player at an angle
local hrpFrame = Player.Character.PrimaryPart.CFrame
newAnglePart.CFrame = hrpFrame
newAnglePart.CFrame = newAnglePart.CFrame * CFrame.Angles(math.rad(Angle), 0, 0)
local angleRay = Ray.new(newAnglePart.CFrame.Position, newAnglePart.CFrame.LookVector * LaunchSpeed * 3.8)
local function RayToPart(ray)
--this function takes the ray as a parameter. Below, it gets the midpoint.
local MidPoint = ray.Origin + ray.Direction/2
--below it creates the part and returns it. I'm sure you're familiar with properties
local Part = Instance.new("Part")
Part.Anchored = true
Part.CFrame = CFrame.lookAt(MidPoint, ray.Origin)
Part.Size = Vector3.new(1, 1, ray.Direction.Magnitude/1.5)
Part.Parent = workspace
Part.CanCollide = false
Part.Transparency = 1
debris:AddItem(Part, 2)
return Part
end
local function IsGround()
if Angle > 0 and Angle < 361 then
return false
end
local blackList = RaycastParams.new()
blackList.FilterType = Enum.RaycastFilterType.Blacklist
blackList.FilterDescendantsInstances = {Target}
local direction = Vector3.new(0, -3, 0)
local origin = Target.PrimaryPart.Position
local newRay = workspace:Raycast(origin, direction, blackList)
if newRay then
if newRay.Instance then
return true
else
return false
end
else
return false
end
end
RayToPart(angleRay)
--local designatedPointReference = newAnglePart.CFrame * CFrame.new(0,0, LaunchSpeed)
if LaunchSpeed >= 40 then
require(RS.Modules.StunModule).AddStun(Target, 1)
require(RS.Modules.StunModule).AddStun(Player.Character, 1)
PSound("rbxassetid://8821028196", 100, 1.3, Target, 8)
eModule.BasicEffect("SMASH!!!", 8, Target)
local newZoom = Instance.new("StringValue")
Player.Character.PrimaryPart.Anchored = true
Target.PrimaryPart.Anchored = true
newZoom.Name = "ZoomIn"
newZoom.Parent = Player.Character
debris:AddItem(newZoom, 1)
local pAnimator:Animator = Player.Character.Humanoid.Animator
for i, track:AnimationTrack in pairs(pAnimator:GetPlayingAnimationTracks()) do
track:AdjustSpeed(0)
task.delay(1, function()
track:AdjustSpeed(1)
end)
end
local newZoomTwo = Instance.new("StringValue")
newZoomTwo.Name = "ZoomIn"
newZoomTwo.Parent = Target
debris:AddItem(newZoomTwo, 1)
local tAnimator:Animator = Target.Humanoid.Animator
for i, track:AnimationTrack in pairs(tAnimator:GetPlayingAnimationTracks()) do
track:AdjustSpeed(0)
task.delay(1, function()
track:AdjustSpeed(1)
end)
end
task.wait(1)
Player.Character.PrimaryPart.Anchored = false
Target.PrimaryPart.Anchored = false
end
Target.PrimaryPart.Anchored = false
local finalizedAngle = Angle
--[[
if Target.PrimaryPart:FindFirstChild("Velocity") then
local prevAngle = Target.PrimaryPart:FindFirstChild("Velocity"):GetAttribute("Angle")
local distanceBetweenAngles = math.abs(Angle - prevAngle)
if Angle < prevAngle then
finalizedAngle = Angle + (distanceBetweenAngles / 2)
elseif Angle > prevAngle then
finalizedAngle = prevAngle + (distanceBetweenAngles / 2)
end
Target.PrimaryPart:FindFirstChild("Velocity"):Destroy()
end
]]
Angle = finalizedAngle
print(Angle, "Angle finalized change")
Knockback.Parent = Target.HumanoidRootPart
Knockback.Name = "Velocity"
Knockback.MaxForce = Vector3.new(20000, 20000, 0)
Knockback:SetAttribute("Angle", Angle)
local identifier = Instance.new("StringValue")
identifier.Name = "DontKick"
identifier.Parent = Knockback
local pressedAnything = false
local pressedConnection = nil
pressedConnection = Thumanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
pressedAnything = true
pressedConnection:Disconnect()
end)
local launchModifier = math.clamp((LaunchSpeed * 3.8/100), .05, 0.6)
local launchTimeTicker = tick()
local launchTime = (.2 +launchModifier)
local AfterTime = (launchTime - .2)
local hAfterTime = AfterTime / 2
if game:GetService("Players"):GetPlayerFromCharacter(Target) then
local newTag = Instance.new("ObjectValue")
newTag.Value = Player
newTag.Parent = Target
newTag.Name = "DeathTag"
debris:AddItem(newTag, launchTime * 2)
end
debris:AddItem(Knockback,launchTime)
local stun = require(RS.Modules.StunModule)
local launchStun = stun.AddStun(Target, launchTime)
-- Send them flying at this Angle
local CappedVelocity = newAnglePart.CFrame.LookVector * LaunchSpeed * 3.8
print(newAnglePart.CFrame.LookVector)
local function backOrFront(root1, root2)
local ObjectSpace = root2.CFrame:inverse() * root1.CFrame
if ObjectSpace.Z > 0 then
return "HitFromBack"
else
return "HitFromFront"
end
end
-- gets if hit from front or back, then turns it into a string
local hitFrom = backOrFront(Player.Character.PrimaryPart, Target.PrimaryPart)
-- Uses that string to decide what animation to pick.
local hitAnimation = script.KB:FindFirstChild(hitFrom)
local load:AnimationTrack = Thumanoid.Animator:LoadAnimation(hitAnimation)
load.Name = hitFrom
if Angle >= 0 and Angle <= 85 then
load:Play()
elseif Angle > 85 and Angle <= 105 then
load = Thumanoid.Animator:LoadAnimation(script.KB.HitFromUp)
load:Play()
end
Knockback.Destroying:Connect(function()
load:Stop()
end)
Knockback.Velocity = CappedVelocity
local landedConnection = nil
--[[landedConnection = Thumanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Landed and Angle > 0 and Angle < 360 then
if Knockback and pressedAnything == false then else return end
Angle = -Angle
print(Angle, "Angle reversed change")
Knockback:Destroy()
landedConnection:Disconnect()
local RS = game:GetService("ReplicatedStorage")
local tweenService = game:GetService("TweenService")
local function slamEffect(position:Vector3):MeshPart
local newSlam = RS.Effects.HitWave:Clone()
newSlam.Position = position
newSlam.Parent = workspace
local goals = {
Transparency = 1;
Size = Vector3.new(20, 2, 20)
}
local inf = TweenInfo.new(.4, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local newTween = tweenService:Create(newSlam, inf, goals)
newTween:Play()
debris:AddItem(newSlam, 1)
return newSlam
end
slamEffect(Target.PrimaryPart.Position - Vector3.new(0, 2.25, 0))
PSoundNormal("rbxassetid://5246111377", 2, 2)
local groundHitAnimation:AnimationTrack = Thumanoid.Animator:LoadAnimation(script.GroundHit)
groundHitAnimation:Play()
groundHitAnimation:GetMarkerReachedSignal("GroundEnd"):Connect(function()
local bigStun = stunModule.AddStun(Target, "INF", true, 270)
local groundStayingAnimation:AnimationTrack = Thumanoid.Animator:LoadAnimation(script.GroundLong)
groundStayingAnimation:Play()
local input:Enum.KeyCode = nil
local inputScript
if game:GetService("Players"):GetPlayerFromCharacter(Target) ~= nil then
local tPlayer = game:GetService("Players"):GetPlayerFromCharacter(Target)
inputScript = task.spawn(function()
input = waitforinput:InvokeClient(tPlayer)
end)
end
local longevity = 0
local stunned = false
repeat
task.wait(.01)
longevity += 0.1
for i, v in pairs(Target:GetChildren()) do
if v.Name == "Stun" and v:IsA("IntValue") then
if v == launchStun or v.Value == 270 then else
stunned = true
end
end
end
until stunned == true or longevity >= 10 or input ~= nil
groundStayingAnimation:Stop()
bigStun:Destroy()
coroutine.yield(inputScript)
local iframes = require(RS.Modules.IFrameModule)
local velocity = require(RS.Modules.BodyVelocity)
local playerHumanoid = Player.Character:FindFirstChild("Humanoid")
local rightOri = Vector3.new(0, -90, 0)
local leftOri = Vector3.new(0, 90, 0)
if input ~= nil then
if input == Enum.KeyCode.A then
local hrp = Target.HumanoidRootPart
local anim = nil
if hrp.Orientation == rightOri then
velocity.InflictVelocity(Target, Target.PrimaryPart.CFrame.LookVector * -40, nil, .2)
anim = Thumanoid.Animator:LoadAnimation(script.BFlip)
elseif hrp.Orientation == leftOri then
velocity.InflictVelocity(Target, Target.PrimaryPart.CFrame.LookVector * 40, nil, .2)
anim = Thumanoid.Animator:LoadAnimation(script.FFlip)
end
if anim ~= nil then
anim:Play()
end
iframes.AddIFrames(Target, .65)
stun.AddStun(Target, 1.15, true, "sak")
elseif input == Enum.KeyCode.D then
local hrp = Target.HumanoidRootPart
local anim = nil
if hrp.Orientation == rightOri then
velocity.InflictVelocity(Target, Target.PrimaryPart.CFrame.LookVector * 40, nil, .2)
anim = Thumanoid.Animator:LoadAnimation(script.FFlip)
elseif hrp.Orientation == leftOri then
velocity.InflictVelocity(Target, Target.PrimaryPart.CFrame.LookVector * -40, nil, .2)
anim = Thumanoid.Animator:LoadAnimation(script.BFlip)
end
if anim ~= nil then
anim:Play()
end
iframes.AddIFrames(Target, .65)
stun.AddStun(Target, 1.15, true, "sak")
end
elseif stunned == false then
iframes.AddIFrames(Target, 1, true)
end
end)
end
end)]]
-- Slows down momentum
local pastAngle = Angle
local timesBounce = 0
local function bounce()
local flippedAngle = -Angle
print(flippedAngle, "Flipped angle")
timesBounce += 1
newAnglePart.CFrame = hrpFrame
newAnglePart.CFrame = newAnglePart.CFrame * CFrame.Angles(math.rad(flippedAngle), 0, 0)
local lifetimeLeft = launchTime - (tick() - launchTimeTicker)
Knockback.Velocity = (newAnglePart.CFrame.LookVector * LaunchSpeed * (3.8 / timesBounce))
task.spawn(function()
local wat = "?"
repeat
task.wait(.05) lifetimeLeft = launchTime - (tick() - launchTimeTicker)
if IsGround() == true then
bounce()
wat = true
return
end
until lifetimeLeft <= 0 or wat == true
end)
end
task.delay(.2, function()
if Angle < 0 or Angle < 5 then
Knockback:Destroy()
else
for i = 10, 1, -1 do
local momentumLoss = (newAnglePart.CFrame.LookVector * LaunchSpeed * 3.8) * (i / 10)
if Angle > 0 and Angle ~= 361 then
newAnglePart.CFrame = hrpFrame
newAnglePart.CFrame = newAnglePart.CFrame * CFrame.Angles(math.rad(pastAngle * (i / 10)), 0, 0)
end
Knockback.Velocity = momentumLoss
task.wait(hAfterTime / 10)
if visualize == true then
local newPart = workspace.SpecialValues.LaunchShower:Clone()
newPart.Parent = workspace
newPart.CFrame = Target.PrimaryPart.CFrame
debris:AddItem(newPart,2)
end
end
for i = 1, 10 do
local lessVel = (newAnglePart.CFrame.LookVector * LaunchSpeed * 3.8) * (i / 10) * 1.2
if Angle > 0 and Angle ~= 361 then
newAnglePart.CFrame = hrpFrame
newAnglePart.CFrame = newAnglePart.CFrame * CFrame.Angles(math.rad(-pastAngle * (i / 10)), 0, 0)
end
Knockback.Velocity = lessVel * (1 - (i / 10))
task.wait(hAfterTime / 10)
if visualize == true then
local newPart = workspace.SpecialValues.LaunchShower:Clone()
newPart.Parent = workspace
newPart.CFrame = Target.PrimaryPart.CFrame
debris:AddItem(newPart, 2)
end
if i == 5 then
debris:AddItem(launchStun, 0)
if visualize == true then
local newPart = workspace.SpecialValues.LaunchShower:Clone()
newPart.Parent = workspace
newPart.CFrame = Target.PrimaryPart.CFrame
newPart.BrickColor = BrickColor.new("Lime green")
debris:AddItem(newPart, 2)
end
end
end
Knockback:Destroy()
end
end)
--Create a trail of smoke
task.spawn(function()
if LaunchSpeed >= 8 and Angle >= 15 and Angle < 361 then
local timeOfSmoke = .2 + hAfterTime
local sEffect = game:GetService("ReplicatedStorage").Effects.Smoke:Clone()
sEffect.Parent = Target.Torso
task.delay(timeOfSmoke, function()
sEffect.Enabled = false
task.wait(2)
sEffect:Destroy()
end)
end
end)
if LaunchSpeed >= 19 and Thumanoid.FloorMaterial == Enum.Material.Air then
if Angle > 15 and Angle < 360 then
--Tumble script for stun
local load = Target.Humanoid.Animator:LoadAnimation(script:FindFirstChild("Tumble"))
load:Play()
task.delay(math.clamp(KnockbackCalculation/60, 0, 1), function()
load:Stop()
end)
local con
con = Thumanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
if Thumanoid.FloorMaterial ~= Enum.Material.Air then
load:Stop()
con:Disconnect()
if game:GetService("Players"):GetPlayerFromCharacter(Target) then
script.GroundedRemoteEvent:FireClient(game:GetService("Players"):GetPlayerFromCharacter(Target))
end
end
end)
end
end
-- Delete the angle part
debris:AddItem(newAnglePart,4)
end
--[[local amount = 0
for _, child in pairs(target:GetChildren()) do
if child.ClassName == "BodyVelocity" and child.Name == "Velocity" then
amount += 1
end
end
if amount > 1 then
for _, child in pairs(target:GetChildren()) do
if child.ClassName == "BodyVelocity" and child.Name == "Velocity" then
debris:AddItem(child, 0)
end
end
end
local bv = Instance.new("BodyVelocity")
bv.Velocity = velocity
bv.MaxForce = Vector3.new(20000, 20000, 0)
bv.Parent = target.HumanoidRootPart
bv.Name = "Velocity"
debris:AddItem(bv, lifetime)
local biggestValue = 0
if math.abs(velocity.X) > math.abs(velocity.Y) then
biggestValue = math.abs(velocity.X)
elseif math.abs(velocity.X) < math.abs(velocity.Y) then
biggestValue = math.abs(velocity.Y)
else
biggestValue = math.abs(velocity.Y)
end
if noEffects == nil or noEffects == false or DOEFFECTS == true then
if biggestValue >= 50 and target.Torso:FindFirstChild("BodyFrontAttachment") then
local newSmoke = game:GetService("ReplicatedStorage").Effects.Smoke:Clone()
newSmoke.Parent = target.Torso.BodyFrontAttachment
local GraphicsLevel = UserSettings().GameSettings.SavedQualityLevel.Value
local oldRate = newSmoke.Rate
newSmoke.Rate = oldRate * 10 / GraphicsLevel
task.delay(lifetime * 2 + .8, function()
newSmoke.Enabled = false
wait(2)
debris:AddItem(newSmoke, 0)
end)
elseif DOEFFECTS == true then
local newSmoke = game:GetService("ReplicatedStorage").Effects.Smoke:Clone()
newSmoke.Parent = target.Torso.BodyFrontAttachment
local GraphicsLevel = UserSettings().GameSettings.SavedQualityLevel.Value
local oldRate = newSmoke.Rate
newSmoke.Rate = oldRate * 10 / GraphicsLevel
task.delay(lifetime * 2 + .8, function()
newSmoke.Enabled = false
wait(2)
debris:AddItem(newSmoke, 0)
end)
end
if biggestValue > 100 then
PSoundNormal("rbxassetid://9057675920", 4, 5)
eModule.BasicEffect("SmashEffect", .4, target)
end
end--]]
return bVelocity
This video shows the intended angle (part) and the actual angle, where the noob is sent.