Calculating board angle gone wrong, help wanted

I want the board to properly align with the player’s hitbox, as shown:


(video demonstration reverted to a version where angle calculation was not added)

But when adding angle calculation for the board, it starts freaking out:


I’m not very good at math, so I’m not totally sure what could be causing this. Any help is appreciated.
Here’s the code for updating the board angle

rs.RenderStepped:Connect(function(delta) --updates board angle
	local boardAngle = skateModule.getBoardAngle(testingBoard,testingBoard.FrontEnd,testingBoard.BackEnd)
	if boardAngle then
		testingBoard.CFrame = hitbox.CFrame*CFrame.new(0,5,0)*CFrame.Angles(math.rad(boardAngle.X),math.rad(boardAngle.Y),math.rad(boardAngle.Z))
	else
		testingBoard.CFrame = hitbox.CFrame*CFrame.new(0,5,0)
	end
end)

And heres the code for calculating the board angle

function skateAnimations.getBoardAngle(board, frontPoint, backPoint)
	local boardRayParams = RaycastParams.new()
	boardRayParams.FilterType = Enum.RaycastFilterType.Exclude
	boardRayParams.IgnoreWater = true
	boardRayParams.FilterDescendantsInstances={CHARACTER, frontPoint, backPoint, board, workspace.testing}
	
	local raycastDistance = 20 --for testing, standardize later
	local raycastDirection = -board.CFrame.UpVector.Unit
	
	local function getGroundVector(position)
		local raycastResult = workspace:Raycast(position + Vector3.new(0,5,0), raycastDirection * raycastDistance, boardRayParams)
		makeRayVisible(raycastResult,position + Vector3.new(0,5,0),true)
		if raycastResult then
			return raycastResult.Position
		end

		return nil
	end

	local backGroundVector = getGroundVector(backPoint.WorldCFrame.Position)
	local frontGroundVector = getGroundVector(frontPoint.WorldCFrame.Position)
	
	if frontGroundVector and backGroundVector then
		local midPoint = (backGroundVector + frontGroundVector) / 2
		local direction = (frontGroundVector - backGroundVector).Unit

		local midpointRay = workspace:Raycast(midPoint + Vector3.new(0,1,0), raycastDirection * raycastDistance, boardRayParams)
		makeRayVisible(midpointRay,midPoint + Vector3.new(0,5,0),true,0.2,Color3.new(0, 0.333333, 0.498039))
		local normal = midpointRay and midpointRay.Normal or Vector3.new(0,1,0)

		local right = direction:Cross(normal).Unit
		local up = normal.Unit
		local forward = right:Cross(up).Unit
		
		local goalCFrame = CFrame.fromMatrix(midPoint, right, up)
		
		oriPart.CFrame = goalCFrame
		return oriPart.Orientation
	else
		warn('missing ground vector')
	end
end

BasePart.Orientation contains angles that, when applied in YXZ order, result in the rotational part of the CFrame of the part. The angles given to CFrame.Angles are applied in XYZ order.

Here’s the code that needs to be changed.

CFrame.Angles(math.rad(boardAngle.X),math.rad(boardAngle.Y),math.rad(boardAngle.Z))

Here are three alternative replacements for it.

CFrame.fromOrientation(math.rad(boardAngle.X),math.rad(boardAngle.Y),math.rad(boardAngle.Z))
CFrame.fromEulerAnglesYXZ(math.rad(boardAngle.X),math.rad(boardAngle.Y),math.rad(boardAngle.Z))
CFrame.fromEulerAngles(math.rad(boardAngle.X),math.rad(boardAngle.Y),math.rad(boardAngle.Z), Enum.RotationOrder.YXZ)

I’m not sure whether this change alone will fix the code. Also, what is the purpose of converting the CFrame to euler angles and then converting the euler angles back to a CFrame? Why don’t you just return the rotational part of the CFrame (CFrame whose rotation is same and position is a zero vector)? CFrame has a Rotation property for this.

Here’s what I mean. In skateAnimations.getBoardAngle:

return goalCFrame.Rotation

In the RenderStepped connection code:

rs.RenderStepped:Connect(function(delta) --updates board angle
	local boardRotation = skateModule.getBoardAngle(testingBoard,testingBoard.FrontEnd,testingBoard.BackEnd)
	if boardAngle then
		testingBoard.CFrame = hitbox.CFrame*CFrame.new(0,5,0)*boardRotation
	else
		testingBoard.CFrame = hitbox.CFrame*CFrame.new(0,5,0)
	end
end)
1 Like

Also, what is the purpose of converting the CFrame to euler angles and then converting the euler angles back to a CFrame?

Didn’t even realize I did this, made the code at like 4 am so it’s a little wack :grimacing: Thanks

After making the adjustments you suggested, the angle of the board seem to work better when entering a slope, but the board spinning persists:

Some more information,
The board spins slower as the hitbox’s y orientation approaches 0 or 180

Edit: after second look I found that culprit of the spinning is

testingBoard.CFrame = hitbox.CFrame*boardAngle

It’s taking the angle of the hitbox and adding it to the boards goal angle, causing the spinning

Does this work?

rs.RenderStepped:Connect(function(delta) --updates board angle
	local boardAngle = skateModule.getBoardAngle(testingBoard,testingBoard.FrontEnd,testingBoard.BackEnd)
	local offsettedCFrame = hitbox.CFrame*CFrame.new(0,5,0)
	if boardAngle then
		testingBoard.CFrame = boardAngle + offsettedCFrame.Position 
	else
		testingBoard.CFrame = offsettedCFrame
	end
end)
1 Like

I managed to find a solution outside of CFrames, but thank you for the help regardless!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.