How to position a Moving Part above the part it is touching?

Hello! I am currently making a slash attack, where the player will slash an axe, shooting out a slash projectile with rocks forming on the side of the slash. So far, the rocks that form will do a downcast, setting the material and color the the object it is touching. But a problem has occured: when the slash projectile clips into a part, the rocks also do aswell, having weird small rocks sticking out or not visible rocks at all.

The solution to this would be to position the slash projectile above whatever it is above / clipped through as the rocks get positioned based on the slash projectiles position, but I do not know a way to do that. My only idea is some sort of downcast, but I am not sure. Please help!

A video showing the issue: Watch Desktop 2024.07.09 - 07.06.04.01 | Streamable

1 Like

Hey! I’ve been working on this for a bit, and I thought I came across a solution:

NewSlash.Position += Vector3.new(0,rayslash.Position.Y - NewSlash.Position.Y,0)

NewSlash being the slash, and rayslash being a raycast.

Sadly, this doesn’t seem to work.
The raycast is created like:

local rayslash = workspace:Raycast(NewSlash.Position,NewSlash.CFrame.UpVector * -8,rayparamsslash)

Is it something wrong with how I create the raycast? The slash is moved via a BodyVelocity, so that could be it too. Please help!

How exactly are the rocks being placed? From what I’m seeing, there is only a single raycast for your rocks (since there is one material)?

The rocks are created like this;

local Rock1 = Instance.new("Part")
		Rock1.Size = Vector3.new(1,1,1)
		Rock1.Parent = workspace.Map.IgnoreParts
		Rock1.BrickColor = BrickColor.new("Dark grey")
		Rock1.Material = Enum.Material.Slate
		Rock1.Anchored = true
		Rock1.CanCollide = false
		Rock1.Position = NewSlash.Position + Vector3.new(-0.8,-2.9,-1)
		Rock1.Orientation = Vector3.new(0,0,0)
		TS:Create(Rock1,TI,{Size = Vector3.new(0,0,0)}):Play()
		Debris:AddItem(Rock1,6.5)
		local rayparams = RaycastParams.new()
		rayparams.FilterType = Enum.RaycastFilterType.Exclude
		rayparams.FilterDescendantsInstances = {Char,NewSlash,Rock1}

		local ray = workspace:Raycast(Rock1.Position,Rock1.CFrame.UpVector * -8,rayparams)

		if ray then
			Rock1.Material = ray.Instance.Material
			Rock1.Color = ray.Instance.Color
		end
		Rock1.Orientation = Vector3.new(math.random(0,180),math.random(0,180),math.random(0,180))

And when are they being created (under what context)?

Your slash is just one part that is being transformed, correct?

The rocks are created under a local script every heartbeat (by firing all clients), the slash is just one part that is being moved by a BodyVelocity, yes.

I’m a little bit confused to be honest, as the rock script that is supposed to be in a LocalScript means that you are passing Instances over remotes, which is bad practice.

Second, assuming you are running this every heartbeat and firing off to the client to run the calculations and visuals,

  1. Are your map’s parts’ CanQuery set to true? I see that the color of the rock is still the grass color regardless of the raycast. Print if it is really hitting anything.
    Your raycast will more than likely not hitting in this scenario because of the fact that you are already positioning your rock downwards and using that position as your origin point. Use the NewSlash as your origin point instead, with something like this:
workspace:Raycast(NewSlash.Position, Vector3.FromAxis(Enum.Axis.Y) * -8, rayparams)
  1. The ray will have a Position key you can use to position your rock. Otherwise if it detects no parts, stick to some arbitrary position (or don’t render at all).

Here is a video showing that grass isn’t the only thing rendering, it was just the way the raycast was set up, I will be trying your solution to this now.

Also, I would like to position the slash above the things such as the grass, road, etc as the rocks are positioned to match with the slash and it would save me a hassle positioning those as well.

Your solution for mismatched color seems to work! Only issue now is positioning the slash above objects it passes over so the slash and rocks don’t clip through them.

The ray result has a Position key if it detects an Instance. Use that to override the position of the rock.

Alright, how would I go about doing this? So far, the position is set up like this.

		Rock2.Position = NewSlash.Position + Vector3.new(0.4, -2.9, 1.1)

Would I set the Y axis to ray.Position.Y + the -2.9 to line it up with the Slash?

No, you simply do this if it detects a ray:

if ray then
    -- appearance stuff
    Rock1.Position = ray.Position
end

The Position returns the world point in which the ray detected the hit.

Seems to have worked, thank you so much!