I am making a Spider-man swinging game, similar to others, where a rope appears at where you click.
I have an annoying bug where when the player hits a wall, or swings too fast, they spin uncontrollably. Here is a video:
I have tried a bunch of fixes, like changing the density of the part that is attached to the players hand to be bigger, changing the density to be smaller, changing the rope restitution, and others, and still cant find a solution.
Here is my current code, it creates a part that it welds to the players hand, then when you click it creates a rope that attaches to a part at the mouse, and the part at the hand:
local plrs = game:GetService("Players")
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local plr = plrs.LocalPlayer
local stateType = Enum.HumanoidStateType
local char = plr.Character or plr.CharacterAdded:Wait()
local hum = char:WaitForChild("Humanoid")
local PartA = Instance.new("Part")
local AttachmentA = Instance.new("Attachment")
local AttachmentB = Instance.new("Attachment")
local mouse = plr:GetMouse()
local rope = Instance.new("RopeConstraint")
local testing = true
local handPart = Instance.new("Part")
local testHum = workspace.testhum
local fall = false
local anims = game.ReplicatedStorage.Animations
local randNum = nil
local camToggle = false
local swinging
local chargeCapacity
local physicsOn
local charging
local MAX_LENGTH = 300
local MAX_CAPACITY = 15
local JUMP_POWER = 1000
local CHARGED_MAX_POWER = 4250
local s1
local s2
local swing1Track
local swing2Track
local charge
local hand = char:WaitForChild("RightHand")
local properties = PhysicalProperties.new(2, 0 ,0)
handPart.Parent = hand
handPart.Position = hand.Position
handPart.CanCollide = false
handPart.Transparency = 1
handPart.CustomPhysicalProperties = properties
local const = Instance.new("WeldConstraint")
const.Part0 = handPart
const.Part1 = hand
const.Parent = workspace
local function preloadAnims(folder)
local desc = folder:GetChildren()
for i, v in desc do
print(i)
local track = hum.Animator:LoadAnimation(v)
track:Play()
task.wait()
track:Stop()
end
end
local function playAnim(anim)
local track = hum.Animator:LoadAnimation(anim)
track:Play(0.35)
return track
end
preloadAnims(anims)
mouse.Icon = "rbxassetid://83537166843785"
AttachmentA.Parent = PartA
AttachmentA.Position = Vector3.zero
AttachmentB.Parent = handPart
AttachmentB.Position = Vector3.zero
PartA.Parent = workspace
PartA.CanCollide = false
PartA.Anchored = true
local function Web(state)
if state == "shoot" then
PartA.Transparency = 1
PartA.Position = mouse.Hit.Position
local distance = PartA.Position - char.RightHand.Position
if distance.Magnitude < MAX_LENGTH then
hum:ChangeState("Physics")
physicsOn = true
rope.Length = distance.Magnitude
rope.Attachment0 = AttachmentA
rope.Attachment1 = AttachmentB
rope.Parent = workspace
rope.Visible = true
rope.Restitution = 0.15
rope.Enabled = true
rope.Thickness = 0.5
rope.Color = BrickColor.White()
print(distance.Magnitude)
return distance.Magnitude
end
else
rope.Enabled = false
end
end
rs.RenderStepped:Connect(function()
if camToggle then
workspace.CurrentCamera.CFrame = CFrame.new(char.Head.CFrame.Position)
end
end)
uis.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if not charging then
randNum = math.random(1,2)
print(randNum)
swinging = true
Web("shoot")
swing1Track = nil
swing2Track = nil
if randNum == 1 then
swing1Track = playAnim(anims:WaitForChild("Swing1Still"))
else
swing2Track = playAnim(anims:WaitForChild("Swing2Still"))
end
end
end
if input.KeyCode == Enum.KeyCode.LeftShift then
hum.WalkSpeed *= 2
end
if input.KeyCode == Enum.KeyCode.F then
hum:ChangeState("GettingUp")
physicsOn = false
end
if input.KeyCode == Enum.KeyCode.E then
if camToggle then
camToggle = false
char.Head.Transparency = 0
plr.CameraMode = Enum.CameraMode.Classic
else
camToggle = true
char.Head.Transparency = 1
plr.CameraMode = Enum.CameraMode.LockFirstPerson
end
end
if input.KeyCode == Enum.KeyCode.Space then
if swinging then
Web("delete")
swinging = false
handPart:ApplyImpulse(Vector3.new(0,JUMP_POWER,0))
print(swing1Track)
print(swing2Track)
print(randNum)
if randNum == 1 then
swing1Track:Stop()
else
print(randNum)
swing2Track:Stop()
end
end
end
if input.KeyCode == Enum.KeyCode.LeftControl then
if not swinging and not physicsOn and hum.FloorMaterial ~= Enum.Material.Air then
task.wait()
if hum.FloorMaterial == Enum.Material.Air then return end
char.HumanoidRootPart.Anchored = true
charging = true
charge = playAnim(anims.BuildUp)
chargeCapacity = 1
repeat
task.wait(0.2)
if chargeCapacity == 0 then return end
chargeCapacity += 1
until chargeCapacity == MAX_CAPACITY or chargeCapacity == 0
print(chargeCapacity)
end
end
end)
uis.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
Web("delete")
task.wait()
if swinging then
swinging = false
print(swing1Track)
print(swing2Track)
print(randNum)
if randNum == 1 then
swing1Track:Stop()
else
print(randNum)
swing2Track:Stop()
end
end
end
if input.KeyCode == Enum.KeyCode.LeftControl then
if not swinging and not physicsOn and hum.FloorMaterial ~= Enum.Material.Air then
char.HumanoidRootPart.Anchored = false
local amount = CHARGED_MAX_POWER/MAX_CAPACITY
charging = false
print(amount)
print(chargeCapacity*amount)
handPart:ApplyImpulse(Vector3.new(0,chargeCapacity*amount,0))
charge:Stop()
chargeCapacity = 0
end
end
if input.KeyCode == Enum.KeyCode.LeftShift then
hum.WalkSpeed /= 2
end
end)
hum.FallingDown:Connect(function()
hum:ChangeState("Running")
end)
Thanks in advance.