# How to make a tornado pull?

Hey, I’m making a weather system and I want to add a tornado to it. The tornado is a part with particle emitters and beams.

How would I make the tornado pull players and make them spin around the tornado while going upwards?

Any help is appreciated

2 Likes

I have never made a tornado, but I did at one time, make a giant toilet that made the players rotate around like a whirlpool if they were in the bowl when it flushed.

The way I did it, was to have a series of points, sort of in a ever tightening spiral as it moved down, and I would just use body movers (although now I would use AlignPosition) to move the players to each node.

However, if I were to re-do it, I would probably just use a mathematical formula, probably some sin and cos to move them with AlignPosition in a spiral motion.

1 Like

Yeah, I’m hoping to use some formula and use align position to create that spiral motion. Thank you

1 Like

you could make an invisible box around the tornado that carries false collisions so that when a player touches it then drag it spinning to the center, you could spin with Cframe.Angles from the HumanoidRootPart and also make it Cframe to the center or somew
here

I already have all the player’s HumanoidRootPart. I just need a function that pulls them toward the tornado with a force that increases the closer the player is to the tornado and then spirals the player up

You could try getting the difference in positions and then slightly rotating it!

I’m not sure what you mean by this.

`CFrame.fromEulerAngles((tornadoPosition - playercharacterPosition).Unit) * CFrame.Angles(0,3,0)`
Calculating the Vector3 force required to bring the player directly to the tornado, and then slightly turning the Vector3.

I see, and how would I apply the CFrame to the HumanoidRootPart? With a VectorForce, ApplyImpulse, etc.?

You could extract the LookVector and then use that in a LineForce or just set the velocity of the character itself.

How I imagine this would work is get the difference in CFrame from the player and the Tornado, we’ll call this Diff we’ll also store some distance data.

``````Diff = TornadoCFrame * Player.CFrame:Inverse()
CurrentDist
MaxDist = 300--maximum distance from the tornado
MinDist = 15--eye of the storm
``````

Then we offset that CFrame to get our next desired position.
We’ll call this NextCFrame

``````--rotate the tornado angle
``````

Next we need to calculate a direction to go FLING!
We’ll call this Fling it requires a few steps to set up

``````MaxPower = 300
FlingAngle = CFrame.new(CharacterPos,NextCFrame.Position).LookVector
FlingDist = (CharacterPos - NextCFrame.Position).Magnitude--how far away?
--get number between 1 and 0 to represent our distance from 15-300
FlingPower = (FlingDist - MinDist)/(MaxDist - MinDist)) -- 'ol reliable (Val - Min)/(Max - Min)
Fling = FlingAngle * (FlingPower*MaxPower)
``````

Then we should be able to apply this velocity to a player!

``````PrimaryPart.Velocity = Fling
``````

disclaimer: i wrote this all here and is untested incomplete. only conceptual code snippets to get a general idea of how something like this could work

hope that helps

4 Likes

How would I apply the Fling as Velocity is deprecated

AssemblyLinearVelocity

#30charrs

1 Like

Also please use local variables instead of global as that its better for long term use.

This is my current code

``````local MaxPower = 300
local MaxDist = 300
local MinDist = 15

RunService.Heartbeat:Connect(function()
for _,player in pairs(Players:GetPlayers()) do
local character = player.Character
if not character then continue end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then continue end

local Diff = tornado.Part.CFrame * humanoidRootPart.CFrame:Inverse()

local FlingAngle = CFrame.new(humanoidRootPart.Position, NextCFrame.Position).LookVector
local FlingDist = (humanoidRootPart.Position - NextCFrame.Position).Magnitude

local FlingPower = (FlingDist - MinDist)/(MaxDist - MinDist)
local Fling = FlingAngle * (FlingPower * MaxPower)

humanoidRootPart.AssemblyLinearVelocity = Fling
end
end)
end
``````

This is the result I’m getting. What is wrong?

I didn’t add force to throw you in the air. oops
Example:

``````UpForce = Vector3.new(0,FlingPower*MaxForce,0)--add more upward force the closer you get
Fling = Fling + UpForce
``````

also my calculations are probably wrong somewhere
untested code***

This is much better. However, the character is moved depending on what way it is facing. I think this has something to do with this line:

``````local FlingAngle = CFrame.new(humanoidRootPart.Position, NextCFrame.Position).LookVector
``````

How can I fix this?

Try using CFrame.lookAt to see if that changes anything.

That didn’t change anything

``````local FlingAngle = CFrame.lookAt(humanoidRootPart.Position, NextCFrame.Position).LookVector
``````

Try using CFrame for the position lines.