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 8 years ago
Edited 8 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:

01local Part = cannon -- this is the Part we will move
02local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
03local Time = 5 -- the time that the script will take to move the part
04local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
05local Debounce = false
06local Diff = newPos - Part.Position -- the difference between the two positions
07local Mag = Diff.magnitude -- the distance between the two parts
08local Direction = CFrame.new(Part.Position, newPos).lookVector
09function MovePart() -- function to move the Part
10    if Debounce then return end -- end the function if debounce is true
11    Debounce = true -- make Debounce true so the function can't run
12    for n = 0, Mag, Increment do
13        Part.CFrame = Part.CFrame + (Direction * Increment)
14        wait( (Time/Mag) * Increment )
15    end
16    Debounce = false
17end
18script.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...

01local Part = cannon -- this is the Part we will move
02local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
03local Time = 5 -- the time that the script will take to move the part
04local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
05local Debounce = false
06local Diff = newPos - Part.Position -- the difference between the two positions
07local Mag = Diff.magnitude -- the distance between the two parts
08local Direction = CFrame.new(Part.Position, newPos).lookVector
09 
10local RotationAngle = Part.CFrame * CFrame.Angles(-45, 0, 45)
11local RotationAxis = RotationAngle * Direction
12 
13function MovePart() -- function to move the Part
14    if Debounce then return end -- end the function if debounce is true
15    Debounce = true -- make Debounce true so the function can't run
View all 22 lines...

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 8 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 — 7y
0
game:GetService("RunService").Heartbeat:connect(function(waiting) return end) --Instantly ends to take up one frame... " ghostwalker13 2 — 7y
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 — 7y
Ad
Log in to vote
0
Answered by 8 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.

01function performRotation()
02    local n = 30
03    local movementTime = 3 
04    local movementIncrement = 0.1
05    external = true
06    while n == n do
07        Part.CFrame = Part.CFrame * CFrame.Angles(math.rad(0), math.rad(3), math.rad(0))
08        wait((movementIncrement / movementTime))
09        n = n - 1
10        if n == 0 then return end
11    end
12end
13parent.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