Mobile support and projectiles (Yes, another one)

  1. What do you want to achieve?
    Finding a way to make a projectile traveling a distance when the player tap screen on mobile (or when touch enabled)

  2. What is the issue?
    On pc, we can use the mouse lookVector then multiply it by an arbitrary number when you can’t on touch enabled. My problem is, i can’t find the way to get the position of the destination when you tap on screen

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    i tried by myself for 3 days and also tried to check on google. If there is a post similare to mine, i didn’t find it.

So basically, how it work is:

  1. You press a GUI named “X”, It becomes selected
  2. You have to tap somewhere on screen to activate the power which should fire a heat ball.
UIS.TouchStarted:Connect(function(touch)
	print(touch)
	if not InUse1 and InUse2 then
		InUse1 = true
		atsuEvent:FireServer("MobileEgg", touch.Position)
		wait(1)
		InUse1 = false
		InUse2 = false
		btn.Selected = false
	end
end)

I would thank the one to find a solution to my small problem!

local paramsCast = RaycastParams.new()
paramsCast.FilterDescendantsInstances = {player.Character}
paramsCast.FilterType = Enum.RaycastFilterType.Blacklist

local posScreen = touch.Position
local camCurrent = workspace.CurrentCamera
local rayProjectile = camCurrent:ViewportPointToRay(posScreen.X,posScreen.Y,1)

local posHit
local resultCast = workspace:Raycast(rayProjectile.Origin,rayProjectile.Direction*1500)
if resultCast then
	-- if a part is found, take the hit position
	posHit = resultCast.Position
else
	-- if no part is found, take the max cast distance
	posHit = rayProjectile.Origin + rayProjectile.Direction*1500
end
2 Likes

You gave me a bigger answer than i was expecting, i will try it and tell you back

The first block just sets up the raycast parameters.

The second block finds the touch position on the screen and generates a ray that points from the camera using that info.

The final block gets the hit position that you can use to cast the projectile. In case a part is found, it will use that position. If not (pointing at sky or something really far), the projectile will be fired at an imaginary hit position.

i know what does these blocks but i have to modify it a bit. What i didn’t say is i am using a local script to with a remote event. Hold on, it will takes only a few minutes to adjust your code to my scripts!

i just have a small gravity problem with my projectile. Once i fixed it, i will be able to try your code. Hold on, it isn’t a big deal

alright so, i added the anti gravity thing to my projectile and adjusted your code to my scripts but the projectile is not moving. Did i do something wrong?

LOCAL

UIS.TouchStarted:Connect(function(touch)
	local rayProjectile = camera:ViewportPointToRay(touch.Position.X,touch.Position.Y,1)
	print(touch.Position)
	if not InUse1 and InUse2 then
		InUse1 = true
		atsuEvent:FireServer("MobileEgg", rayProjectile)
		wait(1)
		InUse1 = false
		InUse2 = false
		btn.Selected = false
	end
end)

SERVER

local bf = Instance.new("BodyForce", hotegg)
bf.Force = Vector3.new(0,workspace.Gravity,0) * hotegg:GetMass()
		
local paramsCast = RaycastParams.new()
paramsCast.FilterDescendantsInstances = {char}
paramsCast.FilterType = Enum.RaycastFilterType.Blacklist

local posHit
local resultCast = workspace:Raycast(Value2.Origin,Value2.Direction*1500)
if resultCast then
	-- if a part is found, take the hit position
	posHit = resultCast.Position
else
	-- if no part is found, take the max cast distance
	posHit = Value2.Origin + Value2.Direction*1500
end

All of my code has to be done on the client for optimal performance. Just send the posHit value to the server.

Your code doesn’t include anything that will actually move the projectile. The one I sent is a replacement of mouse.CFrame that gives you a position your projectile will be aiming at.

oh alright, i will do that (sorry, i am pretty new to raycasting)

So, it works almost perfectly but it doesnt go where i tap on screen, a bit above where i tap which is annoying.
https://gyazo.com/ed3ea79635a0dada8362683b2a242aa3

i changed the local as you said:

UIS.TouchStarted:Connect(function(touch)
    if not InUse1 and InUse2 then
        InUse1 = true
        local paramsCast = RaycastParams.new()
		paramsCast.FilterDescendantsInstances = {plr.Character}
		paramsCast.FilterType = Enum.RaycastFilterType.Blacklist

		local posScreen = touch.Position
		local camCurrent = workspace.CurrentCamera
		local rayProjectile = camCurrent:ViewportPointToRay(posScreen.X,posScreen.Y,1)

		local posHit
		local resultCast = workspace:Raycast(rayProjectile.Origin,rayProjectile.Direction*200)
		if resultCast then
			-- if a part is found, take the hit position
			posHit = resultCast.Position
			atsuEvent:FireServer("MobileEgg", posHit)
		else
			-- if no part is found, take the max cast distance
			posHit = rayProjectile.Origin + rayProjectile.Direction*200
			atsuEvent:FireServer("MobileEgg", posHit)
		end
		wait(1)
		InUse1 = false
		InUse2 = false
		btn.Selected = false
	end
end)

and used a Tween to try where it go:

local bf = Instance.new("BodyForce", hotegg)
bf.Force = Vector3.new(0,workspace.Gravity,0) * hotegg:GetMass()
local info2 = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
local prop2 = {Position = Value2}
local Tween2 = tween:Create(hotegg, info2, prop2)
Tween2:Play()

Any idea how to make the projectile reaching the destination more reliably?

Replace ViewportPointToRay with ScreenPointToRay.

1 Like

yay you found a solution for my problems, thanks to you!