Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

CFrame-Intergrated Revolving-axis(es) - How?

Asked by 7 years ago
Edited 7 years ago

My current game in development requires the use of 'laser distributors' and 'laser receptacles', additionally paired with several more custom-made items.
My current focus is on the distributor, which requires for the 'nozzle' or 'cannon' (/'launcher') brick to revolve in an orbit around the distributor's turret brick, always sticking inside-of the hull of the the brick in question.

The nozzle/cannon brick is required to make 90-degree rotations, always having one end of the brick (which is a cylinder) inside the hull; that doesn't mean that it can't move, just that it needs to appear-to-be in the hull at all times.

My current script, which has served me very well in the making of sliding-doors and hidden-panels, derived from the Roblox Wiki Article concerning Part Sliding is seen as below:

local Part = cannon -- this is the Part we will move
local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
local Time = 5 -- the time that the script will take to move the part
local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
local Debounce = false
local Diff = newPos - Part.Position -- the difference between the two positions
local Mag = Diff.magnitude -- the distance between the two parts
local Direction = CFrame.new(Part.Position, newPos).lookVector
function MovePart() -- function to move the Part
    if Debounce then return end -- end the function if debounce is true
    Debounce = true -- make Debounce true so the function can't run
    for n = 0, Mag, Increment do
        Part.CFrame = Part.CFrame + (Direction * Increment)
        wait( (Time/Mag) * Increment )
    end
    Debounce = false
end
script.Parent.ClickDetector.MouseClick:connect(MovePart)

I have tried to modify it to suit my need of an additional 'rotationAxis' argument, but that has met a brick-wall. Figuratively, of course...

local Part = cannon -- this is the Part we will move
local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
local Time = 5 -- the time that the script will take to move the part
local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
local Debounce = false
local Diff = newPos - Part.Position -- the difference between the two positions
local Mag = Diff.magnitude -- the distance between the two parts
local Direction = CFrame.new(Part.Position, newPos).lookVector

local RotationAngle = Part.CFrame * CFrame.Angles(-45, 0, 45)
local RotationAxis = RotationAngle * Direction 

function MovePart() -- function to move the Part
    if Debounce then return end -- end the function if debounce is true
    Debounce = true -- make Debounce true so the function can't run
    for n = 0, Mag, Increment do
        Part.CFrame = Part.CFrame + ( (Direction * Increment) * RotationAxis * Mag)
        wait( (Time/Mag) * Increment )
    end
    Debounce = false
end
script.Parent.ClickDetector.MouseClick:connect(MovePart)

And bearing in mind that the Roblox Wiki's document on this is really really hard to understand, I can't fit my needs properly - hence why I came here.

To recap, the subject of assistance: Rotation Axis and Orbits: How do I create such thing?
If you have a viable solution, that is appreciated. Smiley face.

After-Note: It seems like I have solved the problem Myself. Albeit a bit 'laggy' and 'un-optimised', it serves well. You'll see my answer to the post.

2 answers

Log in to vote
0
Answered by 7 years ago

Some tips for potentially smoother animation:

  • Use lerp to interpolate between two different CFrames. If you can get the starting and goal CFrames, perform newCFrame = startCFrame:lerp(goalCFrame, timePassed/animationTime) every frame/update.
  • Ideally you should use Heartbeat ) if you want very smooth animation. This will be faster than using wait() (which waits for about 0.03 seconds, which is about what you're waiting for at the moment).
  • math.rad(0) == 0 (so you could simplify line 7 if you wanted)
0
Great answer! Sorry I couldn't get to you - a lot of stuff happening and me forgetting that this site exists... Anyway, I have a few questions: How would I integrate the Heartbeat Service into the lerp'ing? I already have a basic idea, " Part.CFrame = this.CFrame:lerp( (this.CFrame * fromEulerAngles(0, 90, 0) ), timePassed / animationTime) ghostwalker13 2 — 6y
0
game:GetService("RunService").Heartbeat:connect(function(waiting) return end) --Instantly ends to take up one frame... " ghostwalker13 2 — 6y
0
Looks like you've got the right idea. In the Heartbeat:connect line, instead of "return" you should have your code from your first comment. You'll need to increase 'timePassed' by 'waiting'. chess123mate 5873 — 6y
Ad
Log in to vote
0
Answered by 7 years ago

Yay, solving my own conundrum!
Instead of using the Wiki's script as a base line, I just used a 'while' loop.

From there... it built this.

function performRotation()
    local n = 30
    local movementTime = 3  
    local movementIncrement = 0.1
    external = true
    while n == n do
        Part.CFrame = Part.CFrame * CFrame.Angles(math.rad(0), math.rad(3), math.rad(0))
        wait((movementIncrement / movementTime))
        n = n - 1
        if n == 0 then return end
    end
end
parent.clickDetector.MouseClick:connect(performRotation)

I siphoned the Increment and Time variables, did a bit of searching and threw in a few mathematical operators. And by golly it worked. If you guys want to take this, feel free.

Answer this question