Hey!
I’m finishing up my placement system, and I ran intro the issue of using a real rig, not just a block, now, It’s just halfway into the ground for no reason. Why? I think it may be to do with Humanoid.HipHeight, But I have no idea.
Script:
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")
local getMap = ReplicatedStorage.SelectedMap
if not getMap.Value then
getMap:GetPropertyChangedSignal("Value"):Wait()
end
local getReplicatedMap = ReplicatedStorage.Maps:FindFirstChild(tostring(getMap.Value))
if not getReplicatedMap then
error("REPLICATED MAP: "..getMap.Name.." DOES NOT EXIST")
end
local PlacementEvents = ReplicatedStorage:WaitForChild("PlacementEvents")
local PlacementEventsMain = PlacementEvents:WaitForChild("Main")
local spawnTowerEvent = PlacementEventsMain:WaitForChild("SpawnTower")
local Camera = workspace.Camera
local gui = script.Parent
local TowerToSpawn = nil
local CanPlace = false
local Rotation = 0
local Placing = 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
UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return --gameProcessed means inputed in different object e.g chat
end
if TowerToSpawn then
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if CanPlace then
spawnTowerEvent:FireServer(TowerToSpawn.Name, TowerToSpawn.PrimaryPart.CFrame)
RemovePlaceholderTower()
end
elseif input.KeyCode == Enum.KeyCode.R then
Rotation += 90
end
end
end)
function RemovePlaceholderTower()
if TowerToSpawn then
TowerToSpawn:Destroy()
TowerToSpawn = nil
Rotation = 0
Placing = false
for i, tower in ipairs(workspace.Towers.ActiveTowers:GetChildren()) do
tower.RangeBox.Transparency = 1
end
end
end
local function AddPlaceHolderTower(name : string)
local towerExists = getReplicatedMap.Towers:FindFirstChild(tostring(name))
if towerExists and Placing == false then
TowerToSpawn = towerExists:Clone()
TowerToSpawn.Parent = workspace.Towers.PlacingTowers
for i, object in ipairs(TowerToSpawn:GetDescendants()) do
if object:IsA("BasePart") then
PhysicsService:SetPartCollisionGroup(object, "Tower")
end
end
for i, tower in ipairs(workspace.Towers.ActiveTowers:GetChildren()) do
tower.RangeBox.Transparency = 0
end
Placing = true
end
end
local function ColorPlaceholderTower(color)
for i, object in ipairs(TowerToSpawn:GetDescendants()) do
if object:IsA("BasePart") and object.Name ~= "RangeBox" then
object.Color = color
end
end
if not CanPlace then
TowerToSpawn.Range.Transparency = 1
else
TowerToSpawn.Range.Transparency = 0
end
end
gui["1"].MainButton.Activated:Connect(function()
AddPlaceHolderTower("Tower")
end)
gui["2"].MainButton.Activated:Connect(function()
AddPlaceHolderTower("Dummy")
end)
RunService.RenderStepped:Connect(function()
if TowerToSpawn then
local result = MouseRaycast({TowerToSpawn})
if result and result.Instance then
local GetRangeBoxTouchingParts = TowerToSpawn.RangeBox:GetTouchingParts()
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
for index, part in ipairs(GetRangeBoxTouchingParts) do
if part.Name == "RangeBox" and part.Parent ~= TowerToSpawn then
CanPlace = false
ColorPlaceholderTower(Color3.new(1,0,0))
end
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)
PhysicsService:SetPartCollisionGroup(TowerToSpawn.Range,"Tower")
PhysicsService:SetPartCollisionGroup(TowerToSpawn.RangeBox,"TowerBox")
TowerToSpawn.Range.Size = Vector3.new(0.1, TowerToSpawn.Levels[TowerToSpawn.CurrentLevel.Value].Range.Value * 2, TowerToSpawn.Levels[TowerToSpawn.CurrentLevel.Value].Range.Value * 2)
end
end
end)