I was actually doing some research on this for almost whole year
Well, there is 2-3 ways of doing that right now…
I will talk only about first 2 methods as the third one is extremely complicated
1st Method will make you rewrite most of your current code, but PROBABLY will help you achieve your goal perfectly! [SLIGHTLY COMPLICATED AND PERFOMANCE EXPENSIVE!]
2nd Method is a little easier but idk i still don’t trust roblox physics yk
First method requires some knowledge of “AABB” Collisions
Sorry but bean shape will turn into a square, its just not possible without some extra math which im really bad at
Second method will require you to do some raycasting
What you want to do for the first method:
- Create 2-3 bounding boxes, First one will be player’s, Second will be “predicted bbox” [OPTIONAL], Third one will be used to find all parts for AABB checks (make third bbox a little larger or equal to second bbox position to keep it somewhat accurate)
- Find some AABB module on internet that returns volume vector, pretty sure there is plenty of them. (Don’t forget rotation!)
- Create a loop in which Second bbox moves in the direction of player’s velocity, Then call :GetPartBoundsInBox() OR :GetTouchingParts() on third bbox and iterate every part it returned, if AABB module returned some vector volume then just push the second bbox to the closest free space.
- that should be enough!
Obviously i didn’t covered many small details here as it would made this reply even bigger but i hope it will give you somewhere to start from!
and sorry for not giving code example it would take me way too long for this one
Now let’s talk about second method!
I just thought it would be easiest way for you right now so why not
- Do multiple raycasts in the direction of player’s velocity, length should be ± same size as your bean
- From raycast results get raycast normals
- And just “push” away player in the direction of normal if you think he is way too close (dont forget to cancel/reduce/freeze the velocity or obviously its gonna look choppy)
I think thats it! Also i did small example for this one
--Dont mind the code btw i made it for a quick test =)
local hrp = script.Parent:WaitForChild("HumanoidRootPart")
local rp = RaycastParams.new()
rp.FilterType = Enum.RaycastFilterType.Blacklist
rp.FilterDescendantsInstances = {hrp.Parent}
game:GetService("RunService").RenderStepped:Connect(function()
local rey = workspace:Raycast(hrp.Position, Vector3.new(0, 0, 3))
if rey and rey.Instance and rey.Normal then
local x, y, z = hrp.CFrame:ToEulerAnglesXYZ()
hrp.CFrame = CFrame.new(rey.Position+(rey.Normal*3.001)) * CFrame.Angles(x, y, z)
--I don't know what kind of velocity you are using so just cancel/freeze it somewhere around here idk
end
end)
Let me know if i could help you!
btwbtw forgot to mention that for the most smoothest result just not let characters move in the direction of walls at all when they are too close
btwbtwbtw forgot to mention again that first method makes meshparts collisions not work at all