Problem with Specific Object Rotation | Placement System

Hey guys, how are all of you? I hope you are doing well. Alrighty so, today I started working on a placement system for my game and it works much better than my old one but that’s beside the point. The issue I am having with this system is with a specific rotation of the object, all of the other rotations work except for this one; see the video below:

Current code for this (ignore spaghetti code, going to rewrite later):

local isInsideHitbox = false

local axisisis = {"X","Z"}

local function PlotBounds(point)
	local relativePoint = CFrame.new(Plot.CFrame:PointToObjectSpace(point))
	
	local valid = {
		X = false,
		Y = false,
		Z = false,	
	}
	
	local X,Y,Z = hitbox.CFrame:ToEulerAnglesXYZ()
	
	
	for _,axis in pairs(axisisis) do
		local PlotSize = (Vector3.new(math.abs(Plot.Size.X), math.abs(Plot.Size.Y), math.abs(Plot.Size.Z)))/2
		
		local modelSize = CFrame.fromEulerAnglesYXZ(X, Y, Z) * hitbox.Size
		modelSize = Vector3.new(math.abs(math.round(modelSize.X)), math.abs(math.round(modelSize.Y)), math.abs(math.round(modelSize.Z)))/2
		
		local ObjMin = hitbox.Position - modelSize
		local ObjMax = hitbox.Position + modelSize
		
		local BoundDistance = ((Plot.Size[axis]/2) - modelSize[axis])
		
		--print(math.abs(relativePoint[axis]), ((Plot.Size[axis]/2) - modelSize[axis]))
	
		if ObjMax.Y <= (Plot.Position.Y + PlotSize.Y) + 20 then
			valid["Y"] = true
		else valid["Y"] = false	 end
		
		if math.abs(relativePoint[axis]) <= BoundDistance then 
			valid[axis] = true
		else valid[axis] = false end
	end
	
	--print(valid["X"] , valid["Y"] , valid["Z"])
	if valid["X"] and valid["Y"] and valid["Z"] then 
		isInsideHitbox = true
	else
		isInsideHitbox = false
	end
	
end

If you have any questions please ask, I really don’t wanna go down the if statement fix route :grimacing:

Thanks guys!

I have no clue to what you can do about that, sorry dude.

All good, once I find a fix I’ll post it here

1 Like

After many hours of tourment and struggle I have finally done it lol

I decided to go with a complete different approach to this and it was well worth it because it works way better and is more reliable now, also allows me to use full 360 deg rotations for my model and still be able to detect clip from boundary, grid sizes will work perfectly with this as well.

Now since I am feeling generous, I will supply you with a video and my final product of code below

(the corner parts are just for debug and showcase)

local Plot = workspace.Plot
local Hitbox = script.Parent


local InsideBoundaries = false

local MaxHeight = 20


local function UpdatedCornerCFrames(Size)
	return {
		Corner1 = Hitbox.CFrame * CFrame.new(-Size.X, -Size.Y, -Size.Z),
		Corner2 = Hitbox.CFrame * CFrame.new(Size.X, -Size.Y, Size.Z),
		Corner3 = Hitbox.CFrame * CFrame.new(-Size.X, Size.Y, -Size.Z),
		Corner4 = Hitbox.CFrame * CFrame.new(Size.X, Size.Y, Size.Z),

		Corner5 = Hitbox.CFrame * CFrame.new(-Size.X, -Size.Y, Size.Z),
		Corner6 = Hitbox.CFrame * CFrame.new(Size.X, -Size.Y, -Size.Z),
		Corner7 = Hitbox.CFrame * CFrame.new(-Size.X, Size.Y, Size.Z),
		Corner8 = Hitbox.CFrame * CFrame.new(Size.X, Size.Y, -Size.Z),
	}
end

local function PlotBoundary(point)
	local RelativePoint = Plot.CFrame:PointToObjectSpace(point)
	local PlotSize = (Vector3.new(math.abs(Plot.Size.X), math.abs(Plot.Size.Y), math.abs(Plot.Size.Z)))/2
	
	local X,Y,Z = Hitbox.CFrame:ToEulerAnglesXYZ()
	
	local ModelSize = CFrame.fromEulerAnglesYXZ(X, Y, Z) * Hitbox.Size
	ModelSize = Vector3.new(math.abs(math.round(ModelSize.X)), math.abs(math.round(ModelSize.Y)), math.abs(math.round(ModelSize.Z)))/2
	
	local CornerTable = UpdatedCornerCFrames(Hitbox.Size/2)
	
	for i, Corner in pairs(CornerTable) do
		
		local DummyPart = workspace.Terrain.Parts[i]
		
		DummyPart.CFrame = Corner
		
		local Position = Plot.CFrame:PointToObjectSpace(Corner.Position)
		
		local BoundDistX = (Plot.Size.X/2 - ModelSize.X)
		local BoundDistZ = (Plot.Size.Z/2 - ModelSize.Z)
	
		local WithinX = (Position.X >= -(BoundDistX + ModelSize.X) and Position.X <= (BoundDistX + ModelSize.X))
		local WithinY = (Hitbox.Position.Y - ModelSize.Y) <= (Plot.Position.Y + PlotSize.Y) + 20
		local WithinZ = (Position.Z >= -(BoundDistZ + ModelSize.Z) and Position.Z <= (BoundDistZ + ModelSize.Z))
		
		if WithinX and WithinY and WithinZ then
			DummyPart.BrickColor = BrickColor.Green()
			InsideBoundaries = true
			
		else
			DummyPart.BrickColor = BrickColor.Red()
			InsideBoundaries = false
			break
		end
		
	end
	
end


game:GetService("RunService").Heartbeat:Connect(function()
	PlotBoundary(Hitbox.Position)
	
	if InsideBoundaries then
		Hitbox.BrickColor = BrickColor.new("Lime green")		
	else
		Hitbox.BrickColor = BrickColor.new("Really red")
	end
end)

2 Likes