J'ai ce script en roblox lua pour envoyer des sorts mais j'ai un problème de précision si le joueur clique au sol à 100m de sa position par exemple le sort s'arrêteras sur le sol 50m avant quel est le moyen pour adapter la vitesse à laquelle le projectile descende de façon à attérir au sol à 100m

local function spellProjectile(player,spellId,mouseHit) 

	local startTime = os.clock() 
	local spellSettings = spellsModule.List[spellId]

	local character = player.Character 
	local humanoidRootPart = character.HumanoidRootPart

	if eventsCooldown:CheckRemote(player,tostring(spellSettings.Name)) == false then return end 

	local wandTool

	for i,v in pairs (player.Character:GetChildren()) do 
		if v:GetAttribute("Wand") then 
			wandTool = v
		end
	end

	local colorSequence = ColorSequence.new{
		ColorSequenceKeypoint.new(0, spellSettings.Color),
		ColorSequenceKeypoint.new(1, spellSettings.Color)
	}
	
	local mousePosition = Vector3.new(mouseHit.Position.X,mouseHit.Position.Y,mouseHit.Position.Z)
	
	wandTool.Handle.Cast:Play() 

	wandTool.Handle.Attachment.spellFire.Color = colorSequence
	wandTool.Handle.Attachment.Sparks.Color = colorSequence

	wandTool.Handle.Attachment.spellFire.Enabled = true
	wandTool.Handle.Attachment.Sparks.Enabled = true


	delay(.1,function()
		wandTool.Handle.Attachment.spellFire.Enabled = false
		wandTool.Handle.Attachment.Sparks.Enabled = false
	end)
	
	--shakeEvent:FireClient(player,)
	shakeEvent:FireClient(player,"Bump",0.1)

	--wandTool.Handle.Attachment.spellFire:Emit(800)

	local spellProjectile = game.ReplicatedStorage.ProjectileNew:Clone() --projectile:Clone()
	spellProjectile.Player.Value = player.Name
	spellProjectile.Parent = workspace.Projectiles
	spellProjectile.CFrame = CFrame.new(character.HumanoidRootPart.Position,mousePosition)
	spellProjectile.projectileLoop.Volume = 0.3
	spellProjectile.spellGlow.Range = 0 
	
	spellProjectile.Trail1.Color = colorSequence 
	spellProjectile.Trail2.Color = colorSequence 
	spellProjectile.Trail3.Color = colorSequence 
	spellProjectile.Main.Color = colorSequence 
	
	spellProjectile.Particles.Hit.Color = colorSequence 
	spellProjectile.Particles.Sparks.Color = colorSequence 
	spellProjectile.Particles.Spiral.Color = colorSequence 
	spellProjectile.Particles.Water.Color = colorSequence 
	spellProjectile.Particles.Wind.Color = colorSequence

	local bodyGyro = Instance.new("BodyGyro", player.Character.HumanoidRootPart)
	bodyGyro.Name = "FaceTargetBodyGyro"
	bodyGyro.MaxTorque = Vector3.new(10000, 10000, 10000)
	bodyGyro.P = 8000
	bodyGyro.D = 0

	local targetDirection = (mousePosition - humanoidRootPart.Position).unit
	local targetCFrame = CFrame.lookAt(humanoidRootPart.Position, humanoidRootPart.Position + targetDirection)
	bodyGyro.CFrame = targetCFrame

	game:GetService("Debris"):AddItem(bodyGyro,.45)

	spellProjectile.CFrame = CFrame.new(humanoidRootPart.Position,mousePosition)

	spellProjectile.spellGlow.Color = spellSettings.Color
	spellProjectile.IsActive.Value = true

	spellProjectile.SpellId.Value = spellId

	--localLightningEvent:FireAllClients(true,spellId,spellProjectile)

	--local direction = mouseHit.LookVector - spellProjectile.a1.Position
	--local cframe = CFrame.new(spellProjectile.a1.Position, spellProjectile.a1.Position + direction) * CFrame.new(0, 0, spellSettings.BoltProperties.LengthBetweenAttachment)

	--spellProjectile.a2.CFrame = cframe 

	local connection = {} 

	local ignoreList = {} 

	for i,v in pairs (player.Character:GetDescendants()) do 
		if v:GetAttribute("Wand") then
			for a,b in pairs (v:GetChildren())  do
				if b:IsA("Part") or b:IsA("MeshPart") then 
					table.insert(ignoreList,b)
				end
			end
		elseif v:IsA("Part") or v:IsA("MeshPart") or v:IsA("BasePart") then 
			table.insert(ignoreList,v)
		end
	end

	table.insert(ignoreList,spellProjectile)

	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = ignoreList

	local direct = (mousePosition - spellProjectile.Position).Unit


	task.spawn(function()
		while spellProjectile.IsActive.Value == true do 
			task.wait() 
			local part = squareRay(spellProjectile,raycastParams,2)

			if part then 
				if part.Name ~= "projectile" then 

					spellProjectile.IsActive.Value = false
					for i,v in pairs (connection) do v:Disconnect() end 
					tweenService:Create(spellProjectile.projectileLoop,tweenQuint,{Volume = 0}):Play()
					
					for i,v in pairs (spellProjectile:GetDescendants()) do 
						if v:IsA("ParticleEmitter") then v:Destroy() end 
					end

					if spellProjectile:FindFirstChild("spellGlow") then 
						spellProjectile.spellGlow:Destroy()
					end

					if part.Name == "Shield" and not spellSettings.Heal then
						if part.Parent.PrimaryPart.Transparency < 1 then 
							spellProjectile:Destroy()
							part.Parent.PrimaryPart.Attachment.Flare:Emit(3)
							part.Parent.PrimaryPart.Attachment.Sparkle:Emit(3)
							part.Parent.PrimaryPart.Attachment.Wave:Emit(3)

							part.Parent.PrimaryPart.counterSpell:Play()
							return
						end
					end

					spellProjectile.hitSound.SoundId = spellSettings.hitSound
					spellProjectile.hitSound:Play()
					
					local lightningExplo = game.ReplicatedStorage.Lightning:Clone() 
					lightningExplo.Parent = workspace 
					
					lightningExplo.Glow.Color = colorSequence 
					lightningExplo.Lightning.Color = colorSequence
					
					lightningExplo.Position = spellProjectile.Position 
					
					delay(.3,function()
						for i,v in pairs (lightningExplo:GetChildren()) do 
							if v:IsA("ParticleEmitter") then v.Enabled = false end 
						end
					end)
					
					
					delay(2,function()
						spellProjectile:Destroy()
						lightningExplo:Destroy()
					end)

					callBack(player,part,spellId,spellProjectile)

					return
				end
			end

			if os.clock() - startTime >= 3 then 
				for i,v in pairs (connection) do v:Disconnect() end 
				spellProjectile:Destroy()
				return
			end
		end
	end)

	connection[#connection+1] = runService.Heartbeat:Connect(function(dt)

		spellProjectile.CFrame = CFrame.new(spellProjectile.Position) + direct * dt * spellSettings.Speed

		--spellProjectile.CFrame = CFrame.new(spellProjectile.Position) + mouseHit.LookVector * dt * spellSettings.Speed

		for i,v in pairs (workspace.Projectiles:GetChildren()) do 
			if v ~= spellProjectile and v.Player.Value ~= player.Name then 
				if (v.Position - spellProjectile.Position).magnitude <= 5 then 
					if v.IsActive.Value ~= false and spellProjectile.IsActive.Value ~= false then 
						if (game.Players:FindFirstChild(v.Player.Value).Character.HumanoidRootPart.Position - player.Character.PrimaryPart.Position).magnitude <= 85 then
							spellProjectile.IsActive.Value = false
							v.IsActive.Value = false 

							for i,v in pairs (connection) do v:Disconnect() end 

							spellProjectile.spellGlow:Destroy()
							v.spellGlow:Destroy()

							tweenService:Create(spellProjectile.projectileLoop,tweenQuint,{Volume = 0}):Play()
							tweenService:Create(v.projectileLoop,tweenQuint,{Volume = 0}):Play()

							clash(v,spellProjectile)
							return
						end
					end
				end
			end
		end
	end)
end