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:
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!
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.
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:
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.
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!
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)
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)
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?
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
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.