What do you want to achieve?
I’d like the tower to be spawned at floor level as it is in the preview before it is placed.
What is the issue?
The tower is spawned in a floating position.
Code for the event firing (where position data is sent)
UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if towerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
end
end
end)
Code for the actual placement (Module Script)
local ServerStorage = game:GetService("ServerStorage")
local PhysicsService = game:GetService("PhysicsService")
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.TowersPlaced
newTower.HumanoidRootPart:SetNetworkOwner(nil)
for i, objects in ipairs(newTower:GetDescendants()) do
if objects:IsA("BasePart") then
objects.CollisionGroup = "Tower"
end
end
end
end
spawnTowerEvent.OnServerEvent:Connect(tower.Spawn)
return tower
I’m currently going off a tutorial while making this that is ~1yr old.
If you need any other information then let me know and I’ll get you that information as soon as possible!
You should reference .HumanoidRootPart instead of .PrimaryPart to keep it consistent.
LocalScript code:
UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if towerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.HumanoidRootPart.CFrame)
end
end
end)
I may have found something that could help; When setting the “HipHight” property in the Humanoid, it is level to the ground, but when in the state where the user is chosing where to place it, the tower is in the ground. Here is the code that manages the raycasting and stuff I believe :]
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) * CFrame.Angles(0, math.rad(rotation), 0)
towerToSpawn:SetPrimaryPartCFrame(cframe)
end
end
end)
Alright thanks for the clarification. You may have to subtract the .HipHeight on the CFrame when positioning it.
LocalScript code:
UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if towerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame - Vector3.yAxis * towerToSpawn.Humanoid.HipHeight)
end
end
end)
You said you wanted it to be spawned at floor level as it is in the preview. I assumed this meant it was in the right position in the preview but when you clicked, it just spawned in the air.
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.PrimaryPart.Size.Y / 2)
local z = result.Position.Z
local cframe = CFrame.new(x,y,z) * CFrame.Angles(0, math.rad(rotation), 0)
towerToSpawn:SetPrimaryPartCFrame(cframe)
end
end
end)
LocalScript:
UserInputService.InputBegan:Connect(function(input, processed)
if processed then
return
end
if towerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
spawnTowerEvent:FireServer(towerToSpawn.Name, towerToSpawn.PrimaryPart.CFrame)
end
end
end)