# Casting Rays to the side to keep distance to the wall?

Hello community!

Maybe you saw my post regarding leaning with the hovercraft and now I am thinking about adding another thing. I was thinking on maybe adding something so the hovercraft cannot actually hit the walls and always keeps a distance to it.

I was thinking of maybe casting rays to the side of the vehicle and moving the hovercraft If needed ( if the hovercraft is to close to a wall ) So it never actually touches a wall and always keeps a distance :))

Any ideas on how to do this code-wise?
If not, any ideas on how to do this better?

Btw. having an invisible part acting as a hitbox isnt the solution I am looking for

3 Likes

What Iâ€™d do is detect if a part is intercepting the ray then Iâ€™d run the code to move the hovercraft.
Make sure to blacklist the hovercraft.

Why are you opposed to using invisible parts acting as hitboxes? Maybe you could use them in a way you are not considering (we can use them to avoid lots of raycasts and then perform some math to do the actual adjustments).

You may be interested in my GJK implementation. Given a function defining the convex hull of the hovercraft, it will find the distance to the wall. You can then use the rejection of the velocity on the wall to determine how long until a collision and thus how much force to apply to escape.

(Sorry, meant to update my last post)

That sounds very interesting, do you mind helping me out?
Sounds like it would work

I have a fairly simple way to do this. Iâ€™ll try to explain it as much as I can, but if you only want the code, Iâ€™ll have it at the bottom of the post.

First of all, letâ€™s define some constants:

``````local push_force = 30;
local check_dist = 10;

local origin = your_vehicle.PrimaryPart; -- change if needed, this is an example
local force = your_vehicle.BodyForce; -- this is your main force
``````

`check_dist` is your distance from the wall, `push_force` is the amount of force used to push your vehicle.
Now, letâ€™s get into the meat!

``````local rs = game:GetService("RunService");

local function check_dir(direction)
local ray = Ray.new(origin.Position, direction*check_dist);
local part = workspace:FindPartOnRayWithIgnoreList(ray, {your_vehicle});
if part then
return true;
end
return false;
end

rs.Heartbeat:Connect(function()
force.Force = Vector3.new(); -- reset force

for i = 1, 4 do
local direction;

if i == 1 then
direction = origin.CFrame.LookVector; -- front
elseif i == 2 then
direction = -origin.CFrame.LookVector; -- back
elseif i == 3 then
direction = origin.CFrame.RightVector; -- right
elseif i == 4 then
direction = -origin.CFrame.RightVector; -- left
end

if check_dir(direction) then
force.Force = force.Force + -direction*push_force;
end
end
end);
``````

`check_dir` checks whether a given direction is obstructed, using `check_dist` as the distance from the wall.
`force.Force = force.Force + -direction*push_force;` takes the direction, makes it negative (so it faces the opposite direction), multiplies it by `push_force` for the extra oomp, then finally adds it to the net force on `force`.

Final code:
``````local rs = game:GetService("RunService");

local push_force = 30;
local check_dist = 10;

local origin = your_vehicle.PrimaryPart; -- change if needed, this is an example
local force = your_vehicle.BodyForce; -- this is your main force

local function check_dir(direction)
local ray = Ray.new(origin.Position, direction*check_dist);
local part = workspace:FindPartOnRayWithIgnoreList(ray, {your_vehicle});
if part then
return true;
end
return false;
end

rs.Heartbeat:Connect(function()
force.Force = Vector3.new(); -- reset force

for i = 1, 4 do
local direction;
if i == 1 then
direction = origin.CFrame.LookVector; -- front
elseif i == 2 then
direction = -origin.CFrame.LookVector; -- back
elseif i == 3 then
direction = origin.CFrame.RightVector; -- right
elseif i == 4 then
direction = -origin.CFrame.RightVector; -- left
end

if check_dir(direction) then
force.Force = force.Force + -direction*push_force;
end
end
end);

``````

Hope I helped

This was typed on a mobile device so feel free to yell at me if thereâ€™s any mistakes

First of all I appreciate your help!
But inserting the code didnâ€™t work for me. I removed some errors that occured, example: Chaning Line 7, the Origin. Itâ€™s important to get the CFrame of that obj. In my example

``````local origin = script.Parent.Chassis.CFrame
``````

But for some reason itâ€™s not doing what it is supposed to do rn.
I inserted some print statements to see what he is detecting and it is printing everything out. every direction.

Code:

``````local rs = game:GetService("RunService");
local hovercraft = script.Parent

local push_force = 30;
local check_dist = 10;

local origin = hovercraft.Chassis.CFrame -- change if needed, this is an example
local force = hovercraft.Chassis.BodyForce; -- this is your main force

local function check_dir(direction)
local ray = Ray.new(origin.Position, direction*check_dist);
local part = workspace:FindPartOnRayWithIgnoreList(ray, {hovercraft});
if part then
return true;
end
return false;
end

rs.Heartbeat:Connect(function()
for i = 1, 4 do
local direction;
force.Force = Vector3.new(); -- reset force

if i == 1 then
print("Front")
direction = origin.LookVector; -- front
elseif i == 2 then
print("Back")
direction = -origin.LookVector; -- back
elseif i == 3 then
print("Right")
direction = origin.RightVector; -- right
elseif i == 4 then
print("Left")
direction = -origin.RightVector; -- left
end

if check_dir(direction) then
force.Force = force.Force + -direction*push_force;
end
end
end);
``````
1 Like

Maybe my ignorelist is wrong? Hovercraft is the whole model. Isnt that correct?

pushforce = 30 is faar too low to stop something like a hovecraft from colliding,maybe increase it to 200-1000 also you might wanna add the character in the ignore list aswell.

Aha! Thanks for pointing that out. In your edit, however, you referenced `origin.CFrame` only once at the beginning of the script, which will cause issues. Iâ€™ve edited my code and it should probably work a lot better.

Also fixed a small logical error, itâ€™s supposed to reset the force once per loop, but it was doing it four times.

Iâ€™ll try it out in a minute! :))

1 Like

Aight, because it is still not working, Iâ€™ll show some stuff so you guys can get a better understanding.
This is my Explorer tab for the hovercaft

I want it to push away from these walls

and I am using the code you have me in a diffrent normal script inside the hovercraft ( see photo 1 , itâ€™s called Collision )

Is `Collision` the script I sent earlier?
If so, you should probably switch to a LocalScript since client-sided physics is almost always better. If you havenâ€™t already, use SetNetworkOwner() from a Script so that the player can fully control the vehicleâ€™s physics without interference.

I tried that too now and It didnt seem to work hm.
Here is the whole model for you, I am sorry if it takes so long to figure out!
Thanks for the help!
hovercraftnew.rbxm (112.9 KB)

Alright. Its getting the distance and ray correctly . I checked it with a print statement to see when it â€śwouldâ€ť push the vehicle away from the wall.
But even with force 600 itâ€™s not doing much

Oh. Fixed it with changes to the force :)) 20k made it work. Iâ€™ll adjust it some more