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??
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