Hi, currently I’m working on a soccer game and I already made a lot of the game engine. Essentially when I shoot the ball from the client I send an event to the server and create a BodyForce to push the ball forward. The ball has set the touched event active and if it collides with the goalkeeper the ball is caught, so from the server I attached the ball to the goalkeeper.
The problem is from the client game I see the shoot going so fast and while the server process the logic the ball pass through the goalkeeper and goes behind him and studently appears in the goalkeeper hands, so that is a bad experience for the player perspective.
Is there any way to prevent that behavior?
Thinking about that I am wondering if I built the game engine with a wrong approach and maybe I should change how the game works using other techniques that do not show that behavior.
The touched event is unrelaible for fast moving parts, and sometimes doesn’t fire the touched event at all.
To prevent this use a region3 around the ball or raycast to the ball’s next position (You can’t do this since your using bodymovers), so region3 is the best option.
As far I tested, I agree with you. At this moment I’m thinking to change my game and change my current bodymovers engine (using the game physics) to a Bézier Curves behavior so I will have control to the ball movement and so to the players interaction with the ball.
Thank you all of you for the help, I just want to ask you if this could be a good approach to the Bezier soccer ball shoot function. This is the code for passing for example, this is executed from the server:
local function OnPlayerPass(player, playerPassTo)
releaseBallEvent:Fire()
--time
local t = 1
local ball = game.Workspace:FindFirstChild("Stadium").Field:WaitForChild("Ball")
--disable gravity
local bv = Instance.new("BodyVelocity")
bv.Velocity = Vector3.new(0,0,0)
bv.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
bv.P = 9000
bv.Parent = ball
--create the points based on the hearthbeat per seccond
local fps = t / RunService.Heartbeat:Wait()
local n = fps
local p0 = ball.Position
local p2 = playerPassTo.HumanoidRootPart.Position
local p1 = p0 + player.Character.HumanoidRootPart.CFrame.lookVector * ((p2-p0).magnitude / 2) + Vector3.new(0, 20, 0)
local bezier = Bezier.new(Bezier.quadBezier, n, p0, p1, p2)
--iterate for each point and set the ball position
for i = 0, n do
RunService.Heartbeat:Wait()
local p = bezier:calc(i/fps)
ball.Position = p
end
bv:Destroy()
ball.Position = p2
end
Yah it is, assuming there’s only one soccer ball at the same time, if you have multiple soccer balls at the same time consider adding them to a table and updating there positions. (But you porbably only have one soccer ball at a given time)
Make sure to add collision detection with ray-casting.