@rbxts/falldown 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/out/index.d.ts CHANGED
@@ -38,7 +38,7 @@ export interface IActiveRagdoll {
38
38
  * @see {@linkcode IActiveRagdoll.Destroyed}
39
39
  * @see {@linkcode Falldown.UnragdollCharacter}
40
40
  */
41
- Destroy(): void;
41
+ Destroy(exitMode: (typeof Falldown.ExitMode)[keyof typeof Falldown.ExitMode]): void;
42
42
  }
43
43
  /**
44
44
  * Main Falldown class providing static methods for ragdolling characters in Roblox. Creates realistic ragdoll physics by replacing Motor6Ds with constraints, managing collision groups, and providing smooth getup animations.
@@ -64,6 +64,19 @@ export declare class Falldown {
64
64
  /** Each part gets a random velocity from 0 to the specified magnitude in the same direction. Creates varied motion, useful for explosions. */
65
65
  readonly RandomMax: 3;
66
66
  };
67
+ /**
68
+ * Enum used to represent how a ragdolled character should exit the ragdoll state.
69
+ * @static
70
+ * @readonly
71
+ * @enum {number}
72
+ * @see {@linkcode IActiveRagdoll.Destroy}
73
+ */
74
+ static ExitMode: {
75
+ /** Character will play the appropriate getup animation and stand up on their own. Default behavior. */
76
+ readonly Smooth: 0;
77
+ /** Character will be restored at its current exact ragdoll position, standing with no fade or animations */
78
+ readonly Immediate: 1;
79
+ };
67
80
  private static readonly _activeRagdolls;
68
81
  private static MakeProxies;
69
82
  private static CreateActiveRagdollR6;
@@ -81,7 +94,7 @@ export declare class Falldown {
81
94
  * @see {@linkcode Falldown.UnragdollCharacter}
82
95
  * @see {@linkcode Falldown.VelocityMode}
83
96
  */
84
- static RagdollCharacter(character: Model, standupFadeTime: number, automaticDuration?: number, getupFront?: Animation, getupBack?: Animation): IActiveRagdoll | undefined;
97
+ static RagdollCharacter(character: Model, standupFadeTime: number, automaticDuration?: number, exitMode?: (typeof Falldown.ExitMode)[keyof typeof Falldown.ExitMode], getupFront?: Animation, getupBack?: Animation): IActiveRagdoll | undefined;
85
98
  /**
86
99
  * Manually ends the ragdoll state for a specific character. Equivalent to calling {@linkcode IActiveRagdoll.Destroy} on the ragdoll instance. If the character is not currently ragdolled, this method does nothing.
87
100
  * @static
@@ -91,7 +104,13 @@ export declare class Falldown {
91
104
  * @see {@linkcode Falldown.RagdollCharacter}
92
105
  * @see {@linkcode Falldown.UnragdollAllCharacters}
93
106
  */
94
- static UnragdollCharacter(character: Model, delayTime?: number): void;
107
+ static UnragdollCharacter(character: Model, delayTime?: number, exitMode?: (typeof Falldown.ExitMode)[keyof typeof Falldown.ExitMode]): void;
108
+ /**
109
+ * @static
110
+ * @param character - The character `Model` to check
111
+ * @returns Whether the character is currently ragdolled
112
+ */
113
+ static IsCharacterRagdolled(character: Model): boolean;
95
114
  /**
96
115
  * Ends the ragdoll state for ALL currently ragdolled characters. Useful for game-wide effects like round resets or emergency cleanup. Each character performs their getup animation independently.
97
116
  * @static
@@ -99,5 +118,5 @@ export declare class Falldown {
99
118
  * @see {@linkcode Falldown.UnragdollCharacter}
100
119
  * @see {@linkcode Falldown.RagdollCharacter}
101
120
  */
102
- static UnragdollAllCharacters(delayTime?: number): void;
121
+ static UnragdollAllCharacters(delayTime?: number, exitMode?: (typeof Falldown.ExitMode)[keyof typeof Falldown.ExitMode]): void;
103
122
  }
package/out/init.luau CHANGED
@@ -374,7 +374,7 @@ do
374
374
  local self = setmetatable({}, ActiveRagdoll)
375
375
  return self:constructor(...) or self
376
376
  end
377
- function ActiveRagdoll:constructor(character, objectiveHeight, standFadeTime, humanoid, humanoidRootPart, leftTouchObj, rightTouchObj, jointDestructionInfo, proxyGroupId, bodypartGroupId, proxyMapping, automaticDuration, getupFront, getupBack)
377
+ function ActiveRagdoll:constructor(character, objectiveHeight, standFadeTime, humanoid, humanoidRootPart, leftTouchObj, rightTouchObj, jointDestructionInfo, proxyGroupId, bodypartGroupId, proxyMapping, automaticDuration, exitMode, getupFront, getupBack)
378
378
  self.Destroyed = Signal.new()
379
379
  self.Ended = Signal.new()
380
380
  character.Destroying:Once(function()
@@ -417,7 +417,12 @@ do
417
417
  end
418
418
  if _condition ~= 0 and _condition == _condition and _condition then
419
419
  delay(self._automaticDuration, function()
420
- self:Destroy()
420
+ local _self = self
421
+ local _condition_1 = exitMode
422
+ if not (_condition_1 ~= 0 and _condition_1 == _condition_1 and _condition_1) then
423
+ _condition_1 = Falldown.ExitMode.Smooth
424
+ end
425
+ _self:Destroy(_condition_1)
421
426
  end)
422
427
  end
423
428
  end
@@ -492,7 +497,7 @@ do
492
497
  end
493
498
  end
494
499
  end
495
- function ActiveRagdoll:Destroy(overrideDeathLock)
500
+ function ActiveRagdoll:Destroy(exitMode, overrideDeathLock)
496
501
  if self.Character.Parent == nil then
497
502
  return nil
498
503
  end
@@ -502,55 +507,7 @@ do
502
507
  if #self._jointDestructionInfo == 0 or next(self._proxyMapping) == nil then
503
508
  return nil
504
509
  end
505
- local clonedCharacter = Instance.new("Model")
506
- clonedCharacter.Name = "Falldown_FadeClone_Temp"
507
- local humanoid = Instance.new("Humanoid")
508
- local animator = humanoid:FindFirstChildOfClass("Animator")
509
- humanoid.RigType = self.Humanoid.RigType
510
- humanoid.RequiresNeck = false
511
- humanoid.AutoRotate = false
512
- if animator then
513
- for _, anim in animator:GetPlayingAnimationTracks() do
514
- anim:Stop()
515
- end
516
- animator:Destroy()
517
- end
518
- local cloneCG = HttpService:GenerateGUID(false)
519
- PhysicsService:RegisterCollisionGroup(cloneCG)
520
- PhysicsService:CollisionGroupSetCollidable(cloneCG, "Default", false)
521
- PhysicsService:CollisionGroupSetCollidable(cloneCG, self._bodypartGroupId, false)
522
- PhysicsService:CollisionGroupSetCollidable(cloneCG, cloneCG, false)
523
- local cloneToRealMap = {}
524
- local originalTransparencies = {}
525
- for _, descendant in self.Character:GetDescendants() do
526
- if descendant:IsA("BasePart") then
527
- local partClone = descendant:Clone()
528
- partClone.Anchored = true
529
- partClone.CollisionGroup = cloneCG
530
- partClone.CFrame = descendant.CFrame
531
- cloneToRealMap[partClone] = descendant
532
- local _transparency = descendant.Transparency
533
- originalTransparencies[descendant] = _transparency
534
- for _1, partDesc in partClone:GetDescendants() do
535
- if partDesc:IsA("JointInstance") or partDesc:IsA("Constraint") or partDesc:IsA("Attachment") then
536
- partDesc:Destroy()
537
- elseif partDesc:IsA("Decal") then
538
- local _arg0 = descendant:FindFirstChild(partDesc.Name)
539
- local _transparency_1 = partDesc.Transparency
540
- originalTransparencies[_arg0] = _transparency_1
541
- end
542
- end
543
- partClone.Parent = clonedCharacter
544
- elseif descendant:IsA("Clothing") then
545
- local clothingClone = descendant:Clone()
546
- clothingClone.Parent = clonedCharacter
547
- end
548
- end
549
- humanoid.Parent = clonedCharacter
550
- clonedCharacter.Parent = Workspace
551
- for thing, originalTransparency in originalTransparencies do
552
- thing.Transparency = 1
553
- end
510
+ -- ── Shared: remove ragdoll constraints, restore Motor6Ds ──
554
511
  for _, info in self._jointDestructionInfo do
555
512
  info.Replaced.Enabled = true
556
513
  info.Constraint:Destroy()
@@ -574,21 +531,12 @@ do
574
531
  descendant.AssemblyAngularVelocity = Vector3.zero
575
532
  end
576
533
  end
577
- self.Humanoid.PlatformStand = false
578
- self.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
579
- self.HumanoidRootPart.Anchored = true
580
- --const thisAnimator = this.Humanoid.FindFirstChildOfClass("Animator");
581
- --if (thisAnimator) {
582
- -- for (const anim of thisAnimator.GetPlayingAnimationTracks()) {
583
- -- anim.Stop(0);
584
- -- }
585
- --}
534
+ -- ── Shared: destroy proxy parts ──
586
535
  for _, proxyPart in self._proxyMapping do
587
536
  proxyPart:Destroy()
588
537
  end
589
538
  table.clear(self._proxyMapping)
590
- local facing = ActiveRagdoll:GetVerticalDirection(self.HumanoidRootPart.CFrame.LookVector)
591
- local activeAnimation = nil
539
+ -- ── Shared: raycast for ground & compute stand CFrame ──
592
540
  local _cFrame = self.LeftTouchPart.CFrame
593
541
  local _cFrame_1 = CFrame.new(0, -(self.LeftTouchPart.Size.Y / 2), 0)
594
542
  local leftToes = _cFrame * _cFrame_1
@@ -627,6 +575,7 @@ do
627
575
  local gDot = gravity:Dot(groundNormal)
628
576
  local _arg0_1 = groundNormal * gDot
629
577
  local downhill = gravity - _arg0_1
578
+ local isSloped = downhill.Magnitude >= 0.05
630
579
  if downhill.Magnitude < 1e-3 then
631
580
  downhill = Vector3.new(0, 0, 1)
632
581
  end
@@ -646,7 +595,7 @@ do
646
595
  if along.Magnitude < 1e-3 then
647
596
  along = downhill
648
597
  end
649
- if along:Dot(downhill) < 0 then
598
+ if isSloped and along:Dot(downhill) < 0 then
650
599
  along = along * (-1)
651
600
  end
652
601
  return along.Unit
@@ -660,79 +609,10 @@ do
660
609
  end
661
610
  right = right.Unit
662
611
  local forwardOnSurface = right:Cross(groundNormal).Unit
663
- if facing == 0 then
664
- activeAnimation = self.GetupBackAnimation
665
- else
666
- activeAnimation = self.GetupFrontAnimation
667
- end
668
- task.spawn(function()
669
- if activeAnimation then
670
- local targetCFrame = CFrame.fromMatrix(centerPoint, forwardOnSurface, groundNormal)
671
- self.Character:PivotTo(targetCFrame)
672
- activeAnimation:Play(0, 1, 0)
673
- while not activeAnimation.IsPlaying do
674
- task.wait()
675
- end
676
- activeAnimation.TimePosition = 0.0
677
- task.wait()
678
- local activeLerp = 0
679
- task.spawn(function()
680
- while true do
681
- local dt = task.wait(1 / 60)
682
- local lerpAlpha = activeLerp + (dt / math.min(self._standFadeTime, activeAnimation.Length))
683
- local ended = false
684
- if lerpAlpha >= 1 then
685
- ended = true
686
- lerpAlpha = 1
687
- end
688
- for partClone, realPart in cloneToRealMap do
689
- partClone.CFrame = partClone.CFrame:Lerp(realPart.CFrame, lerpAlpha)
690
- end
691
- activeLerp = lerpAlpha
692
- if ended then
693
- for partClone, realPart in cloneToRealMap do
694
- partClone:Destroy()
695
- end
696
- for thing, originalTransparency in originalTransparencies do
697
- thing.Transparency = originalTransparency
698
- end
699
- return nil
700
- end
701
- end
702
- end)
703
- activeAnimation:AdjustSpeed(1)
704
- activeAnimation.Ended:Wait()
705
- else
706
- local targetCFrame = CFrame.fromMatrix(centerPoint, forwardOnSurface, groundNormal)
707
- self.Character:PivotTo(targetCFrame)
708
- task.wait()
709
- local activeLerp = 0
710
- task.spawn(function()
711
- while true do
712
- local dt = task.wait(1 / 60)
713
- local lerpAlpha = activeLerp + (dt / self._standFadeTime)
714
- local ended = false
715
- if lerpAlpha >= 1 then
716
- ended = true
717
- lerpAlpha = 1
718
- end
719
- for partClone, realPart in cloneToRealMap do
720
- partClone.CFrame = partClone.CFrame:Lerp(realPart.CFrame, lerpAlpha)
721
- end
722
- activeLerp = lerpAlpha
723
- if ended then
724
- for partClone, realPart in cloneToRealMap do
725
- partClone:Destroy()
726
- end
727
- for thing, originalTransparency in originalTransparencies do
728
- thing.Transparency = originalTransparency
729
- end
730
- return nil
731
- end
732
- end
733
- end)
734
- task.wait(self._standFadeTime)
735
- end
612
+ local targetCFrame = CFrame.fromMatrix(centerPoint, forwardOnSurface, groundNormal)
613
+ if exitMode == Falldown.ExitMode.Immediate then
614
+ -- ── Immediate: snap character to standing pose, no clone or animation ──
615
+ self.Character:PivotTo(targetCFrame)
736
616
  for _, descendant in self.Character:GetDescendants() do
737
617
  if descendant:IsA("BasePart") then
738
618
  descendant.Anchored = false
@@ -746,21 +626,174 @@ do
746
626
  end
747
627
  self.Humanoid.PlatformStand = false
748
628
  self.HumanoidRootPart.Anchored = false
749
- RunService.Heartbeat:Wait()
629
+ self.Humanoid.EvaluateStateMachine = true
630
+ self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
631
+ self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
632
+ self.Humanoid:ChangeState(Enum.HumanoidStateType.Running)
750
633
  task.defer(function()
751
634
  while self.Humanoid.MoveDirection.Magnitude <= 0 do
752
635
  RunService.Stepped:Wait()
753
636
  end
754
637
  self.HumanoidRootPart:SetNetworkOwner(self.Owner)
755
638
  end)
756
- self.Humanoid.EvaluateStateMachine = true
757
- self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
758
- self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
759
- self.Humanoid:ChangeState(Enum.HumanoidStateType.Running)
760
639
  self.Ended:Fire()
761
640
  self.Ended:Destroy()
762
- clonedCharacter:Destroy()
763
- end)
641
+ else
642
+ -- ── Smooth: create fade clone, play getup animation, tween ──
643
+ local clonedCharacter = Instance.new("Model")
644
+ clonedCharacter.Name = "Falldown_FadeClone_Temp"
645
+ local humanoid = Instance.new("Humanoid")
646
+ local animator = humanoid:FindFirstChildOfClass("Animator")
647
+ humanoid.RigType = self.Humanoid.RigType
648
+ humanoid.RequiresNeck = false
649
+ humanoid.AutoRotate = false
650
+ if animator then
651
+ for _, anim in animator:GetPlayingAnimationTracks() do
652
+ anim:Stop()
653
+ end
654
+ animator:Destroy()
655
+ end
656
+ local cloneCG = HttpService:GenerateGUID(false)
657
+ PhysicsService:RegisterCollisionGroup(cloneCG)
658
+ PhysicsService:CollisionGroupSetCollidable(cloneCG, "Default", false)
659
+ PhysicsService:CollisionGroupSetCollidable(cloneCG, self._bodypartGroupId, false)
660
+ PhysicsService:CollisionGroupSetCollidable(cloneCG, cloneCG, false)
661
+ local cloneToRealMap = {}
662
+ local originalTransparencies = {}
663
+ for _, descendant in self.Character:GetDescendants() do
664
+ if descendant:IsA("BasePart") then
665
+ local partClone = descendant:Clone()
666
+ partClone.Anchored = true
667
+ partClone.CollisionGroup = cloneCG
668
+ partClone.CFrame = descendant.CFrame
669
+ cloneToRealMap[partClone] = descendant
670
+ local _transparency = descendant.Transparency
671
+ originalTransparencies[descendant] = _transparency
672
+ for _1, partDesc in partClone:GetDescendants() do
673
+ if partDesc:IsA("JointInstance") or partDesc:IsA("Constraint") or partDesc:IsA("Attachment") then
674
+ partDesc:Destroy()
675
+ elseif partDesc:IsA("Decal") then
676
+ local _arg0_2 = descendant:FindFirstChild(partDesc.Name)
677
+ local _transparency_1 = partDesc.Transparency
678
+ originalTransparencies[_arg0_2] = _transparency_1
679
+ end
680
+ end
681
+ partClone.Parent = clonedCharacter
682
+ elseif descendant:IsA("Clothing") then
683
+ local clothingClone = descendant:Clone()
684
+ clothingClone.Parent = clonedCharacter
685
+ end
686
+ end
687
+ humanoid.Parent = clonedCharacter
688
+ clonedCharacter.Parent = Workspace
689
+ for thing, originalTransparency in originalTransparencies do
690
+ thing.Transparency = 1
691
+ end
692
+ self.Humanoid.PlatformStand = false
693
+ self.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
694
+ self.HumanoidRootPart.Anchored = true
695
+ local facing = ActiveRagdoll:GetVerticalDirection(self.HumanoidRootPart.CFrame.LookVector)
696
+ local activeAnimation = nil
697
+ if facing == 0 then
698
+ activeAnimation = self.GetupBackAnimation
699
+ else
700
+ activeAnimation = self.GetupFrontAnimation
701
+ end
702
+ task.spawn(function()
703
+ if activeAnimation then
704
+ self.Character:PivotTo(targetCFrame)
705
+ activeAnimation:Play(0, 1, 0)
706
+ while not activeAnimation.IsPlaying do
707
+ task.wait()
708
+ end
709
+ activeAnimation.TimePosition = 0.0
710
+ task.wait()
711
+ local activeLerp = 0
712
+ task.spawn(function()
713
+ while true do
714
+ local dt = task.wait(1 / 60)
715
+ local lerpAlpha = activeLerp + (dt / math.min(self._standFadeTime, activeAnimation.Length))
716
+ local ended = false
717
+ if lerpAlpha >= 1 then
718
+ ended = true
719
+ lerpAlpha = 1
720
+ end
721
+ for partClone, realPart in cloneToRealMap do
722
+ partClone.CFrame = partClone.CFrame:Lerp(realPart.CFrame, lerpAlpha)
723
+ end
724
+ activeLerp = lerpAlpha
725
+ if ended then
726
+ for partClone, realPart in cloneToRealMap do
727
+ partClone:Destroy()
728
+ end
729
+ for thing, originalTransparency in originalTransparencies do
730
+ thing.Transparency = originalTransparency
731
+ end
732
+ return nil
733
+ end
734
+ end
735
+ end)
736
+ activeAnimation:AdjustSpeed(1)
737
+ activeAnimation.Ended:Wait()
738
+ else
739
+ self.Character:PivotTo(targetCFrame)
740
+ task.wait()
741
+ local activeLerp = 0
742
+ task.spawn(function()
743
+ while true do
744
+ local dt = task.wait(1 / 60)
745
+ local lerpAlpha = activeLerp + (dt / self._standFadeTime)
746
+ local ended = false
747
+ if lerpAlpha >= 1 then
748
+ ended = true
749
+ lerpAlpha = 1
750
+ end
751
+ for partClone, realPart in cloneToRealMap do
752
+ partClone.CFrame = partClone.CFrame:Lerp(realPart.CFrame, lerpAlpha)
753
+ end
754
+ activeLerp = lerpAlpha
755
+ if ended then
756
+ for partClone, realPart in cloneToRealMap do
757
+ partClone:Destroy()
758
+ end
759
+ for thing, originalTransparency in originalTransparencies do
760
+ thing.Transparency = originalTransparency
761
+ end
762
+ return nil
763
+ end
764
+ end
765
+ end)
766
+ task.wait(self._standFadeTime)
767
+ end
768
+ for _, descendant in self.Character:GetDescendants() do
769
+ if descendant:IsA("BasePart") then
770
+ descendant.Anchored = false
771
+ descendant.AssemblyLinearVelocity = Vector3.zero
772
+ descendant.AssemblyAngularVelocity = Vector3.zero
773
+ if descendant:GetAttribute("Falldown_Reverse_CC_To") ~= nil then
774
+ descendant.CanCollide = descendant:GetAttribute("Falldown_Reverse_CC_To")
775
+ descendant:SetAttribute("Falldown_Reverse_CC_To", nil)
776
+ end
777
+ end
778
+ end
779
+ self.Humanoid.PlatformStand = false
780
+ self.HumanoidRootPart.Anchored = false
781
+ RunService.Heartbeat:Wait()
782
+ task.defer(function()
783
+ while self.Humanoid.MoveDirection.Magnitude <= 0 do
784
+ RunService.Stepped:Wait()
785
+ end
786
+ self.HumanoidRootPart:SetNetworkOwner(self.Owner)
787
+ end)
788
+ self.Humanoid.EvaluateStateMachine = true
789
+ self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
790
+ self.Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
791
+ self.Humanoid:ChangeState(Enum.HumanoidStateType.Running)
792
+ self.Ended:Fire()
793
+ self.Ended:Destroy()
794
+ clonedCharacter:Destroy()
795
+ end)
796
+ end
764
797
  PhysicsService:UnregisterCollisionGroup(self._proxyGroupId)
765
798
  PhysicsService:UnregisterCollisionGroup(self._bodypartGroupId)
766
799
  self.Destroyed:Fire()
@@ -826,7 +859,7 @@ do
826
859
  end
827
860
  return proxyMap
828
861
  end
829
- function Falldown:CreateActiveRagdollR6(character, humanoid, standFadeTime, automaticDuration, getupFront, getupBack)
862
+ function Falldown:CreateActiveRagdollR6(character, humanoid, standFadeTime, automaticDuration, exitMode, getupFront, getupBack)
830
863
  local leftArm = character:FindFirstChild("Left Arm")
831
864
  local rightArm = character:FindFirstChild("Right Arm")
832
865
  local leftLeg = character:FindFirstChild("Left Leg")
@@ -844,7 +877,7 @@ do
844
877
  local _cFrame_2 = rightLeg.CFrame
845
878
  local _cFrame_3 = CFrame.new(0, -rightLeg.Size.Y / 2, 0)
846
879
  local endPos = _:Lerp((_cFrame_2 * _cFrame_3).Position, 0.5)
847
- local height = (primaryPos - endPos).Magnitude
880
+ local height = math.abs(primaryPos.Y - endPos.Y)
848
881
  humanoid:ChangeState(Enum.HumanoidStateType.Physics)
849
882
  local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid)
850
883
  local getupFrontTrack = if getupFront then animator:LoadAnimation(getupFront) else nil
@@ -1064,9 +1097,9 @@ do
1064
1097
  end
1065
1098
  end
1066
1099
  humanoid.EvaluateStateMachine = false
1067
- return ActiveRagdoll.new(character, height, standFadeTime, humanoid, humanoidRootPart, leftLeg, rightLeg, destructionInfo, proxyGroupId, bodypartGroupId, ProxyMapping, automaticDuration, getupFrontTrack, getupBackTrack)
1100
+ return ActiveRagdoll.new(character, height, standFadeTime, humanoid, humanoidRootPart, leftLeg, rightLeg, destructionInfo, proxyGroupId, bodypartGroupId, ProxyMapping, automaticDuration, exitMode, getupFrontTrack, getupBackTrack)
1068
1101
  end
1069
- function Falldown:CreateActiveRagdollR15(character, humanoid, standFadeTime, automaticDuration, getupFront, getupBack)
1102
+ function Falldown:CreateActiveRagdollR15(character, humanoid, standFadeTime, automaticDuration, exitMode, getupFront, getupBack)
1070
1103
  local leftUpperArm = character:FindFirstChild("LeftUpperArm")
1071
1104
  local leftLowerArm = character:FindFirstChild("LeftLowerArm")
1072
1105
  local leftHand = character:FindFirstChild("LeftHand")
@@ -1093,7 +1126,7 @@ do
1093
1126
  local _cFrame_2 = rightFoot.CFrame
1094
1127
  local _cFrame_3 = CFrame.new(0, -rightFoot.Size.Y / 2, 0)
1095
1128
  local endPos = _:Lerp((_cFrame_2 * _cFrame_3).Position, 0.5)
1096
- local height = (primaryPos - endPos).Magnitude
1129
+ local height = math.abs(primaryPos.Y - endPos.Y)
1097
1130
  humanoid:ChangeState(Enum.HumanoidStateType.Physics)
1098
1131
  local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid)
1099
1132
  local getupFrontTrack = if getupFront then animator:LoadAnimation(getupFront) else nil
@@ -1518,9 +1551,9 @@ do
1518
1551
  end
1519
1552
  end
1520
1553
  humanoid.EvaluateStateMachine = false
1521
- return ActiveRagdoll.new(character, height, standFadeTime, humanoid, humanoidRootPart, leftFoot, rightFoot, destructionInfo, proxyGroupId, bodypartGroupId, ProxyMapping, automaticDuration, getupFrontTrack, getupBackTrack)
1554
+ return ActiveRagdoll.new(character, height, standFadeTime, humanoid, humanoidRootPart, leftFoot, rightFoot, destructionInfo, proxyGroupId, bodypartGroupId, ProxyMapping, automaticDuration, exitMode, getupFrontTrack, getupBackTrack)
1522
1555
  end
1523
- function Falldown:RagdollCharacter(character, standupFadeTime, automaticDuration, getupFront, getupBack)
1556
+ function Falldown:RagdollCharacter(character, standupFadeTime, automaticDuration, exitMode, getupFront, getupBack)
1524
1557
  local __activeRagdolls = self._activeRagdolls
1525
1558
  local _character = character
1526
1559
  if __activeRagdolls[_character] ~= nil then
@@ -1531,7 +1564,7 @@ do
1531
1564
  return nil
1532
1565
  end
1533
1566
  if humanoid.RigType == Enum.HumanoidRigType.R6 then
1534
- local createdActiveRagdoll = self:CreateActiveRagdollR6(character, humanoid, standupFadeTime, automaticDuration, getupFront, getupBack)
1567
+ local createdActiveRagdoll = self:CreateActiveRagdollR6(character, humanoid, standupFadeTime, automaticDuration, exitMode, getupFront, getupBack)
1535
1568
  if createdActiveRagdoll then
1536
1569
  local __activeRagdolls_1 = self._activeRagdolls
1537
1570
  local _character_1 = character
@@ -1550,7 +1583,7 @@ do
1550
1583
  return nil
1551
1584
  end
1552
1585
  else
1553
- local createdActiveRagdoll = self:CreateActiveRagdollR15(character, humanoid, standupFadeTime, automaticDuration, getupFront, getupBack)
1586
+ local createdActiveRagdoll = self:CreateActiveRagdollR15(character, humanoid, standupFadeTime, automaticDuration, exitMode, getupFront, getupBack)
1554
1587
  if createdActiveRagdoll then
1555
1588
  local __activeRagdolls_1 = self._activeRagdolls
1556
1589
  local _character_1 = character
@@ -1570,7 +1603,7 @@ do
1570
1603
  end
1571
1604
  end
1572
1605
  end
1573
- function Falldown:UnragdollCharacter(character, delayTime)
1606
+ function Falldown:UnragdollCharacter(character, delayTime, exitMode)
1574
1607
  local __activeRagdolls = self._activeRagdolls
1575
1608
  local _character = character
1576
1609
  local activeRagdoll = __activeRagdolls[_character]
@@ -1583,7 +1616,11 @@ do
1583
1616
  local __activeRagdolls_2 = self._activeRagdolls
1584
1617
  local _character_2 = character
1585
1618
  __activeRagdolls_2[_character_2] = nil
1586
- activeRagdoll:Destroy()
1619
+ local _condition = exitMode
1620
+ if not (_condition ~= 0 and _condition == _condition and _condition) then
1621
+ _condition = Falldown.ExitMode.Smooth
1622
+ end
1623
+ activeRagdoll:Destroy(_condition)
1587
1624
  end
1588
1625
  end)
1589
1626
  else
@@ -1593,18 +1630,31 @@ do
1593
1630
  local __activeRagdolls_2 = self._activeRagdolls
1594
1631
  local _character_2 = character
1595
1632
  __activeRagdolls_2[_character_2] = nil
1596
- activeRagdoll:Destroy()
1633
+ local _condition = exitMode
1634
+ if not (_condition ~= 0 and _condition == _condition and _condition) then
1635
+ _condition = Falldown.ExitMode.Smooth
1636
+ end
1637
+ activeRagdoll:Destroy(_condition)
1597
1638
  end
1598
1639
  end
1599
1640
  end
1600
1641
  end
1601
- function Falldown:UnragdollAllCharacters(delayTime)
1642
+ function Falldown:IsCharacterRagdolled(character)
1643
+ local __activeRagdolls = self._activeRagdolls
1644
+ local _character = character
1645
+ return __activeRagdolls[_character] ~= nil
1646
+ end
1647
+ function Falldown:UnragdollAllCharacters(delayTime, exitMode)
1602
1648
  if delayTime ~= 0 and delayTime == delayTime and delayTime then
1603
1649
  delay(delayTime, function()
1604
1650
  for character, activeRagdoll in self._activeRagdolls do
1605
1651
  if self._activeRagdolls[character] ~= nil then
1606
1652
  self._activeRagdolls[character] = nil
1607
- activeRagdoll:Destroy()
1653
+ local _condition = exitMode
1654
+ if not (_condition ~= 0 and _condition == _condition and _condition) then
1655
+ _condition = Falldown.ExitMode.Smooth
1656
+ end
1657
+ activeRagdoll:Destroy(_condition)
1608
1658
  end
1609
1659
  end
1610
1660
  end)
@@ -1612,7 +1662,11 @@ do
1612
1662
  for character, activeRagdoll in self._activeRagdolls do
1613
1663
  if self._activeRagdolls[character] ~= nil then
1614
1664
  self._activeRagdolls[character] = nil
1615
- activeRagdoll:Destroy()
1665
+ local _condition = exitMode
1666
+ if not (_condition ~= 0 and _condition == _condition and _condition) then
1667
+ _condition = Falldown.ExitMode.Smooth
1668
+ end
1669
+ activeRagdoll:Destroy(_condition)
1616
1670
  end
1617
1671
  end
1618
1672
  end
@@ -1623,6 +1677,10 @@ do
1623
1677
  SplitEqual = 2,
1624
1678
  RandomMax = 3,
1625
1679
  }
1680
+ Falldown.ExitMode = {
1681
+ Smooth = 0,
1682
+ Immediate = 1,
1683
+ }
1626
1684
  Falldown._activeRagdolls = {}
1627
1685
  end
1628
1686
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/falldown",
3
- "version": "1.0.4",
3
+ "version": "1.1.1",
4
4
  "description": "A realistic ragdoll physics system for Roblox with smooth getup animations, collision management, and customizable velocity modes. Supports both R6 and R15 rigs with surface-aware positioning.",
5
5
  "main": "out/init.luau",
6
6
  "scripts": {