How do I debug this

Before I go in depth about my current problems, I’ll explain my problem I’m having.

I’m trying to make a model that doesn’t revolve around humanoid parts and is anchored while also being able to take damage from attacks. Basically, I’m trying to make a eyeball that stays in the air and attacks players while being able to take damage from other player’s attacks.

Now this is where my problem comes in. Here’s the heriarchy of the model.

Inside Welder, it contains 6 weld constraints that connect to unanchored parts and is anchored on purpose. The unanchored parts are the ones that aren’t the following: Laser, Welder. While the parts do stay in air, it results in the humanoid not being able to take damage and that’s not a result I want, as I want the model to take damage while being in air and being anchored by one part that keeps the model afloat while still being able to be hit my other player’s tools with attacks. I don’t know what to do here, as I know for a fact that humanoids can’t take damage if they aren’t at LEAST moving a slight bit or aren’t anchored, which is not what I want.

In basic terms, I’m trying to make a enemy eyeball that attacks players while being able to take damage and stay in air without having to be on the ground, unanchored just so it can take damage. That is what I’m trying to do that isn’t working out so well.

The most important script that controls the eyeball that should be worth noting is this, since it might be a alternative to what I’m trying to propose as a possible solution. Click here if you want to see it.

Click to see script
local parent = script.Parent

local function nearestHumanPos(origin: Vector3) : Vector3? --ALTERNATE, FOR NPCS
	local nearestPosition: Vector3 = nil;
	local smallestDistance: number = 15000; -- DISTANCE

	for _, human in workspace:GetDescendants() do --GETTING PLAYERS
		--print("ACTIVE")

		if human.Name ~= "Souls" then
			if human.Name ~= parent.EnemyOwner.Value then
				if human.ClassName == "Model" then 
					if human:FindFirstChild("NPCTAG") == nil then
						local hrp = human:FindFirstChild("HumanoidRootPart")
						if hrp then
							local distance = (hrp.Position - origin).Magnitude -- TRACKING PLAYER HUMANOID

							if distance < smallestDistance then
								smallestDistance = distance;
								nearestPosition = hrp.Position;
							end
						end
					end
				end
			end
		end
	end

	return nearestPosition
end

while true do
	local nhp = nearestHumanPos(parent:GetPrimaryPartCFrame().Position)
	if nhp then
		parent.Welder.Anchored = false
		parent:SetPrimaryPartCFrame(CFrame.new(parent:GetPrimaryPartCFrame().Position, nhp))
	elseif nhp == nil then
		parent.Welder.Anchored = true
	end
	task.wait()
end

--This is the same script that I was given by someone by the name of "PhoenixRessusection" on DevForum. 
--No intent to slander, I'm just crediting the original script writer.

--Also worth noting, this script is a modified version of that script, designed for targetting humanoids (players, NPCS.)

--If you are having thoughts about why I made the "Welder" part turn unanchored, it's because I was going to make the eyeball float above players, 
--however I didn't know how to do so even with the AimScript I was provided, so the script isn't finished.

What do I need to do here? If anyone would like to help, please do! I haven’t been able to do anything that gets to do a good amount of progress at fixing this.

6 Likes

Could we see a video about this issue? I can’t seem to make real accurate solutions that might help with this problem as of now.

2 Likes

Just a heads up, the clips might get loud.


The first one is the one with the anchored version. (Above)

The 2nd one is the one with the unanchored version. (Above)

The reason why I’m using NPCS to attack the eyeball is because they function the same way as players using tools to attack. They have the same code that attacks NPCs.

The output isn’t shown as there isn’t any prints being shown in any of the scripts the eyeball has nor are there any errors.

This is the problem being shown in real time. The unanchored one is the version that “works” and the one I don’t want. The anchored version is the one I want, but can’t take damage, which is the core problem of this post.

3 Likes

Ooh, I realized the problem here. You’re most likely using BasePart.Touched to determine if it should take damage or not. But, in this scenario, it wouldn’t work at all. Because this event only fires as a result of physical movement. Meaning, that beam, or the eye, has to be unanchored for the event to get fired. And setting its CFrame each frame won’t do anything, because it’s not simulating any physics on the eye. So, the reason it being unanchored works whilst it being anchored doesn’t, is because the unanchored one is simulating physics, which is firing the touched event. So, ultimately, the issue lies within how you’re determining the damage within your tools.

A way you would resolve that is by changing the method of how the beam detects intersection of parts/humanoids. I’m not a total expert of how you would do that, but I know one way is by using Raycasts/Shapecasts with RunService. You can use this to check if something’s colliding with something else, despite if it’s anchored or not. You would need to check every frame if there’s an instance that has been caught by the cast. If so, then you damage them. But, this can also lead to unintended continuous damage. So, I suggest you also using RaycastParams to blacklist instances that are both not supposed to be gotten by the cast, and those who’ve already been hit by it.

You could also use replace Raycasts/Shapecasts with Workspace:GetPartsInPart. It gets an array of instances that collide with the part specified. But, it won’t take in consideration of the shape of the part, just its CFrame and Size.

Well, I do hope this helped you. But, if what I assumed was wrong, how are you detecting if the ray should be damaging the eyeball, or any instance in particular?

3 Likes

For a physics based eyeball why not use AlignPosition and AlignOrientation?

2 Likes

That would work, however I’m not sure how I would be able to implement that while making the eyeball stay in air, target a player/npc under certain conditions while being able to take damage.

3 Likes

Stay in one spot in the air = AlignPosition.
Orient to players = AlignOrientation.
Take damage = it’s not Anchored.

4 Likes

So how would I use AlignPosition, AlignOrientation in this case? I’m new to those and I have no knowledge on how to use it.

2 Likes

That could work. The problem is, every script that relies on attacking a NPC with a humanoid relies on a .onTouch event and I have practically 0 knowledge of raycasts/Shapecasts. Almost all the attacks rely on CFrames/clones of certain attacks and it’d take too much effort to figure out how to implement raycasts into the attacks. What I mean is that there are also other player’s character attacks and other NPCS, so I’m not just showing one. The code for damaging is virtually the same for others. Also not to mention Workspace:GetPartsInPart, which I also have 0 knowledge of how to use it.

3 Likes

Well, then I won’t suggest switching the scripts systems you don’t know the knowledge of what would’ve been better just yet. I could give you things on how raycasts work, but I think it’s best to follow @Scottifly’s suggestion on using AlignPosition and AlignOrientation. It would make it seem like it’s anchored, when it’s really just being held by a mover constraint.

How you would set it up for your script is, of course, create the instances into the RootPart of the Eyeball, or it’s root part. Have an attachment that would be used for both of these instances. Afterward, just set Attachment0 on them both and turn the RelativeTo to World, to keep it somewhat similar to your script.

Now, how you would code it is sort of the same as how your previous code was, except you’re adding some more variables:

-- Reference your AlignPosition and AlignOrientation somewhere in the script as a global variable
while true do
	local nhp = nearestHumanPos(parent:GetPrimaryPartCFrame().Position)
	local newCFrame = CFrame.new(parent:GetPrimaryPartCFrame().Position, nhp)
	
	if nhp then
		AlignPosition.Position = newCFrame.Position
		AlignOrientation.CFrame = newCFrame
	end
	task.wait()
end

This may not be 100% accurate to what’s set up in your script, but it should help point you at the right direction.

There’s some more things I’d add here, but it’s irrelevant to the topic.

3 Likes

How would I use AlignPosition and AlignOrientation? Although no errors have showed up in the code, the eyeball isn’t changing position or locking onto a target. AlignOrientation and AlignPosition are inside Welder. The attachments however are located in Welder and HumanoidRootPart. In summary, the eyeball isn’t staying in one position and isn’t changing CFrame to lock onto a target.

3 Likes

Alright so I’ve had my first error.

Workspace.EYEBALL..AimScript:35: invalid argument #2 to 'new' (Vector3 expected, got nil) 
3 Likes

Try using GetPivot() instead of GetPrimaryPartCFrame() because it’s deprecated and you might’ve forgot to set the PrimaryPart.

3 Likes

I have set the PrimaryPart. How can I use GetPivot() in this situation?

2 Likes

simply replace it on line 35

flvyengysiw

2 Likes

I have tried that and it has resulted in the same error, that being Workspace.EYEBALL..AimScript:44: invalid argument #2 to 'new' (Vector3 expected, got nil) .

Almost forgot to mention, the reason why the lines in code went up is because I couldn’t get AlignPosition and AlignOrientation working. The “HumanoidRootPart” wasn’t staying in place of AlignPosition. So I created Instances of it.

3 Likes

to fix the new error, simply check if nhp exists

you alr had that on the original script but @edozune removed it

1 Like

and dont forget to change SetPrimaryPartCFrame() to PivotTo() because it’s deprecated too

2 Likes

I’m not sure if you are getting to the root of the problem but what you said didn’t work.

while true do
	local nhp = nearestHumanPos(parent:GetPivot().Position)
	local newCFrame = CFrame.new(parent:GetPivot().Position, nhp)
	if nhp then
		AlignPosition.Position = newCFrame.Position
		AlignOrientation.CFrame = newCFrame
	elseif nhp == nil then
	end
	task.wait()
end

At local newCFrame = CFrame.new(parent:GetPivot().Position, nhp),

Workspace.EYEBALL..AimScript:44: invalid argument #2 to 'new' (Vector3 expected, got nil)

I’ve also have yet to figure out how to make AlignPosition keep HumanoidRootPart in place of the Welder.

2 Likes

put the newCFrame inside the condition just like in your original script

1 Like