How Can I fix this code?


So pretty much when placing in my tower defense game the tower gets lifted up for some reason. I have two scripts one as a local script which is this

local PhysicsService = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local events = ReplicatedStorage:WaitForChild("Events")
local towers = ReplicatedStorage:WaitForChild("Towers")
local spawnTowerEvent = events:WaitForChild("SpawnTower")
local camera = workspace.CurrentCamera
local Gui = script.Parent
local towerToSpawn = nil
local canPlace = false

local function MouseRayCast(blacklist)
	local mousePosition = UserInputService:GetMouseLocation()	
	local mouseRay = camera:ViewportPointToRay(mousePosition.X,mousePosition.Y)
	local raycastParams = RaycastParams.new()
	
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = blacklist
	
	local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000, raycastParams)

	return raycastResult
end

local function RemovePlaceHolderTower()
	if towerToSpawn then
		towerToSpawn:Destroy()
		towerToSpawn = nil
	end
end

local function AddPlaceHolderTower(name)
	local towerExists = towers:FindFirstChild(name)
	if towerExists then 
		RemovePlaceHolderTower()
	    towerToSpawn = towerExists:Clone()
		towerToSpawn.Parent = workspace.Towers
		
		for i, object in ipairs(towerToSpawn:GetDescendants()) do 
			if object:IsA("BasePart") then 
				PhysicsService:SetPartCollisionGroup(object, "Tower")
				object.Material = Enum.Material.ForceField
			end
			end
	end
end

local function ColorPlaceHoldertower(color)
	for i, object in ipairs(towerToSpawn:GetDescendants()) do 
		if object:IsA("BasePart") then 
			object.Color = color
		end
		end
end

Gui.Spawn.Activated:Connect(function()
	AddPlaceHolderTower("Rifleman")
end)

UserInputService.InputBegan:Connect(function(input, processed)
	if processed then 
		return
	end
	
	if towerToSpawn then 
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
				spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
				RemovePlaceHolderTower()
			end
			
	end	
end
end)

RunService.RenderStepped:Connect(function()
	if towerToSpawn then 
		local result = 	MouseRayCast({towerToSpawn})
		if result and result.Instance then 
			if result.Instance.Parent.Name == "TowerArea" then 
				canPlace = true
				ColorPlaceHoldertower(Color3.new(0,1,0))
			else 
				canPlace = false
				ColorPlaceHoldertower(Color3.new(1,0,0))
			end
			local X = result.Position.X
			local Y = result.Position.Y + towerToSpawn.Humanoid.HipHeight + (towerToSpawn.PrimaryPart.Size.Y / 2)
			local Z = result.Position.Z

			local cframe = CFrame.new(X,Y,Z)
			towerToSpawn:SetPrimaryPartCFrame(cframe)
		end
		end
	
end)

Then this is the script where problem most likely lies. Its a module script:

local PhysicsService = game:GetService("PhysicsService")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local events = ReplicatedStorage:WaitForChild("Events")
local spawnTowerEvent = events:WaitForChild("SpawnTower")
local tower = {}


function tower.Spawn(player, name, cframe)
	local towerExists = ReplicatedStorage.Towers:FindFirstChild(name)	
	
	if towerExists then 
		local newTower = towerExists:Clone()
		newTower.HumanoidRootPart.CFrame = cframe
		newTower.Parent = workspace.Towers
		newTower.HumanoidRootPart:SetNetworkOwner(nil)

		for i, object in ipairs(newTower:GetDescendants()) do 
			if object:IsA("BasePart") then 
				PhysicsService:SetPartCollisionGroup(object, "Tower")
			end
		end
	else 
		warn("Requested tower does not exist", name)
	end
end

spawnTowerEvent.OnServerEvent:Connect(tower.Spawn)

return tower

If anybody can tell me where I went wrong I’d greatly appreciate it!

2 Likes

Check HipHeight property in Humanoid

2 Likes

it’s at 2 if I changed it reckon it would help?

2 Likes

No idea if it would help can you try putting part under the NPC and seeing if it would go up?

1 Like

with a part there it still goes up the exact same amount as it did on baseplate. I’m pretty sure problem is somewhere in Module script but I can’t figure it out.

2 Likes

So when you put part under it or just make the ground higher it goes up?

1 Like

yeah still goes up the exact same amount (like same distance up away from part it was placed on) if i put a part under it

2 Likes

Why not just put the NPC lower after its placed? (actually i was just looking at the code you add the height by the HipHeight of the humanoid can you try setting it lower?)

would I need to add a wait before doing so because there is a lag between when it goes up like seen in video

1 Like

also hipheight just changed the display tower which is working perfectly fine. It’s just when it gets placed.

1 Like

Ok i found it prob
from:

local X = result.Position.X
local Y = result.Position.Y + towerToSpawn.Humanoid.HipHeight + (towerToSpawn.PrimaryPart.Size.Y / 2)
local Z = result.Position.Z

to:

local X = result.Position.X
local Y = result.Position.Y + towerToSpawn.Humanoid.HipHeight)
local Z = result.Position.Z

Just removed the humanoid root part position add if im not blind i saw that the NPC was 1 stud from ground and you dont really need to add the primarypart position

1 Like

It just made the tower show case sink into the ground and the proper tower when placed still levitates
image

2 Likes

nvm you sent screenshot im blind

lol i edited it after coz i forgot to paste screenshot

1 Like
	if towerToSpawn then 
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
				spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
				RemovePlaceHolderTower()
			end
			
	end	

Ok so this is the place where you fire the server right?
if yes then you prob send wrong CFrame pos (try putting the CFrame one stud lower)

yes that is the place. what position should I send?

1 Like
	if towerToSpawn then 
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			if canPlace then
				spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame*CFrame.new(0,-1,0))
				RemovePlaceHolderTower()
			end
			
	end	

The following line:

Has to be above the line where you set the CFrame, I have not checked the code quickly, but I think the client still edits the CFrame when it ends. Else check server-sidedly if it’s placed correctly and maybe it’s only placed wrong Client-sidedly.

Another thing it could be:
You have to Set the HipHeight to 0 and if you could then Anchor the Root.

2 Likes


still doesnt change anything

1 Like

isnt that even higher? if yes then try to put CFrame.new(0,1,0) instead of CFrame.new(0,-1,0)