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
        local human=person.Parent:findFirstChild("Head")
        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

https://gyazo.com/0f836056c9300a5c26043e5dc47e79df

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
		local human=person.Parent:findFirstChild("Head")
		human=person.Parent:findFirstChild("Head")
		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"

slashAnimation = humanoid:LoadAnimation(animation)

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

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.