Hello,
I am currently in the middle of scripting a multi-rig combat animation, and everything works (relatively) well up until I need to apply a ragdoll and knockback to the victim’s character.
The animation I’m using is very dynamic, and has lots of movement – however, as you may (or may not) know, when playing an animation on a rig, the HumanoidRootPart of that rig remains unaffected by the animation.
This fact causes problems for me – especially when trying to apply knockback to a rig when that rig’s RootPart and Torso are far apart from each other. The position differential sometimes causes the rig to behave strangely after being ragdolled and having force applied to it.
Here is what it is supposed to look like:
Please take note of how the ragdoll remains stationary after landing in the above video.
Now, here is what happens when I apply knockback to the victim in the multi-rig animation:
As you can see, a couple of problems occur in this video:
[Problem 1]
- Upon landing, the ragdoll begins to flop around – presumably because the HumanoidRootPart is out of place relative to the character model.
[Problem 2]
- When the character stands up, it takes a pose from the animation for a brief time before returning to normal.
Both of these problems can be resolved by a single solution: stopping the animation of the victim player before applying the knockback and ragdoll. Putting this into practice however, presents another problem:
The above video now shows what happens when I stop the victim animation before I apply the force and ragdoll. Evidently, the ragdoll and force application is fixed since the HumanoidRootPart is positioned correctly. However, clearly this is not a viable solution since the knockback doesn’t apply until the victim slides back to its HumanoidRootPart’s original position.
After searching the Devforum for a possible solution to this new problem, I came acrossed someone who proposed setting the HumanoidRootPart’s position to the victim’s torso’s position. This also does not work since it offsets the animation:
As you can see, while the force is now applied from where the victim should be, the same transformation we applied to the RootPart is also applied to the victim’s character model – meaning the victim’s character model still slides to the HRP before applying the force.
Currently, I’m not sure what I should do here. I am beginning to think that this problem lies within the animation itself – and I should contact our animator.
If there are any scripting solutions you can think of, please let me know.
If you are an animator, and think you have a solution to this, please let me know so I can relay the information to our animator.
All feedback is greatly appreciated!
(below you can find a snippet of my script which deals with knockback)
if not hitChars[v.Parent.Humanoid] then
hitChars[v.Parent.Humanoid] = true
startTrack:AdjustSpeed(0.01)
v.Parent:AddTag("Trapped") -- v.Parent is the Victim's character
local eHRP = v.Parent.HumanoidRootPart
local eHum = v.Parent.Humanoid
local aTrack: AnimationTrack = hum:LoadAnimation(attack)
local eTrack: AnimationTrack = eHum:LoadAnimation(victim)
task.delay(4.3 + pauseTime, function() -- applies knockback to enemy
local direction = (-HRP.CFrame.LookVector + Vector3.new(0, 10, 0)).Unit
local eVel = Instance.new("BodyVelocity", eHRP)
eVel.MaxForce = Vector3.one * 1000000
eVel.Velocity = Vector3.one * -1 * HRP.CFrame.LookVector * knockForce + Vector3.new(0, knockForce, 0)
eVel.Name = "KnockVel"
game.Debris:AddItem(eVel, 0.2)
eTrack:Stop() -- stops victim animation track
eHRP.CFrame = v.Parent.Torso.CFrame
eHum:TakeDamage(10)
task.delay(0.15, function() -- need the 0.15 delay before applying ragdoll, otherwise glitch
HitHandler.NormalRag(eHRP, "", 500000, direction, 0, .6)
end)
v.Parent:RemoveTag("Trapped")
eHRP.Anchored = false
end)
task.delay(6 + pauseTime, function() -- re-enables attacker movement
eTrack:Stop()
aVel:Destroy()
Character:RemoveTag("Firing")
HRP.Anchored = false
hum.AutoRotate = true
end)
local finalHealth = 1
eHRP.CFrame = HRP.CFrame * CFrame.new(0,0,-2) * CFrame.Angles(0, math.rad(0), 0)
HRP.CFrame = eHRP.CFrame * CFrame.new(0,0, 5) * CFrame.Angles(0, math.rad(0), 0)
task.delay(0.5 + pauseTime, function()
HRP.CFrame = eHRP.CFrame * CFrame.new(0,0, -1) * CFrame.Angles(0, math.rad(0), 0)
end)
hum.AutoRotate = false
eHum.AutoRotate = false
HRP.Anchored = true
eHRP.Anchored = true
task.wait(pauseTime)
task.delay(0.1, function()
startTrack:Stop()
end)
aTrack:Play()
eTrack:Play()
eHum:TakeDamage(2)
local uCon
uCon = aTrack:GetMarkerReachedSignal("uppercut"):Connect(function()
uCon:Disconnect()
uCon = nil
eHum:TakeDamage(3)
end)
local bCon
bCon = aTrack:GetMarkerReachedSignal("barrage"):Connect(function()
bCon:Disconnect()
bCon = nil
task.spawn(function()
for i = 1, 8 do
eHum:TakeDamage(0.5)
task.wait(0.1)
end
end)
end)
end