Hello. My current issue is that rotating an accessory works the first time, but after that it kind of freaks out. It also ends up messing up my other handles.
Also, some accessories will rotate in the opposite direction than intended.
I figure the issue is because I basically copied my moveAccessory function, which does work, and tried to replace parts of the script for rotation, but I can’t really wrap my head around how I’d fix this.
Below is my rotateAccessory function.
local function rotateAccessory(axis, relativeAngle)
local primaryPart = getPrimaryPart(currentAccessory)
local worldAxis = Vector3.FromAxis(axis)
local accessoryAxis = cframeAtMouseDown:VectorToWorldSpace(worldAxis)
local rotationCF = CFrame.fromAxisAngle(accessoryAxis, -relativeAngle)
local goalCF = rotationCF * cframeAtMouseDown
pendingTransformations.cframe = goalCF
hasPendingChanges = true
if primaryPart and primaryPart.AccessoryWeld then
if primaryPart.AccessoryWeld:IsA("Weld") then
primaryPart.AccessoryWeld.C0 = goalCF
else
primaryPart.AccessoryWeld.C1 = goalCF
end
end
local x, y, z = goalCF:ToOrientation()
onCoordinateChanged:Fire("Rotate", Vector3.new(x, y, z))
end
I just realized that I’m missing other chunks of my script that are likely going to be important in regards to this issue. I would also like to add that this script isn’t entirely my own as I had it revised and updated since I couldn’t wrap my head around creating working handles initially. Below is the
This function is meant to grab the state of an accessory before it gets moved/rotated/resized. but I feel like this might be the function that’s causing issues.
local function StoreOriginalData() --See how you can name the function properly after seperating function from connection?
if currentAccessory then
local primaryPart = getPrimaryPart(currentAccessory)
local specialMesh = getSpecialMesh(currentAccessory)
if primaryPart then
local AccessoryWeld = primaryPart.AccessoryWeld
if AccessoryWeld:IsA("Weld") then
cframeAtMouseDown = primaryPart.AccessoryWeld.C0 --Other scripts have convoluted functions to ensure function across multiple types of accessories, but i have yet to encounter an accessory that would not simply work like this
else
cframeAtMouseDown = primaryPart.AccessoryWeld.C1
end
if CurrentHandlesMode == "ResizeButton" then
if specialMesh then
vectorAtMouseDown = specialMesh.Scale
print("Stored original mesh scale:", vectorAtMouseDown)
else
vectorAtMouseDown = primaryPart.Size
print("Stored original part size:", vectorAtMouseDown)
end
elseif CurrentHandlesMode == "MoveButton" then
vectorAtMouseDown = cframeAtMouseDown.Position --primaryPart.Position
print("Stored original part size:", vectorAtMouseDown)
end
--Initialize pending transformations
pendingTransformations.size = nil
pendingTransformations.cframe = nil
pendingTransformations.specialMesh = specialMesh
pendingTransformations.accessoryWeld = primaryPart.AccessoryWeld
pendingTransformations.accessoryParts = getAccessoryParts(currentAccessory, primaryPart.AccessoryWeld)
hasPendingChanges = false
isDragging = true
HandlesBools["isDragging"] = true
print("Firing HandlesModeChanged event with:", HandlesBools)
HandlesModeChanged:Fire(HandlesBools)
end
end
end
Arc handles function
local function ManipulateByArcHandles(axis, relativeAngle)
if currentAccessory and isDragging then
local currentTime = tick()
-- Throttle resize events to prevent spam
if currentTime - lastResizeTime >= RESIZE_THROTTLE then
rotateAccessory(axis, relativeAngle)
lastResizeTime = currentTime
-- Update handles to match new orientation
if CurrentHandles and CurrentHandles.Adornee then
CurrentHandles.Adornee = getPrimaryPart(currentAccessory)
end
end
end
end
It might also be important to note that the only issue is the rotation function. I have other functions within the same script for moving accessories + resizing, that work perfectly fine until an accessory is rotated. Re-attaching accessories to other body parts and resizing them also has no issues, so I think I’ve narrowed down the causes to any one of these, but I’m unsure since I’ve been struggling with this for a few days by now.
I don’t exactly know what you mean by that, but I’m going to try and respond with what I think you meant.
The archandles seem to technically already be made in the correct position when they are initially made. I found that the issues with some accessories not rotating correctly only happens when the accessory has a c0 rotation that isn’t (0, 0, 0).
This was actually an issue I had with the arrow handles initially, but I basically used the function in the original post (asides from the fact this one is adjusted for rotation) to fix that issue. All I know is that the accessories’ c0 not being 0 is probably the reason why the archandles stop working properly after using them once.
I tried playing around with the rotateAccessory function in regards to worldAxis and accessoryAxis. I think I likely had the wrong impression that I could just translate the code for moving accessories into rotating accessories though, since the approach I have right now doesn’t seem to update the rotational orientation.
It might be worth it for me to revisit the script before I tried to translate the moveAccessory function into one for rotating accessories, although this is just another headache I don’t know how to wrap my head around.
The rotateAccessory function prior to me messing with it
local function rotateAccessory(axis, relativeAngle, deltaRadius)
if not player or not player.Character or not currentAccessory then return end
local primaryPart = getPrimaryPart(currentAccessory)
if not primaryPart then return end
--find the accessory in the player's character
local axisangle = Vector3.FromAxis(axis) * -relativeAngle
local goalCF = cframeAtMouseDown * CFrame.Angles(axisangle.X, axisangle.Y, axisangle.Z)
local cfX, cfY, cfZ = goalCF:ToOrientation()
local Orientation = Vector3.new(cfX, cfY, cfZ)
TransformationEvent:FireServer(primaryPart.AccessoryWeld, nil, goalCF, nil, nil)
onCoordinateChanged:Fire( "Rotate", Orientation)
end```
I received some outside help,. and it turns out the solution is a lot simpler than I had attempted.
Below is the fix.
local function rotateAccessory(axis, relativeAngle)
local primaryPart = getPrimaryPart(currentAccessory)
local worldAxis = Vector3.FromAxis(axis)
local rotationCF = CFrame.fromAxisAngle(worldAxis, -relativeAngle)
local goalCF = rotationCF * cframeAtMouseDown
pendingTransformations.cframe = goalCF
hasPendingChanges = true
if primaryPart and primaryPart.AccessoryWeld then
if primaryPart.AccessoryWeld:IsA("Weld") then
primaryPart.AccessoryWeld.C0 = goalCF
else
primaryPart.AccessoryWeld.C1 = goalCF
end
end
local x, y, z = goalCF:ToOrientation()
onCoordinateChanged:Fire("Rotate", Vector3.new(x, y, z))
end
I basically just needed to remove one line, and alter rotationCF a bit