Trying to make a realistic bullet using TweenService

What I want to achieve:
I want to make a bullet move smoothly using tweens. I am currently using .Velocity, it works fine but the bullet just drops too fast and Its a bit glitchy. With the tweening I want to make the bullet do the same as it does now, but not drop so fast and add something that when the bullet travelled like 4000 studs it deletes the bullet. And of course not have it really glitchy.

What the issue is:
I dont really know how to make the bullet do that.

What solutions I tried so far:
Searching on the developer forum and internet.

The current code I have using .Velocity (Server Script Inside ServerScriptService):

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("gun_shotEvent")

remoteEvent.OnServerEvent:Connect(function(player, gunPos, mousePos, ShotSound)
	
local Color3 = setmetatable({
	fromInt = function(i)
		return Color3.fromRGB(math.floor(i / 65536) % 256, math.floor(i / 256) % 256, i % 256)
	end
}, {__index = Color3})


local bulletcolor = Color3.fromInt(0xff6a00)
	
	local bullet = Instance.new("Part")
	bullet.Name = "Bullet"
	bullet.Parent = game.Workspace
	bullet.Size = Vector3.new(0.2, 0.2, 0.2)
	bullet.Material = Enum.Material.SmoothPlastic
	bullet.Reflectance = 0.3
	bullet.Transparency = 0
	bullet.Color = bulletcolor
	bullet.Shape = "Ball"
	bullet.CanCollide = false
	
	local attach1 = Instance.new("Attachment", bullet)
	local attach2 = Instance.new("Attachment", ShotSound.Parent)
	local trail = Instance.new("Trail", bullet)
	trail.Name = "bulletTrail"
	trail.Attachment0 = attach1
	trail.Attachment1 = attach2
	
	local damageScript = ServerStorage:FindFirstChild("gun_BulletDamage"):Clone()
	damageScript.Parent = bullet
	
	local attacker = Instance.new("StringValue")
	attacker.Name = "Attacker"
	attacker.Parent = bullet
	attacker.Value = player.Name
	
-- .Velocity
	local distance = (mousePos - gunPos).magnitude
	local bulletspeed = 1000
	bullet.CFrame = CFrame.new(gunPos, mousePos)
	bullet.Velocity = bullet.CFrame.lookVector * bulletspeed
-- .Velocity

	ShotSound:Play()
	
	game:GetService("Debris"):AddItem(bullet, 40)
	
end)

The result of all this : https://gyazo.com/46900516b3dfcb706e232d14dfa1b727
The bullet is falling too much fast .-.

Some of the script is from a tutorial, I made my first gun with the tutorial.
But it uses .Velocity but I want to use TweenService, now any other way that does the same fits in my will too.

Thanks for reading this topic !

2 Likes

Okay, what you need I think is to make a ray.

  1. With that Ray you find where it is hit
  2. You take the Ray’s Hit position, subtract it by the gun’s position to find the distance
  3. make some formula to calculate how much bullet drop you want

here is something I quickly wrote up, so it might have errors. But hopefully you get the idea:

local MaxBulletDistance = 2000 -- set it to anything you want, basically max distance for the bullet

local GunRay = Ray.new(Gun.Position, Gun.CFrame.LookVector * MaxBulletDistance)

local ignorelist = {} -- put the parts that you want the ray to ignore

local hit, position = workspace:FindPartOnRayWithIgnoreList(GunRay, ignorelist)

if hit then
	local bulletDrop = (position - Gun.Position).magnitude/1000 -- divide by anyting. 1000 seems resonable to me
	local NewPosition = Vector3.new(position.X, position.Y - bulletDrop, position.Z)
	local bulletTime = bulletDrop
	
	local BulletInfo = TweenInfo.new(
		bulletTime, -- having bullet drop and time be the same, but you could do something else
		Enum.EasingStyle.Linear,
		Enum.EasingDirection.InOut,
		false,
		0
	)
	
	local BulletTweenProperties = {
		Position = NewPosition -- sets the position of the bullet to the position we wanted
	}
	local BulletTween = game:GetService("TweenService"):Create(Bullet, BulletInfo, BulletTweenProperties)
	BulletTween:Play()
end

I hope this makes sense, if you need help on Rays I can provide you with some good sources

2 Likes

How I made mine was by getting the position of the end ray and getting the inverse CFrame of it. Kinda looks like this laser.CFrame = CFrame.fromMatrix(char.PrimaryPart.Position, rightVector, upVector2) * CFrame.new(0,0, -forwardVector/2) those variables use the Cross algorithm derived from the method :Cross(). So I set the part’s rotation to that matrix then after I just tween the two positions as if they were rays.

I tried your technic (and fixed some forgotten stuff such as the TweenInfo as you forgotten to put 0 before false

But, the bullet is falling on the ground when launched .-.
https://gyazo.com/0a51a1971a2f3e09bee535473a7a2473

I tried to modify some stuff but I did not find the solution for this

1 Like

for the first part,
local GunRay = Ray.new(Gun.Position, Gun.CFrame.LookVector * MaxBulletDistance)
it has the ray point at a front face of any part you chose. Make sure that part‘s front face is facing forwards

the issue from what I see is the part you assigned the ray to was facing down.
also, if you can send the updated script

Edit: You can have the LookVector be Mouse.Hit.LookVector it would be fine. anyways, now that I think of it the issue may be where you incorporated the ray, or something like that

Yea I thought about that too, I will use a script to see which face is the front one

you dont need to. Under properties for the part you assigned it to, click “front” and it should highlight the front face

Actually, you should use Mouse.Hit.LookVector since players can aim with their mouse (all guns that I can think of do this) Having the Part.CFrame.LookVector would make it so the bullet would come out with no player control over where to aim, unless if the gun rotates with the camera/player aim