# How to add/expand the X axis in Velocity Script

Hello! I have a baseball game where players just play a standard game of baseball basically, but I’m having problem when the player hits a ball, and I have little to no scripting knowledge. The distance and the height when hit is fine, but the ball is only ever hit to the right side of the field with only a 10 stud deviation amount. I want the player to be able to hit to the left, center, and right sides of the field. Here’s what I want this to work:

And this is what it looks like: 2021 08 01 22 47 24 - YouTube

The Code
``````
function HitBall(hit)
local person=hit.Parent
if(person.ClassName=="Hat")then
wait()
elseif(person.Name=="Bat")and(person.Parent:findFirstChild("Humanoid")and ball.Parent==workspace)then
script.Disabled=true
if(ball.Handle:findFirstChild("BodyPosition"))then
ball.Handle.BodyPosition.Parent=ball end
ball.Handle.Anchored=true
wait(0.05)
ball.Handle.Anchored=false
if(human)then
ball.HitSound:Play()
ball.Handle.Velocity=(human.CFrame.lookVector*math.random(45,120))+Vector3.new(0,math.random(5,115),0)
local vel = ball.Handle.Velocity
local exitvel = vel.Magnitude -- exit velocity
local angled = (math.atan(vel.Y/(vel.X*vel.X + vel.Z*vel.Z)^0.5))*(180/math.pi) -- launch angle
local angler = (math.atan(vel.Y/(vel.X*vel.X + vel.Z*vel.Z)^0.5))
local distance = (((exitvel^2)*(math.sin(2*angler)))/59.416) -- home run distance
local function round(n)
return math.floor(n + 0.5)
end
print("X-VELO: " .. round((((vel.X)^2)+((vel.Z)^2))^0.5))
print("Y-VELO " .. round(vel.Y))
print("LAUNCH ANGLE: " .. round(angled))
print("EXIT VELOCITY: " .. round(exitvel))
print("DISTANCE: " .. round(distance))
local children = game.Players:GetChildren()
for i, child in ipairs(children) do
local gui = child.PlayerGui.ScreenGui.Frame
local distanceUI = gui.Distance
distanceUI.Text = (round(distance) .. " studs")
end

ball.ClickThrow.Disabled=true
ball.Power.MaxValue=140
ball.Power.MinValue=10
ball.ClickShoot.Disabled=false
end
ball.Power.Value = 115
wait(0.3)
ball.Catch.Disabled=false
wait(1)
script.Disabled=false
end
end

ball.Handle.Touched:connect(HitBall)
``````

To summarize this, I basically want to increase the range where the baseball can be hit to. Thanks all!

1 Like

Wacky script, looks like this is the line where it comes up with a velocity in a some-what random range:

``````ball.Handle.Velocity=(human.CFrame.lookVector*math.random(45,120))+Vector3.new(0,math.random(5,115),0)
``````

Try appending a new velocity for whatever you want the horizontal range to be:

``````(human.CFrame.rightVector * (math.random()*2 - 1) * 10)
``````

The above, will add a new velocity component which adds horizontal velocity in the range (-10, 10).
Ultimately the new line will look like:

``````ball.Handle.Velocity =
(human.CFrame.lookVector*math.random(45,120)) + -- Forward
(Vector3.new(0,math.random(5,115),0)) + -- Up
(human.CFrame.rightVector * (math.random()*2 - 1) * 10) -- Horizontal
``````

Edit:
I thought I’d mention that this script uses the head to decide what is ‘forward’ and ‘left/right’. Since its in an animation, you ultimately have very little control in what is the resulting direction - it all depends where in the animation the ball is hit. So the above might not feel perfect, and find yourself playing around with the numbers on that line or changing the following:
`local human=person.Parent:findFirstChild("Head")`
to something that has a smaller rotation range when the animation plays.

3 Likes

First off,

Thank you so much reply, let me tell you that you’ve probably single handedly saved this entire version of baseball.

But I just have two follow up questions which are:

How do I decrease the bounce off the ball off of the grass, walls, etc, and just make the hit overall softer. Right now it looks like this:

What it looks like

Whereas I want it to look more like this:

What I want

Right now the code looks like this

``````				(human.CFrame.lookVector*math.random(45,120)) + -- Forward
(Vector3.new(0,math.random(5,115),0)) + -- Up
(human.CFrame.rightVector * (math.random()*2 - 2) * 250) -- Horizontal
local vel = ball.Handle.Velocity
``````

Basically I just wanna know what to edit to have a more realistic bounce.

Secondly, what do I need to edit to make the ball go more in this territory:

this

Thank you so much for the help!

So the script is just adding a velocity once to the ball when you hit it - then lets Roblox’s physics engine take over the rest. So there’s really no logic in there for making it bounce less.
Easiest method would be to just change the physics of the ball:
https://developer.roblox.com/en-us/api-reference/property/BasePart/CustomPhysicalProperties
Less elasticity and more friction.

Also to hit it more in the range you want, think about changing out the variable human to something in line with the baseball field:

``````local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,math.rad(90),0)
ball.Handle.Velocity =
(lookCF.lookVector * math.random(45,120)) + -- Forward
(Vector3.fromAxis('Y') * math.random(5,115)) + -- Up
(lookCF.rightVector * math.random(-50, 50)) -- Horizontal
``````

Hi again! Everything so far has worked perfectly; the range, physics, and so forth have all been phenomenal and realistic using the current righty animations. Today I tried to use the ball on left handed animations and it didn’t go as well. The ball just goes backwards.

https://gyazo.com/7eeb15a31a078e26842cb77702e88ec6

Here is a gif showing this, and so far I have applied all of your edits including the second edit with the horizontal -50,50 range. If you have any idea how I can make this work with this animation and you have the time I’d really appreciate a reply. Thank you!

So what I did earlier with

``````local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,math.rad(90),0)
``````

Is I made up a new CFrame where whatever the character’s left side was the forward direction. The first part gets the torso and the second part rotates the CFrame of that 90 degrees CCW (left).

You need to find a way to know which way you’re hitting the ball from the script’s scope. Maybe have some tag (a folder named ‘HittingLeft’ under the character model). Then you can apply the right rotation:

``````local isLeft = human:FindFirstChild('HittingLeft')
local rotDirection = isLeft and -1 or 1
local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,math.rad(90) * rotDirection, 0)
``````

Also good to hear its going well!

Right now im testing it by making a righty ball and a lefty ball-- is there anyway to do it from there?

Of course,
if you have two scripts (Right hand) and (Left hand) then its easy.

We already solved right hand, so all you need to do is modify the right hand code for which way is ‘forward’ when batting left. This just changes the 90 degree rotation CCW to CW.

So in the original:

``````local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,math.rad(90),0)
``````

Becomes:

``````local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,-math.rad(90),0)
``````

Hi again,

I added the edit with the

``````(0,-math.rad(90),
``````

But now the bat doesnt make contact with the ball. The hitboxes seem to be intersecting:
https://gyazo.com/2417bde6db22cd3cc3c11e9406c9be01
but it just doesn’t seem to make contact. The regular righty bat and righty ball work normally though. Do you know how to fix this?

Okay- should just require some minor debugging.

Whats the full script, where is it placed, and how did you go about duplicating it to make a ‘left version’

ok so the entire script right now looks like this

``````local ball=script.Parent

function HitBall(hit)
local person=hit.Parent
if(person.ClassName=="Hat")then
wait()
elseif(person.Name=="Bat")and(person.Parent:findFirstChild("Humanoid")and ball.Parent==workspace)then
script.Disabled=true
if(ball.Handle:findFirstChild("BodyPosition"))then
ball.Handle.BodyPosition.Parent=ball end
ball.Handle.Anchored=true
wait(0.05)
ball.Handle.Anchored=false
if(human)then
ball.HitSound:Play()
local lookCF = person.Parent:FindFirstChild('HumanoidRootPart').CFrame * CFrame.Angles(0,-math.rad(90),
ball.Handle.Velocity =
(lookCF.lookVector * math.random(30,80)) + -- Forward
(Vector3.fromAxis('Y') * math.random(10,105)) + -- Up
(lookCF.rightVector * math.random(-50, 150)) -- Horizontal
local vel = ball.Handle.Velocity
local exitvel = vel.Magnitude -- exit velocity
local angled = (math.atan(vel.Y/(vel.X*vel.X + vel.Z*vel.Z)^0.5))*(180/math.pi) -- launch angle
local angler = (math.atan(vel.Y/(vel.X*vel.X + vel.Z*vel.Z)^0.5))
local distance = (((exitvel^2)*(math.sin(2*angler)))/59.416) -- home run distance
local function round(n)
return math.floor(n + 0.5)
end
print("X-VELO: " .. round((((vel.X)^2)+((vel.Z)^2))^0.5))
print("Y-VELO " .. round(vel.Y))
print("LAUNCH ANGLE: " .. round(angled))
print("EXIT VELOCITY: " .. round(exitvel))
print("DISTANCE: " .. round(distance))
local children = game.Players:GetChildren()
for i, child in ipairs(children) do
local gui = child.PlayerGui.ScreenGui.Frame
local distanceUI = gui.Distance
distanceUI.Text = (round(distance) .. " studs")
end

ball.ClickThrow.Disabled=true
ball.Power.MaxValue=140
ball.Power.MinValue=10
ball.ClickShoot.Disabled=false
end
ball.Power.Value = 110
wait(0.3)
ball.Catch.Disabled=false
wait(1)
script.Disabled=false
end
end

ball.Handle.Touched:connect(HitBall)

``````

https://gyazo.com/774b6691af25a69530c8d06176ec7879

this also looks a bit concerning but i dont know anything about scripting ^.

And what I did was make a lefty bat which plays lefty animations with a script like this:

Lefty Bat
``````
--This is where we will get the character, humanoid, etc. Referance all of it before we continue with the script.

local player = game.Players.LocalPlayer

local character = player.Character or player.CharacterAdded:Wait()

local humanoid = character:WaitForChild("Humanoid")

local InputService = game:GetService("UserInputService")

local InputType = Enum.UserInputType

--Create 2 new variables, 1 for the animation, 1 for the slash animation.

local animation = nil

local slashAnimation = nil

--Each time the tool is equipped we create a new animation and load it to the humanoid.

tool.Equipped:Connect(function()

animation = Instance.new("Animation")

animation.AnimationId = "rbxassetid://7210817517"

end)

--Destroy the animation and set slash to nil. We destroy the animation to remove it from the game's memory.

tool.Unequipped:Connect(function()

animation:Destroy()

slashAnimation = nil

end)

--Here we check if MB1 has been pressed and slash is not nil, that way we dont play an animation that doesnt exist.

local debounce = false

InputService.InputBegan:Connect(function(input, processed) --Processed basically means if the key is binded to a context action or if the player is typing

if input.UserInputType == InputType.MouseButton1 and slashAnimation and not processed then --And not processed means "If they aren't typing then..."

if debounce then return end --If the player is already swinging then dont proceed

debounce = true

slashAnimation:Play()

slashAnimation.Stopped:Wait() --Wait until the animation has finished

debounce = false

end

end)
``````

So I have two different tool sets, one lefty bat, one righty bat; one lefty ball and one lefty bat

1 Like

Hi! Developer for this baseball thing here.

If you were curious on the wackiness, it’s because the tools were originally made in 2014 and have gone through numerous changes made by me and a couple other people. The tools were originally made by @CollegiateJokes who has made some pretty popular sports games before, actually.

Thanks for the help, though. We appreciate it.