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!
This script (specifically the function GrappleSwing) creates a rope constraint that doesn’t appear in game but shows up in the explorer. - What is the issue? Include screenshots / videos if possible!
recording of the issue:
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I rewrote the section of code that isn’t working, and I might use beams later if it still isn’t fixed
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
code (StarterCharacterScripts → SourceMovementFramework):
--# Variables
--/ Services
local run = game:GetService("RunService")
local plrs = game:GetService("Players")
local cas = game:GetService("ContextActionService")
local uis = game:GetService("UserInputService")
local rs = game:GetService("ReplicatedStorage")
--/ Folders
local modules = rs:WaitForChild("modules")
local storage = rs:WaitForChild("storage")
--// Player and Character
--/ Base
local player : Player = plrs.LocalPlayer
local char : Model = player.Character or player.CharacterAdded:Wait()
--/ Character Parts
local root : Part = char:WaitForChild("HumanoidRootPart") or char.PrimaryPart
local humanoid : Humanoid = char:WaitForChild("Humanoid")
local RArm : Part = char:WaitForChild("Right Arm")
local RightHandAttach : Attachment = RArm:WaitForChild("RightGripAttachment")
--// Movement Variables
--/ Momentum
local RunningMomentumGainFactor = 0.5 -- how fast the player will gain momentum
local MomentumLossFactor = 3
local MinumumMomentum, MaximumMomentum = 5, 35
--/ Grounded Check
local LegHeight = 3.005 -- ray distance for grounded check
--/ Jumping
local JumpCooldown = 0.5
local JumpUpwardsVelocity = 10
local isJumping = false
--/ Gear
-- Grappler
local GrapplerCursorPart = storage:WaitForChild("GrapplerCursorPart")
local GrapplerAttach = GrapplerCursorPart:WaitForChild("GrapplerAttach")
local GrapplerCursorUI = GrapplerCursorPart:WaitForChild("GrapplerCursor")
local GrapplerRange = 50
local canGrapple = false
local grappleHooked = false
local grapplerHookCooldown = 0.25
--# Default Keybinds
local DefaultKeybinds = {
["Down Movement"] = Enum.KeyCode.LeftShift,
["Up Movement"] = Enum.KeyCode.Space,
["Dash"] = Enum.KeyCode.Q,
["Core Gear"] = Enum.KeyCode.E,
["Augment Gear"] = Enum.KeyCode.R
}
--// Math
local ceil = math.ceil
local pow = math.pow
local sqrt = math.sqrt
local clamp = math.clamp
local rad = math.rad
local deg = math.deg
local abs = math.abs
local sin = math.sin
local cos = math.cos
local inf = math.huge
local pi = math.pi
local rand = math.random
--# Functions
function momentum()
if humanoid.MoveDirection == Vector3.new(0, 0, 0) then
if humanoid.WalkSpeed > MinumumMomentum then
humanoid.WalkSpeed -= MomentumLossFactor
elseif humanoid.WalkSpeed < MinumumMomentum then
humanoid.WalkSpeed = MinumumMomentum
end
else
humanoid.WalkSpeed += RunningMomentumGainFactor
if humanoid.WalkSpeed >= MaximumMomentum - 1 then
humanoid.WalkSpeed = MaximumMomentum
end
end
end
function getVelocity()
return root.AssemblyLinearVelocity
end
function isGrounded()
-- param setup
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
-- actual ray
local raycastResult = workspace:Raycast(root.Position, Vector3.new(0, -(LegHeight), 0), raycastParams)
if raycastResult ~= nil then
return true
else
return false
end
end
function SetGrapplerToMouse()
local mouse = player:GetMouse()
local hitPosition = mouse.Hit.Position
if player:DistanceFromCharacter(hitPosition) <= GrapplerRange then
GrapplerCursorPart.Position = hitPosition
canGrapple = true
GrapplerCursorUI.Enabled = true
else
GrapplerCursorPart.Position = Vector3.new(0, inf, 0)
canGrapple = false
GrapplerCursorUI.Enabled = false
end
end
function GrappleHook(actionName, inputState, inputObj) -- yanking
if inputState == Enum.UserInputState.Begin then
print("hook")
grappleHooked = true
task.wait(grapplerHookCooldown)
grappleHooked = false
end
end
function GrappleSwing(actionName, inputState, inputObj) -- swinging
if inputState == Enum.UserInputState.Begin then
print("swing")
grappleHooked = true
local rope = Instance.new("RopeConstraint")
rope.Thickness = 0.1
rope.Name = "GrapplerRope"
rope.Color = BrickColor.Black()
rope.Length = GrapplerRange
rope.Enabled = true
rope.Attachment0 = GrapplerAttach
rope.Attachment1 = RightHandAttach
rope.Parent = RArm
rope.Visible = true
elseif inputState == Enum.UserInputState.End then
print("swing release")
grappleHooked = false
if RArm:FindFirstChild("GrapplerRope") then
RArm.GrapplerRope:Destroy()
end
end
end
function Grapple(actionName, inputState, inputObj) -- detect inputs
local mouse = player:GetMouse()
local hit = mouse.Hit
local target : Part = mouse.Target
if player:DistanceFromCharacter(hit.Position) <= GrapplerRange then
if target:HasTag("swing") then
GrappleSwing(actionName, inputState, inputObj)
else
GrappleHook(actionName, inputState, inputObj)
end
end
end
function GrapplerInit() -- initialize
local cursorClone : Part = GrapplerCursorPart:Clone()
cursorClone.Parent = workspace
cursorClone.Name = cursorClone.Name .. player.Name
GrapplerCursorPart = cursorClone
end
--// Start and Update (unity reference)
function Start()
GrapplerInit()
end
function OnRenderStepped()
-- Momentum
momentum()
-- Gear
SetGrapplerToMouse()
end
function OnHeartBeat()
end
--# Connections, Bindings, and setup
Start()
run.RenderStepped:Connect(OnRenderStepped)
run.Heartbeat:Connect(OnHeartBeat)
cas:BindAction("Grappler", Grapple, false, DefaultKeybinds["Core Gear"])