Trouble with making skis

Hi! i have recently been working on a new project for making skis in roblox. But i have had alot of trouble with this. idk how to approach this or what methods to use. i have tried different methods like an invinsible ball and more. But the problem seems to be that its all very buggy. I would greatly appreciate any ideas :slight_smile:

2 Likes

Can you provide any videos or picture and maybe a script if you have any?

This is an older version btw

i have 2 issues first of all the walk animation is running and idk how to disable it

secodn fo all the player slowly start turning to the side for no good reason

local character = script.Parent
local rootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local RunService = game:GetService("RunService")

local SKI_SPEED = 40
local RAY_DISTANCE = 5 

RunService.RenderStepped:Connect(function()
	if not character or not rootPart then return end

	local rayOrigin = rootPart.Position
	local rayDirection = Vector3.new(0, -RAY_DISTANCE, 0)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {character}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local rayResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)

	if rayResult then
		local groundNormal = rayResult.Normal
		local forwardDirection = rootPart.CFrame.LookVector

		local rightVector = forwardDirection:Cross(groundNormal).Unit
		local correctedForward = groundNormal:Cross(rightVector).Unit


		local newCFrame = CFrame.fromMatrix(rootPart.Position, rightVector, groundNormal, -correctedForward)
		rootPart.CFrame = newCFrame

		
		local slopeAngle = math.deg(math.acos(groundNormal.Y))
		if slopeAngle > 5 then 
			rootPart.AssemblyLinearVelocity = correctedForward * SKI_SPEED
		else
			rootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
		end
	end
end)

I can’t really help with the raycast stuff since im still not into that stuff but about that
animation i can help:

First we need to set the animationId to rbxassetId//:0 meaning no animation should play

We can achieve this by copying and pasting the Animation Handler
Here is a small video on how to do that:

1 Like

How about overriding the default movement with ContextActionService:BindAction and adding a forwards force on the player?

Don’t have the time to write an in-detail explanation(I’m on mobile), but this should get you started for now:

game.ContextActionService:BindAction("Forward", function(_, inputState, _)
   if inputState == Enum.UserInputState.Begin then
      --increase players forward velocity
   else
      -- set players velocity to 0
   end
   return Enum.ContextActionResult.Sink
end, false, Enum.Keycode.W)

I might return to this tomorrow to help some more, however this should get you started for now.

2 Likes

i figured it out by testing old methods out again. and i setteled on the bal method with a hingeconstraint to the rootpart. and then alot of physics constraints

local character = script.Parent
local rootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local SKI_SPEED = 40
local RAY_DISTANCE = 5 

character.Animate:Destroy()

humanoid.PlatformStand = false

local Attachment = Instance.new("Attachment", rootPart)

local AlignOrientation = Instance.new("AlignOrientation", rootPart)
AlignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
AlignOrientation.Attachment0 = Attachment
AlignOrientation.Responsiveness = 200 -- How fast it reacts (higher = more instant)
AlignOrientation.MaxTorque = math.huge -- Infinite torque for strong rotation

local TurnSpeed = 1
local TurnDirection = 0

UserInputService.InputBegan:Connect(function(input)
	print(input.KeyCode)
	if input.KeyCode == Enum.KeyCode.A then
		TurnDirection = 1
	elseif input.KeyCode == Enum.KeyCode.D then
		TurnDirection = -1
	end	
end)

UserInputService.InputEnded:Connect(function(input)
	print(input.KeyCode)
	if input.KeyCode == Enum.KeyCode.A then
		TurnDirection = 0
	elseif input.KeyCode == Enum.KeyCode.D then
		TurnDirection = 0
	end	
end)

RunService.RenderStepped:Connect(function()
	if not character or not rootPart then return end
	
	
	if (character:WaitForChild("SkiModel").playerBall.Position - rootPart.Position).Magnitude > 2 then
		character.SkiModel.playerBall.CFrame = rootPart.CFrame * rootPart.Attachment0.CFrame
	end

	local rayOrigin = rootPart.Position
	local rayDirection = Vector3.new(0, -RAY_DISTANCE, 0)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {character}
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local rayResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)

	if rayResult then
		local groundNormal = rayResult.Normal
		local RightVector = rootPart.CFrame.RightVector
		local correctedForward = groundNormal:Cross(RightVector).Unit
		
		local yawRotation = CFrame.Angles(0, math.rad(TurnDirection * TurnSpeed), 0)

		local newCFrame = CFrame.fromMatrix(rootPart.Position, RightVector, groundNormal, -correctedForward)
		AlignOrientation.CFrame = newCFrame	 * yawRotation
		

		local slopeAngle = math.deg(math.acos(groundNormal.Y))
		if slopeAngle > 5 then 
			rootPart.AssemblyLinearVelocity = correctedForward * SKI_SPEED
		else
			rootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
		end
	end
	
end)