Sup, I will try to explain the best I can.
I made a very basic plane concept you can observe below:
robloxapp-20220623-2023268.wmv (3.7 MB)
I used “LinearVelocity” instead of VectorForce btw. This is because LinearVelocity controls the speed meanwhile VectorForce just adds it. (If you wish to do a spaceship for example then vector force is very good to simulate non-drag compared to a plane).
Here I will show you all the assets I used:
Antigravity is a vector force relative to the world to contradict gravity. It doesn’t do anything else.
LinearVelocity is a constant value that is set to 100.
AlignOrientation is moving the current part to the desired destination. The desired destination is a part that is:
- Transparent
- Non-collidable
- Anchored
This part simply contains an attachment that is the destination. THIS is the attachment modified by the server script.
Now with that clear let’s first check the server script code which is the simplest we have:
local engine = workspace:WaitForChild("Engine"); --This is the transparent, non-collidable part.
local remoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent");
local currentX, currentY = 0,0; --This is the movement value to change
remoteEvent.OnServerEvent:Connect(function(client, x, y)
--[[
PLEASE perform a check to see if it is the actual pilot or else exploiters can abuse this by sending
modification requests acting as the pilot which will move the plane.
]]
currentX = x; --Set X movement
currentY = y; --Set Y movement
end);
while true do
task.wait();
engine.Orientation += Vector3.new(-currentY,-currentX,0); --Here, every iteration will add to the
-- destination's attachment which we'll move ever so slightly. Btw we are negating the value in
-- Y and X since if we don't it will go inversed.
end;
Now the localscript code.
To calculate how much we should move the plane we need to do something like this:
When your mouse is near the top-right corner we add, if it is in the bottom-left corner we subtract. I guess you don’t want to read the boring code but it is essential for this.
To calculate the percentage what we do is this:
(location.X/currentCamera.ViewportSize.X - 0.5) * 2 * maxHorizontal
location.X is the mouse’s X location.
currentCamera.ViewportSize.X is the total location. By dividing these 2 we get a percentage (the black text). To get the red text we substract that value by 0.5 (0.75 → 0.25) and then multiply by 2 thus giving you the red text. (0.75-0.5=0.25, 0.25*2 = 0.5).
(Red is desired value, black is normal value).
task.wait(1);
local UserInputService = game:GetService("UserInputService");
local remoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent");
local currentCamera = workspace.CurrentCamera; --Current Camera of the client
local maxHorizontal = 2.5; --THIS VALUE IS THE MAXIMUM IT CAN TURN PER ITERATION
local maxVertical = 1.25; --THIS VALUE IS THE MAXIMUM IT CAN TURN PER ITERATION
UserInputService.InputChanged:Connect(function(input)
if(input.UserInputType == Enum.UserInputType.MouseMovement) then
local location = UserInputService:GetMouseLocation();
remoteEvent:FireServer((location.X/currentCamera.ViewportSize.X - 0.5) * 2 * maxHorizontal, (location.Y/currentCamera.ViewportSize.Y - 0.5) * 2 * maxVertical);
-- Boring math I guess you wouldn't want to learn. What this does is get the total screen size:
-- (currentCamera.ViewportSize.X) and divide it to the current location. This will give a range of
-- 0 to 1 depending on the location. (Half-way is 0.5, a quarter of the way is 0.25 etc...)
-- Then we substract this value by 0.5 so that half way instead of being 0.5 is 0.
-- Then we multiply by 2 to exagerate the values. (100% would be 1 - 0.5 = 0.5 which is wrong,
-- that is why we multiply by 2 so it is 1 again)
end;
end);
game:GetService("RunService").RenderStepped:Connect(function() --Every render update the camera's position.
currentCamera.CameraType = Enum.CameraType.Scriptable;
currentCamera.CFrame = workspace:WaitForChild("Plane").CFrame * CFrame.new(0,0,20); --The actual part of
-- the plane.
end);
Join those 2 together and vualá! You have a plane system.
Another thing, I recommend you to add limitations to the orientation’s range. As you could see in the video it is good for military planes to go 100% up, but I feel that isn’t what a normal plane would do. This also can switch your perspective causing the addition to negate itself via the viewport’s orientation which would cause the perspective to shift accordingly preventing you to go back up.
Another thing, EXPERIMENT WITH THE Z AXIS! Imagine doing a barrel roll in a plane, that would be cool. As you see I am just using Y and X for movement, but you can add the A and S keys as Z movement to give barrel rolls, this will also fix the view perspective I told about above since you could do a barrel roll to change orientation again.