Projectile punching attack in a boss fight isn't correctly working due to a Raycast error

The issue has changed since the initial post, see the bottom of the list of replies for the new issue.

It’s me once again with yet another probably arbitrary question on how CFrame works because this stuff is very confusing.

Straight to the point yet again:
I’m making a punching attack for the aforementioned boss fight. It’s supposed to fire it’s fists towards the nearest player based on the boss’s HumanoidRootPart Rotation, Raycasting from the top of the fists and Tweens.

As you can tell, it doesn’t work quite right otherwise I wouldn’t be making this post.

When I print the values for the Raycasts along with a few other bits of the code ( which of course will be below ), I get some very odd positional values which are nowhere close to where the boss actually is.

The code:

local LeftArmClone = game.ServerStorage.LeftArmPunchingClone:Clone()
			local RightArmClone = game.ServerStorage.RightArmPunchingClone:Clone()

			LeftArmClone.Parent = workspace
			RightArmClone.Parent = workspace

			LeftArmClone.CFrame = ActualLeftArm.CFrame * CFrame.Angles(math.rad(180),0,0)
			RightArmClone.CFrame = ActualRightArm.CFrame * CFrame.Angles(math.rad(180),0,0)

			local RayCastParamsVariable = RaycastParams.new()
			RayCastParamsVariable.FilterType = Enum.RaycastFilterType.Blacklist
			local ParentDecendants = Boss:GetDescendants()
			local LeftArmDescendants = LeftArmClone:GetDescendants()
			local RightArmDescendants = RightArmClone:GetDescendants()
			RayCastParamsVariable.FilterDescendantsInstances = {ParentDecendants, LeftArmDescendants, RightArmDescendants}

			local RayCast1 = Ray.new(LeftArmClone.Position, LeftArmClone.CFrame.UpVector * 300)
			local RayCast2 = Ray.new(RightArmClone.Position, RightArmClone.CFrame.UpVector * 300)

			local RayCastResult1 = workspace:Raycast(RayCast1.Origin, RayCast1.Direction, RayCastParamsVariable)
			local RayCastResult2 = workspace:Raycast(RayCast2.Origin, RayCast2.Direction, RayCastParamsVariable)

			local Distance1 = (LeftArmClone.Position - RayCastResult1.Position).Magnitude
			local Distance2 = (RightArmClone.Position - RayCastResult2.Position).Magnitude

			local Timer1 = (Distance1 / 0.5) / 100
			local Timer2 = (Distance2 / 0.5) / 100

			local TweenInf1 = TweenInfo.new(Timer1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)

			local Finish1 = {CFrame = CFrame.new(LeftArmClone.CFrame.UpVector * Distance1)}

			local Tween1 = TweenS:Create(LeftArmClone, TweenInf1, Finish1)
			
			local TweenInf2 = TweenInfo.new(Timer2, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)

			local Finish2 = {CFrame = CFrame.new(RightArmClone.CFrame.UpVector * Distance2)}

			local Tween2 = TweenS:Create(RightArmClone, TweenInf2, Finish2)
			Tween1:Play()
			Tween2:Play()

Now here’s an explanation of the weird bits incase it helps anyone along with extra info.

The Raycast Params ( should ) take the boss’s model as well as both of the punching arms, get their descendants, then blacklist them so they cannot be hit with a potential Raycast from the arms and possibly mess it up.

The Tweens that actually move it times the UpVector by a distance amount as the UpVector * [positive number] = movement in the direction of the top of the fists, or in other words, forward in a downwards direction due to how they are initially rotated. ( at least that is the intention )

Extra bits of info:
the boss arena is a large cylinder with a hole punched right through it, it uses the CollisionFidelity setting PreciseConvexDecomposition for reference.

the arms must be moved and rotated with CFrame as there are Welded parts on the model and using Orientation / Position would mess it up.

TLDR: a very large mess of Raycasting and CFrame tweens needs resolving

Are you sure that CFrame | Roblox Creator Documentation UpVector is the direction you need the RayCasts to point?

local RayCast1 = Ray.new(LeftArmClone.Position, LeftArmClone.CFrame.UpVector * 300)
local RayCast2 = Ray.new(RightArmClone.Position, RightArmClone.CFrame.UpVector * 300)

Could you place Parts that have specific names above, in front of, behind etc. around a test area and get a printout of the Part that the RayCast hits?

Are you sure that CFrame UpVector is the direction you need the RayCasts to point?

honestly not really. you see the fists themselves are unions with a bunch of smaller parts inside of them, and due to roblox making surfaces so much harder to view on instances now, I can’t really figure out the sides of it.

incase if you are wondering the whole reason I thought it was UpVector to begin with was because I put a large part of it and gave it all of the positional etc. values and found that the part I needed to move was the Top surface, however that was on a single part and not a union instance

Could you place Parts that have specific names above, in front of, behind etc. around a test area and get a printout of the Part that the RayCast hits?

I’ll try this. I’ll probably reply again after I’ve identified any kind of issue with the raycasts.

Well for one thing I’ve identified that UpVector is the wrong vector I need to be using. From what I’ve gathered it’s LookVector I need.

As for checking for the raycast hitting anything. Nil. It doesn’t appear to be a case of the raycasts ignoring certain parts or anything, they just don’t even touch anything to BEGIN with and I guess that results in it defaulting to 0, 0, 0 as a backup or something??

Whatever the case, something’ll need to be done about the raycasts hitting absolutely nothing. Unfortunately I’m not entirely sure how I might accomplish doing that as I’m not that experienced in raycasting yet.

I managed to find somewhat of a resolution to this problem, the fists no longer go flying near 0, 0, 0. Turns out the reason this happened was because the fists used code which subtracted one position from another leading to a value near 0, 0, 0 exactly.

That being said however the issue is not resolved yet. I’ve since encountered a completely different issue which would merit a change to the title of this post.

Examine this code:

LeftArmClone.CFrame = LeftArm.CFrame
			RightArmClone.CFrame = RightArm.CFrame	
			local RayCastParamsVariable = RaycastParams.new()
			RayCastParamsVariable.FilterType = Enum.RaycastFilterType.Blacklist
			local ParentDecendants = lolmaster146:GetDescendants()
			local LeftArmDescendants = LeftArmClone:GetDescendants()
			local RightArmDescendants = RightArmClone:GetDescendants()
			RayCastParamsVariable.FilterDescendantsInstances = {ParentDecendants, LeftArmClone, RightArmClone, LeftArmDescendants, RightArmDescendants, game.Workspace.TestCastleBossArena.Target}
			local RayCastResult1 = workspace:Raycast(LeftArmClone.Position, (LeftArmClone.CFrame.LookVector * 25), RayCastParamsVariable)
			local RayCastResult2 = workspace:Raycast(RightArmClone.Position, (RightArmClone.CFrame.LookVector * 25), RayCastParamsVariable)
			print(RayCastResult1.Position)
			print(RayCastResult2.Position)

This errors, claiming that the RayCastResult1.Position value is nil.
( meaning RayCastResult2.Position would also be nil )

Obviously this won’t do since without the Raycast actually returning a not nil value, the code just won’t run properly.

Some things to note include:
Left/RightArmClone.CFrame is not nil
Left/RightArm is not nil
Left/RightArmClone.CFrame.LookVector is not nil and also travels in the correct direction.

For slight clarification, by 0, 0, 0 I am referring to a Position value in the Game

oh and chances are this is probably a really easy fix and I apologise in advance for a high likelihood of stupidity

A small TLDR:

Raycast position is returning a nil value and I need it to not do that in order to project where a punching attack will launch to.

I’ve just realized that I have clarified absolutely nowhere what the punching action even is. The punches themselves for the boss are not just a standard lunge forward and hit something.

Instead rather they are sort of like large cloned projectiles that fly forward with trusters and are supposed to hit the walls of the arena and get stunned, then the player is able to hit them while in that state.

The reason raycasting is needed here is to project where exactly the fists are launched since they are fired in vague relation to the closest player to the boss. More specifically the boss rotates towards the nearest player then fires the fists in that general direction.

OK. I have at least identified WHERE the issue is, however I am not exactly ABLE to fix it without some kind of assistance.

Let me elaborate:
The issue is being caused by the RaycastParams. I ran a fair few tests and diagnosed this, the Raycasts would fire without the variable however they would immediately hit a close by surface since there was no restriction to what they could hit.

Now, please examine this code:

            local LeftArmClone = game.ServerStorage.LeftArmPunchingClone:Clone()
			local RightArmClone = game.ServerStorage.RightArmPunchingClone:Clone()
			LeftArmClone.Parent = workspace
			RightArmClone.Parent = workspace
			wait(1.65)
			
			LeftArmClone.CFrame = LeftArm.CFrame
			RightArmClone.CFrame = RightArm.CFrame	
			local RayCastParamsVariable = RaycastParams.new()
			RayCastParamsVariable.FilterType = Enum.RaycastFilterType.Blacklist
			local ParentDecendants = {}
			local LeftArmDescendants = {}
			local RightArmDescendants = {}
			for _, Thing in pairs(Boss:GetDescendants()) do
				if Thing.ClassName == "Part" or Thing.ClassName == "UnionOperation" then
					table.insert(ParentDecendants, Thing)
				end
			end
			for _, Thing in pairs(LeftArmClone:GetDescendants()) do
				if Thing.ClassName == "Part" or Thing.ClassName == "UnionOperation" then
					table.insert(LeftArmDescendants, Thing)
				end
			end
			for _, Thing in pairs(RightArmClone:GetDescendants()) do
				if Thing.ClassName == "Part" or Thing.ClassName == "UnionOperation" then
					table.insert(RightArmDescendants, Thing)
				end
			end
			RayCastParamsVariable.FilterDescendantsInstances = {ParentDecendants, LeftArmClone, RightArmClone, LeftArmDescendants, RightArmDescendants, game.Workspace.TestCastleBossArena.Target}

I have changed my approach to the Params Variable since the last time it was showed off, however it still doesn’t work.

Basically the For loops take the Part or UnionOperation instances inside of the arm clones and the boss itself and throw them into tables to put into the Params Variable.

I have printed these tables and they return all of the values they should, however when put into the Params Variable they then don’t function as they probably should when the Raycast itself is fired.

Just to confirm, the error is the same as last time.
[script location]:[line]: attempt to index nil with 'Position'

Is there just a hard limit on how many things can be blacklisted by a Raycastparams instance? What is my problem here???
( I am genuinely losing my mind over this probably really easy to fix issue )

Edit: ok apparently you are just not allowed to store tables inside of a RaycastParams’ table, meaning each value must be entered separately I think unless there’s a way around it

Edit 2: I did think of a much better workaround, I need to somehow use table.insert() in order to put all of the values that are needed into the params table, the problem is I can’t just structure it like table.insert(RayCastParamsVariable.FilterDescendantsInstances, Thing)