Bullet spawn keep glitching

Why is my BulletPos part keep changing it position or rotation whenever I shoot and move my mouse?? How do I prevent that from happening??

image

Client Script:

local Players = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local UserInputService = game:GetService('UserInputService')
local TweenService = game:GetService('TweenService')

local ModulesFolder = ReplicatedStorage:WaitForChild('Modules')
local RemotesFolder = ReplicatedStorage:WaitForChild('Remotes')

local TowersManager = require(ModulesFolder:WaitForChild('TowersManager'))
local CameraShaker = require(ModulesFolder:WaitForChild('CameraShaker'))

local TowerBehaviour = RemotesFolder:WaitForChild('TowerBehaviour')
local TowerPositioner = RemotesFolder:WaitForChild('TowerPositioner')

local Player = Players.LocalPlayer

local PlayerCamera = workspace.CurrentCamera
local PlayerMouse = Player:GetMouse()
local PlayerGui = Player.PlayerGui or Player:WaitForChild('PlayerGui')

local Character = Player.Character or Player.CharacterAdded:Wait()
local Hum = Character:WaitForChild('Humanoid')

local TransitionUI = PlayerGui:WaitForChild('TransitionUI')
local TransitionFrame = TransitionUI:WaitForChild('TransitionFrame')

local TransitionInfo = TweenInfo.new(
	.5,
	Enum.EasingStyle.Quad,
	Enum.EasingDirection.Out,
	0,
	false,
	0
)

------------------------------------------------------------------------------------------------------------

--- // Reference Cannon // ---

local ReferenceCannons = workspace:WaitForChild('ReferenceCannons')
local _3Cannons = ReferenceCannons:WaitForChild('3Cannons')
local _3CannonsRoot = _3Cannons.PrimaryPart or _3Cannons:WaitForChild('cannons.013')
local _3CannonCam = _3Cannons:WaitForChild('CannonCamera')

------------------------------------------------------------------------------------------------------------

local OpenTransition = TweenService:Create(TransitionFrame, TransitionInfo, {BackgroundTransparency = 0})
local CloseTransition = TweenService:Create(TransitionFrame, TransitionInfo, {BackgroundTransparency = 1})

local ShootDebounce = false
local IsAiming = false
local CanAim = false

local function SetCameraType(CameraType: Enum.CameraType)
	assert(typeof(CameraType) == 'EnumItem', 'CameraType is not a valid EnumItem.')
	repeat task.wait()
		PlayerCamera.CameraType = CameraType
	until PlayerCamera.CameraType == CameraType
end

local function ToggleAim(Option: boolean)
	assert(typeof(Option) == 'boolean', 'Option is not a valid boolean.')
	if Option then
		OpenTransition:Play()
		OpenTransition.Completed:Wait()
		SetCameraType(Enum.CameraType.Scriptable)
		PlayerCamera.CFrame = _3CannonCam.CFrame
		CloseTransition:Play()
		CloseTransition.Completed:Wait()
	else
		OpenTransition:Play()
		OpenTransition.Completed:Wait()
		SetCameraType(Enum.CameraType.Custom)
		CloseTransition:Play()
		CloseTransition.Completed:Wait()
	end
	IsAiming = Option
end

UserInputService.InputBegan:Connect(function(Input: InputObject, GPE: boolean)
	if GPE then return end
	
	if Input.KeyCode == Enum.KeyCode.E then
		CanAim = not CanAim
		ToggleAim(CanAim)
	end
end)

PlayerMouse.Move:Connect(function()
	if ShootDebounce and not CanAim then return end
	TowerPositioner:FireServer(PlayerMouse.Hit.Position, IsAiming)
end)

PlayerMouse.Button1Down:Connect(function()
	if ShootDebounce or not CanAim then return end
	ShootDebounce = true
	TowerBehaviour:FireServer('Shoot', nil)
	ShootDebounce = false
end)

Hum.Died:Connect(function()
	if CanAim then
		CanAim = false
		ToggleAim(CanAim)
	end
end)

Server Script:


local Players = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')

local ModulesFolder = ReplicatedStorage:WaitForChild('Modules')
local RemotesFolder = ReplicatedStorage:WaitForChild('Remotes')

local TowersManager = require(ModulesFolder:WaitForChild('TowersManager'))

local TowerBehaviour = RemotesFolder:WaitForChild('TowerBehaviour')
local TowerPositioner = RemotesFolder:WaitForChild('TowerPositioner')

------------------------------------------------------------------------------------------------------------

--- // Reference Cannon // ---

local ReferenceCannons = workspace:WaitForChild('ReferenceCannons')
local _3Cannons = ReferenceCannons:WaitForChild('3Cannons')
local _3CannonsRoot = _3Cannons.PrimaryPart or _3Cannons:WaitForChild('cannons.013')
local _3CannonCam = _3Cannons:WaitForChild('CannonCamera')

------------------------------------------------------------------------------------------------------------

TowerBehaviour.OnServerEvent:Connect(function(Plr: Player, BehaviorType: string, ClientData: {[string]: any})
	if BehaviorType == 'Shoot' then
		TowersManager.Shoot(_3Cannons, _3CannonsRoot)
	end
end)

TowerPositioner.OnServerEvent:Connect(function(Plr: Player, MousePosition: Vector3, CanAim: boolean)
	TowersManager.Aim(_3CannonsRoot, MousePosition, CanAim)
end)

Module Script:

local TowersHandler = {}

type TowerType = Model? | Folder?

local Players = game:GetService('Players')
local RunService = game:GetService('RunService')
local Debris = game:GetService('Debris')
local UserInputService = game:GetService('UserInputService')
local TweenService = game:GetService('TweenService')

local Spring = require(script.Parent:WaitForChild('Spring'))

local CannonBulletsFolder = workspace:WaitForChild('CannonBullets')

local TransitionInfo = TweenInfo.new(
	.5,
	Enum.EasingStyle.Quad,
	Enum.EasingDirection.InOut,
	0,
	false,
	0
)

local OldCannonPosList = {}
local HitboxDebouncesList = {}
local BulletDurationsList = {}

local ShootDebounce = false
local HitboxThread = nil

function TowersHandler.Shoot(Tower: TowerType, Cannon: BasePart?)
	if not Tower:GetAttribute('Team') then
		warn('Cannot shoot cannon from tower due to unidentify tower team')
		return
	end
	
	Spring.target(Cannon, .5, 5, {
		Position = Cannon.Position + Cannon.CFrame.LookVector * 3
	})
	
	local Blacklist = {Tower}
	
	local BulletBoundsParams = OverlapParams.new()
	BulletBoundsParams.FilterType = Enum.RaycastFilterType.Exclude
	BulletBoundsParams.FilterDescendantsInstances = Blacklist
	
	for _, Teammate in Players:GetPlayers() do
		if Teammate.Team.Name == Tower:GetAttribute('Team') then
			local TeammateChar = Teammate.Character or Teammate.CharacterAdded:Wait()
			if TeammateChar then
				table.insert(Blacklist, TeammateChar)
			end
		end
	end
	
	if not OldCannonPosList[Cannon] then
		OldCannonPosList[Cannon] = Cannon.Position
	end
	
	for _, BulletPos in Tower:GetChildren() do
		if BulletPos:IsA('Part') and BulletPos.Name == 'BulletPos' then
			local NewBullet = BulletPos:Clone()
			NewBullet.Shape = Enum.PartType.Ball
			NewBullet.Transparency = 0
			NewBullet.Color = Color3.fromRGB(0, 0, 0)
			NewBullet.Anchored = false
			NewBullet.CanCollide = false
			NewBullet.Name = 'CannonBullet'
			NewBullet.Parent = CannonBulletsFolder
			NewBullet.CanQuery = false
			
			local PosAttachment = BulletPos:FindFirstChild('BulletPosition')
			
			if PosAttachment and PosAttachment:IsA('Attachment') then
				NewBullet.CFrame = PosAttachment.WorldCFrame
			end
			
			if not BulletDurationsList[NewBullet] then
				BulletDurationsList[NewBullet] = true
			end
			
			local BulletWeld = NewBullet:FindFirstChildWhichIsA('WeldConstraint')
			local BulletTrail = NewBullet:FindFirstChildWhichIsA('Trail')
			local BulletAttachment = NewBullet:FindFirstChild('BulletPosition')
			
			if BulletWeld then
				BulletWeld:Destroy()
			end
			
			if BulletAttachment and BulletAttachment:IsA('Attachment') then
				BulletAttachment:Destroy()
			end
			
			if BulletTrail then
				BulletTrail.Enabled = true
			end

			local BulletMover = Instance.new('BodyVelocity')
			BulletMover.Parent = NewBullet
			BulletMover.MaxForce = Vector3.one * math.huge
			BulletMover.Velocity = BulletPos.CFrame.LookVector * -150

			task.delay(5, function()
				if not BulletDurationsList[NewBullet] then
					print(`Cancelled removing schedule for {NewBullet.Name}!!`)
					return
				end
				local NewExplosion = Instance.new('Explosion')
				NewExplosion.Parent = workspace
				NewExplosion.Position = NewBullet.Position
				NewExplosion.DestroyJointRadiusPercent = 0
				NewExplosion.BlastPressure = 100000 * 5
				NewExplosion.BlastRadius = 20
				NewBullet:Destroy()
				BulletDurationsList[NewBullet] = nil
			end)
		end
	end
	
	HitboxThread = task.spawn(function()
		while task.wait() do
			for _, Bullet in CannonBulletsFolder:GetChildren() do
				if Bullet:IsA('BasePart') and Bullet.Name == 'CannonBullet' then
					
					local BulletBoundsResult = workspace:GetPartBoundsInBox(Bullet.CFrame, Bullet.Size, BulletBoundsParams)
					
					if #BulletBoundsResult ~= 0 then
						for _, HitPart in BulletBoundsResult do
							if HitPart then
								local TargetHum = HitPart.Parent:FindFirstChildWhichIsA('Humanoid')
								
								if TargetHum and not HitboxDebouncesList[TargetHum] then
									HitboxDebouncesList[TargetHum] = true
									TargetHum:TakeDamage(20)
									task.delay(.5, function()
										HitboxDebouncesList[TargetHum] = nil
									end)
								end
							end
						end
						local NewExplosion = Instance.new('Explosion')
						NewExplosion.Parent = workspace
						NewExplosion.Position = Bullet.Position
						NewExplosion.DestroyJointRadiusPercent = 0
						NewExplosion.BlastPressure = 100000 * 5
						NewExplosion.BlastRadius = 20
						Bullet:Destroy()
						if BulletDurationsList[Bullet] then
							BulletDurationsList[Bullet] = nil
						end
					end
				end
			end
		end
	end)
	
	task.delay(.15, function()
		Spring.target(Cannon, .35, 3, {
			Position = OldCannonPosList[Cannon]
		})
	end)
end

function TowersHandler.Aim(Cannon: BasePart?, MousePos: Vector3, Option: boolean)
	assert(typeof(Option) == 'boolean', 'Option is not a valid boolean!!')
	
	if Option then
		Cannon.CFrame = CFrame.lookAt(Cannon.Position, MousePos) * CFrame.Angles(0, math.rad(-180), 0)
	else
		if HitboxThread then
			task.cancel(HitboxThread)
		end
		OldCannonPosList[Cannon] = nil
	end
end

return TowersHandler