How to attach point on the side of the building depending on the character position?

Hey everyone!

I’m currently developing web swinging for a Spiderman game, and it’s going great until my team and I have made a map.

The issue is that the webbing would attach at the very top center of the building like this:

And here’s what I want to achieve:

Any response would help a ton😃

2 Likes

Bump as I really need help :slightly_frowning_face:
‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎

Couldn’t you just cast a ray towards the building and place the attachment where the raycast intersects with the building?

1 Like

I’ve already tried that, but the problem is that the ray would shoot at an angle as seen:

1 Like

And this is what I want:


(Hopefully you get the idea)

1 Like

So you want to cast a ray directly to the left/right of the character?

In that case,
1- Cast a ray from the left (using the root or torso’s -RightVector * a distance)
2- Cast a ray from the right (using the root or torso’s RIghtVector * a distance)
3- If left ray hits, save the distance
4- If right ray hits, save the distance
5- If left and right ray were ok, find the smallest distance between the two, and use that attachment point. Elseif only left or right hits, use the one that hit.

1 Like

You could do multiple raycasts from the player across an angle range of say 120 degrees, 60 degrees either side, and use the one with the smallest angle but greatest range (assuming you set the maximum range of the raycast to the range of your web). This should have the webs always appear slightly in front of you and to the side instead of directly sideways.

2 Likes

But what if the part is directly on top of the player?

1 Like

It’d be tough to find a part like that with raycasts while still being efficient. There are mathematical equations for getting the shortest point between an arbitrary point (the player) and a cube, which you can find with some googling.

You could also bite the bullet and manually mark attachment spots for webs at regular intervals on your buildings, and then just have the player attach to the closest one that is in the direction of movement.

2 Likes

In that case, are you already doing some sort of searching for valid parts they can attach to? If so, could you give us some insight on what you are doing?

If not, I have two ideas. Iterate through each part, find the closest point on the point to the player. If the closest point is within a suitable range, somehow classify that part as ok as well as store the closest point.

Another option could be to just use a spatial query (ie GetPartBoundsInRadius) for the maximum radius for which a player can shoot a web, but since that scales up with the number of valid parts, it may not be feasible. You could optimize the spatial queries by whitelisting the buildings and using bounding boxes of the buildings instead of many parts (assuming your buildings are made of parts).

Then for placing the attachment, if you used the first option, (closest point) you can use that closest point for your attachment point.

If you don’t like the closest point on cube option option, another option could be to cast a ray from the player to the origin of each possible part, find out which points of intersection they are moving towards, and then for these valid points do a magnitude check to find which valid point is the closest or most suitable, and use that for your attachment point.

1 Like

This is what I’m already doing, tho I might go with option 2

I’ll try this too, thanks for your response :smiley:

2 Likes

Also, an idea I had was to find the angle between the building and the player, and then shoot the ray opposite from that angle (Don’t know if this will work tho)

2 Likes

Your looking to make something like this?

1 Like

YES, I’m exactly looking for something like that

Well here you go, saw your post and made it quickly

local player = game.Players.LocalPlayer
local character = player.Character

local A = workspace.A

local humrp = character:WaitForChild("HumanoidRootPart")

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {character}

while true do 
	local raycast = workspace:Raycast(humrp.Position, (A.Position - humrp.Position).Unit * 100, params)

	if raycast then
		if raycast.Instance.Name == "A" then
			local pos = raycast.Position
			local part = Instance.new("Part")
			part.Anchored = true
			part.Size = Vector3.new(.5,.5,.5)
			part.Color = Color3.fromRGB(0,255,0)
			part.Parent = workspace
			local clampedY = math.clamp(pos.Y, A.Position.Y + A.Size.Y/2, A.Position.Y + A.Size.Y/2)
			part.CFrame = CFrame.new(A.Position) * A.CFrame:ToObjectSpace(CFrame.new(Vector3.new(pos.X, clampedY, pos.Z)))
			
		end
	end
	task.wait(.5)
end

Basically I raycast using the direction of my character with the building and then, I transform the raycast position into the buildings object space and then I clamp its Y so its always at the top of the part

3 Likes

Thank you so much dude, works like a charm! :+1::+1:

1 Like

I’ve run into another problem:

https://gyazo.com/d7602611eab46bc4cfbadb60c851d64c

The problem is that the point would either be in front or back of the player as seen above, and I want the point to be something like this (Without having to use RightVector):

image

image

Oh so you want it to calculate that point without having to raycast? Because they way I’m getting that point is by raycasting and using that hit position, also the point wouldn’t always be exactly aligned because since were using the direction between the player and the building it’ll be a bit undercompensated

I just want to find the correct position if it involves raycasting or not

I get what you mean but you notice how its completely aligned here?

image

And as you start moving it, it’s getting like well looking like its being offseted but in reality its just taking into account the direction between the yellow cube and the building; I mean theres not much more you can do with my solution

But maybe if you individually detected each side of the building and then compared the different X and Z and youd have to basically do a bunch of math

1 Like