I want to make a multiplayer bow shooter game from a roblox first person perspective

I want to make a multiplayer bow shooter game from a roblox first person perspective.

I tried with a video of the lecture that I learned with the help of others, but…
It failed for an unknown reason.

I made a mixture of the YouTube tutorials below, but the animation is weird, and the bow doesn’t go up in first person.

bowShotLine: Roblox how to make smooth projectiles - YouTube
bowShotAni: Roblox Studio Bow & Arrow Tutorial - YouTube

Is there a way to add animation naturally and make the bow move up and down to match the camera point of view (center)?

※ There is a delay of 1 second when firing the bow
※ It was written using Google Translator.

[ server ]

local fastcast = require(game.ServerStorage.FastCastRedux)
local rayhitbox = require(game.ServerStorage.RaycastHitboxV4)

local tool = script.Parent.Parent
local remote = tool:WaitForChild("RemoteEvent")

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist

tool.Equipped:Connect(function()
	params.FilterDescendantsInstances = { tool.Parent }
end)

local Damage = 30

local ArrowVelocity = 150

local HoldingAnimationId = "http://www.roblox.com/asset/?id=10367874810" -- you'll have to change these animation ids

local ChargingAnimationId = "http://www.roblox.com/asset/?id=10367747357"

local ChargedAnimationId = "http://www.roblox.com/asset/?id=10367751968"

local FireAnimationId = "http://www.roblox.com/asset/?id=10367864166"

local ArrowLifeTime = 30

local Anim1 = Instance.new("Animation")

Anim1.AnimationId = HoldingAnimationId

local Anim2 = Instance.new("Animation")

Anim2.AnimationId = ChargingAnimationId

local Anim3 = Instance.new("Animation")

Anim3.AnimationId = ChargedAnimationId

local Anim4 = Instance.new("Animation")

Anim4.AnimationId = FireAnimationId

local Cooldown = 0.5

local ChargeTime = 1

local MinChargeTime = 0.25

local LastFire = tick()

local ChargeStart = tick()
remote.OnServerEvent:Connect(function( player, Type , mousepos , LookVector, RightVector )
	local Player = player -- Tool.Parent.Parent
	local Character = workspace:WaitForChild(Player.Name)
	local Humanoid = Character:FindFirstChildOfClass("Humanoid")
	local IsCharging = false
	local HoldingAnimation = Humanoid:LoadAnimation(Anim1)
	local ChargingAnimation = Humanoid:LoadAnimation(Anim2)
	local ChargedAnimation = Humanoid:LoadAnimation(Anim3)
	local FireAnimation = Humanoid:LoadAnimation(Anim4)
	
if Type == "Activated" then -- 활성화됨 ( 대기 )
		if tick()-LastFire > Cooldown then
			ChargeStart = tick()
			IsCharging = true
			Character.Bow.Arrow.Transparency = 1 
			ChargingAnimation:Play()
			wait(ChargingAnimation.Length)
			ChargedAnimation:Play()
		end
	elseif Type == "Deactivated" then 
		ChargedAnimation:Stop()
		Character.Bow.Arrow.Transparency = 1
		if tick()-ChargeStart > MinChargeTime then
			FireAnimation:Play() 
			LastFire = tick()
			-- Fire an Arrow
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

			local bullet = game.ServerStorage.Arrow:Clone()
			bullet.Parent = Character.Bow --workspace
			local origin = tool.Bow.Attachment.WorldPosition
			local direction = ( mousepos - origin ).Unit
			bullet.CFrame = Character.Bow.Arrow.CFrame
			bullet.Sender.Value = Character.Bow.Blot
			bullet.Transparency = 0
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

			local caster = fastcast.new()
			local behaviour = caster.newBehavior()
			behaviour.RaycastParams = params
			caster.LengthChanged:Connect(function(cast, lastpoint, dir, length ) --, velocity , bullet )
				local blength = bullet.Size.Z / 2
				local offset = CFrame.new( 0, 0, -(length-blength))
				bullet.CFrame = CFrame.lookAt( lastpoint , lastpoint+dir ):ToWorldSpace( offset )
			end)
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
			--:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
			
			local hitbox = rayhitbox.new(bullet)
			hitbox.DetectionMode = 2
			hitbox.Visualizer = false
			hitbox.RaycastParams = params
			hitbox:LinkAttachments( bullet.DmgPoint , bullet.DmgPoint )

			hitbox.OnHit:Connect(function( hit, humanoid , result )
				print("asdasdasd")
				if humanoid then
					humanoid:TakeDamage(20)
				end
				wait( 0.5 )
				bullet:Destroy()

				--local explosion = Instance.new("Explosion")
				--explosion.Position = result.Position
				--explosion.Parent = workspace
			end)
			hitbox:HitStart()
			caster:Fire( origin , direction , 150 , behaviour )
			game.Debris:AddItem(bullet, ArrowLifeTime)
		end
		IsCharging = false
	elseif Type == "Equipped" then 
		HoldingAnimation:Play()
	elseif Type == "Unequipped" then 
		IsCharging = false
		Character.Bow.Arrow.Transparency = 1
		ChargingAnimation:Stop()
		ChargedAnimation:Stop()
		HoldingAnimation:Stop()
	end
end)


[ Clinet ]

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local Camera = workspace.CurrentCamera

local tool = script.Parent.Parent
local remote = tool:WaitForChild("RemoteEvent")

local buttonDown = false
mouse.Button1Down:Connect(function()
	buttonDown = true
end)

mouse.Button1Up:Connect(function()
	buttonDown = false
end)

tool.Activated:Connect(function()
	remote:FireServer("Activated" , mouse.hit.p , Camera.CFrame.LookVector, Camera.CFrame.RightVector)
end)

tool.Deactivated:Connect(function()
	remote:FireServer("Deactivated", mouse.hit.p , Camera.CFrame.LookVector, Camera.CFrame.RightVector)
end)

tool.Equipped:Connect(function()
	remote:FireServer("Equipped", mouse.hit.p , Camera.CFrame.LookVector, Camera.CFrame.RightVector)
end)

tool.Unequipped:Connect(function()
	remote:FireServer("Unequipped", mouse.hit.p , Camera.CFrame.LookVector, Camera.CFrame.RightVector)
end)

local Defult_Bow = script.Parent.Parent.Bow
local Defult_Arrow = script.Parent.Parent.Arrow
local Defult_Middle = 0.637 --( Defult_Arrow.Size.Z * 0.5  ) 
local Change_Middle =  ( Defult_Arrow.Size.Z * 0.5 )
local Cooldown = 1
local ChargeTime = 1
local MinChargeTime = 0.25
local LastFire = tick()
local ChargeStart = tick()
game:GetService("RunService").RenderStepped:Connect(function()
	local Bow = script.Parent.Parent.Bow
	local Middle = Bow.Middle
	if buttonDown then
		if tick()-LastFire > Cooldown then
		--script.Parent.Bow.Middle.Position = script.Parent.Bow.Middle.Position:Lerp(Vector3.new(0, 0, 1.998), 0.1)
			Middle.Position = Middle.Position:Lerp(Vector3.new(0, 0, Change_Middle ), 0.1)
			ChargeStart = tick()
		end
	else
		if tick()-ChargeStart > MinChargeTime then
		--script.Parent.Bow.Middle.Position = script.Parent.Bow.Middle.Position:Lerp(Vector3.new(0, 0, 0.637), 0.7)	
			Middle.Position = Middle.Position:Lerp(Vector3.new(0, 0, Defult_Middle ), 0.7)
			LastFire = tick()
		end
	end
	Bow.Weld.C1 = CFrame.new( -Vector3.new(0, 0, Middle.Position.Z*0.5 ) ) 
end)

The “i” is missing from “if”. I believe it should work after this is fixed.

1 Like

When copying the script, the “i” is missing. The anomaly is the same.

Then I believe this is your problem. The hit in Mouse.Hit should be capitalized.

1 Like

No change.
The mouse is the center of the camera. The bow is only looking down.


Ah, alright. Is there any error or warning in the output?

1 Like

There are no warnings or messages. It works normally.

Did you look into the parameters to pass to AnimationTrack:Play? This might be able to smooth out the animation.

1 Like

There is a problem with my Google Translate translation.
I don’t understand what you’re trying to say… (Sad)

I said to look at the documentation mentioned in the link I sent.

The animation track can play animations, so you can change the Weight and fadeTime values lower or higher to get a desired result.

If you’re not using animations, I don’t believe I can help too much here.

1 Like

It seems to be an animation problem.
Thank you for answer!
We recognized that it was a problem with the model animation in the tutorial video.

It’s a problem I can’t solve, so I gave up.

Thank you for thinking, answering and helping.

1 Like