The new issue:
OLD BELOW:
I am attempting to write a physical wheel spinner however the issue is that the pointer is not getting the correct sector that it is over and it is also influenced by weight.
Not really sure why this is. I am using physics with weight however it is not too good so it will just default to the one the point lands on so I suppose you can say it doesn’t really take into account of weight.
The selected one is 1 however it lands on 5 but the script does not end up reflecting this.
I have an offset variable which is used to help calibrate the script to understand that it is at the first option (aka sector 1) and should spin correctly which seems it doesn’t.
Math has never been and will never be my strong suit.
I believe it has to do with the calculation from the following function:
local function getLandedSection(currentWheelAngleRadians)
if #sectionDefinitions == 0 or calculatedAnglePerSectionRadians <= 0 then
warn("SpinTheWheel: Cannot determine landed section, definitions or calculatedAnglePerSectionRadians invalid.")
local fallbackDef = (sectionDefinitions[1] and sectionDefinitions[1]) or {name = "Error"}
return {definition = fallbackDef, debugAngle = -1}
end
-- currentWheelAngleRadians is the physical rotation of the hinge.
-- The part of the wheel under the pointer was originally at -currentWheelAngleRadians relative to the hinge's zero.
local wheelAngleUnderPointer_Raw = normalizeAngleRadiansPositive(-currentWheelAngleRadians)
-- Adjust this raw angle based on the configured offset.
-- This gives us an angle relative to the *start* of the first logical section.
local angleRelativeToLogicalZero = normalizeAngleRadiansPositive(
wheelAngleUnderPointer_Raw - math.rad(CONFIG.WHEEL_ZERO_ANGLE_OFFSET_DEGREES)
)
local sectionIndexFloat = angleRelativeToLogicalZero / calculatedAnglePerSectionRadians
local sectionIndex = math.floor(sectionIndexFloat)
sectionIndex = math.max(0, math.min(sectionIndex, #sectionDefinitions - 1))
local landedSectionDef = sectionDefinitions[sectionIndex + 1]
if not landedSectionDef then
warn("SpinTheWheel: Failed to map angle to a section. RawHingeAngle: " .. string.format("%.2f", math.deg(currentWheelAngleRadians)) .. " deg, WheelAngleAtPointer_Raw: " .. string.format("%.2f", math.deg(wheelAngleUnderPointer_Raw)) .. " deg, AngleRelativeToLogicalZero: " .. string.format("%.2f", math.deg(angleRelativeToLogicalZero)) .. " deg, CalcIndex: " .. sectionIndex)
local fallbackDefOnError = (sectionDefinitions[1] and sectionDefinitions[1]) or {name = "MappingError"}
return {definition = fallbackDefOnError, debugAngle = angleRelativeToLogicalZero}
end
return {definition = landedSectionDef, debugAngle = angleRelativeToLogicalZero}
end
Config:
--[[
=========================================================================
CONFIGURATION TABLE
Adjust these values to customize the wheel's behavior.
=========================================================================
]]
local CONFIG = {
-- Section Weights (SectionName = WeightValue)
-- Used to determine the "announced" target section. Does NOT affect physical stopping.
SECTION_WEIGHTS = {
["1"] = 10, ["2"] = 5, ["3"] = 10, ["4"] = 2,
["5"] = 10, ["6"] = 5, ["7"] = 10, ["8"] = 1,
},
-- added this incase i want to add more sections but am not bothered about the weight of the new sectors.
DEFAULT_SECTION_WEIGHT = 5, -- Weight for sections not listed in SECTION_WEIGHTS.
-- Initial Spin Behavior
INITIAL_SPIN_MIN_ROTATIONS = 5, -- Minimum full rotations during the initial motor-driven phase.
INITIAL_SPIN_MAX_ROTATIONS = 10, -- Maximum full rotations during the initial motor-driven phase.
INITIAL_SPIN_SPEED_RPS = 1.5, -- Rotations Per Second for the initial motor spin.
MOTOR_MAX_TORQUE = 100000, -- Max torque for the HingeConstraint's motor (Nm).
-- Stopping Precision
STOP_VELOCITY_THRESHOLD_DPS = 0.5, -- Angular velocity (Degrees Per Second) below which the wheel is considered to be stopping.
MIN_STOP_DURATION_SECONDS = 2.75, -- How long the wheel's speed must be below threshold to be considered fully stopped.
-- For testing, will change this in the furture from a click detector
CLICK_MAX_ACTIVATION_DISTANCE = 60,
-- THIS IS FINE PLEASE DO NOT WORRY.
-- **** IMPORTANT CALIBRATION SETTING ****
WHEEL_ZERO_ANGLE_OFFSET_DEGREES = 0,
-- This is the clockwise angle (in degrees) from the Pointer's direction to the *starting edge*
-- of what your script considers the *first section* (e.g., 'Section 1', or the first in sorted order),
-- WHEN the `WheelHinge.CurrentAngle` is exactly 0.
-- Example:
-- - If your pointer is fixed at 12 o'clock:
-- - And the *starting edge* of 'Section 1' is at 12 o'clock when WheelHinge.CurrentAngle = 0, then offset is 0.
-- - If 'Section 1' *starts* at 3 o'clock when WheelHinge.CurrentAngle = 0, offset is 90.
-- - If 'Section 1' *starts* at 9 o'clock when WheelHinge.CurrentAngle = 0, offset is 270 (or -90).
-- Adjust this value until the script correctly reports the section the pointer is over.
}
--[[
END OF CONFIGURATION TABLE
=========================================================================
]]