Hello everyone, so I’m currently creating a custom movement which is the same as the game “Bloxorz” it works great until we reach the edge of the baseplate and it shows some weird behavior
as seen on the video the block does this weird behavior when it’s near the edge
here is the relevant code for it. any help would be greatly appreciated
function Movement:_getRotation(Keycode: Enum.KeyCode): CFrame
--
if Keycode.Name == "A" then
return CFrame.Angles(0,0, math.rad(ANGLE))
elseif Keycode.Name == "D" then
return CFrame.Angles(0,0, math.rad(-ANGLE))
elseif Keycode.Name == "W" then
return CFrame.Angles(math.rad(-ANGLE),0, 0)
elseif Keycode.Name == "S" then
return CFrame.Angles(math.rad(ANGLE),0, 0)
end
end
-- Checks if Bloxorz is Lying Down
function Movement:_isLyingDown(CurrentBloxor: Model): boolean
--
local Bloxorz = CurrentBloxor
--
local BloxorSize = Bloxorz:GetExtentsSize()
local BloxorzCFrame = Bloxorz:GetPivot()
--
local UpCast = workspace:Raycast(BloxorzCFrame.Position, BloxorzCFrame.UpVector * (BloxorSize.Y + .1), CastParams)
local DownCast = workspace:Raycast(BloxorzCFrame.Position, -BloxorzCFrame.UpVector * (BloxorSize.Y + .1), CastParams)
if UpCast or DownCast then
return false
end
return true
end
-- This Simulates a Move First If the Bloxor Will Stand After Moving so We Can Offset It Properly
function Movement:_willStandAfterMove(Keycode: Enum.KeyCode, PositionToSet: Vector3): boolean
--
local GhostBloxorz = self.GhostBloxorz
--
local TempBloxorz = self.BloxorzModel:Clone()
TempBloxorz:PivotTo(GhostBloxorz:GetPivot())
local TempBloxorzCFrame = TempBloxorz:GetPivot()
local Rotation = self:_getRotation(Keycode)
local Position = PositionToSet
--
TempBloxorz:PivotTo(Rotation * (TempBloxorzCFrame - TempBloxorzCFrame.Position) + (TempBloxorzCFrame.Position + Position))
--
local IsLyingDown = self:_isLyingDown(TempBloxorz)
TempBloxorz:Destroy()
return not IsLyingDown
end
-- Gets the Position to Move to
function Movement:_getPositiontoMove(Keycode: Enum.KeyCode)
--
local GhostBloxorz: Model = self.GhostBloxorz
-- Get Movement Offset
local YOffset = GhostBloxorz.PrimaryPart.Size.Y
local XOffset = GhostBloxorz.PrimaryPart.Size.X
------ LEFT / RIGHT MOVEMENT
if Keycode.Name == "A" then
if self:_isLyingDown(GhostBloxorz) then
if self:_willStandAfterMove(Keycode, Vector3.new(-XOffset, 0, 0)) then
return Vector3.new(-YOffset * MOVE_OFFSET, 0, 0)
end
return Vector3.new(-XOffset, 0, 0)
end
return Vector3.new(-YOffset * MOVE_OFFSET, 0, 0)
elseif Keycode.Name == "D" then
if self:_isLyingDown(GhostBloxorz) then
if self:_willStandAfterMove(Keycode, Vector3.new(-XOffset, 0, 0)) then
return Vector3.new(YOffset * MOVE_OFFSET, 0, 0)
end
return Vector3.new(XOffset, 0, 0)
end
return Vector3.new(YOffset * MOVE_OFFSET, 0, 0)
------ FRONT / BACK MOVEMENT
elseif Keycode.Name == "W" then
if self:_isLyingDown(GhostBloxorz) then
if self:_willStandAfterMove(Keycode, Vector3.new(0, 0,XOffset)) then
return Vector3.new(0, 0,-YOffset * MOVE_OFFSET)
end
return Vector3.new(0, 0,-XOffset)
end
return Vector3.new(0, 0,-YOffset * MOVE_OFFSET)
elseif Keycode.Name == "S" then
if self:_isLyingDown(GhostBloxorz) then
if self:_willStandAfterMove(Keycode, Vector3.new(0, 0,XOffset)) then
return Vector3.new(0, 0,YOffset * MOVE_OFFSET)
end
return Vector3.new(0, 0,XOffset)
end
return Vector3.new(0, 0,YOffset * MOVE_OFFSET)
end
end
-- Compiles Everything to Move the Bloxorz
function Movement:_process(Keycode: Enum.KeyCode)
--
if self._inProcess then return end
if self.BloxorzModel:GetAttribute("Died") then return end
-- Get Bloxor Model
local Bloxorz: Model = self.BloxorzModel
local GhostBloxorz: Model = self.GhostBloxorz
local BloxorSize = GhostBloxorz:GetExtentsSize()
local GhostBloxorzCFrame = GhostBloxorz:GetPivot()
-- Get Moveset
local Rotation = self:_getRotation(Keycode)
local Position = self:_getPositiontoMove(Keycode)
if not Rotation or not Position then return end
-- Position Ghost Bloxor to Initial CFrame
self._inProcess = true
GhostBloxorz.PrimaryPart.Anchored = false
GhostBloxorz:PivotTo(Rotation * (GhostBloxorzCFrame - GhostBloxorzCFrame.Position) + (GhostBloxorzCFrame.Position + Position - Vector3.new(0, 2, 0)))
--
task.wait()
GhostBloxorz.PrimaryPart.Anchored = true
TweenService:Create(Bloxorz.PrimaryPart, MOVE_TWEENINFO, {CFrame = GhostBloxorz:GetPivot()}):Play()
UpdatePositionBridge:Fire(GhostBloxorz:GetPivot())
task.delay(MOVE_TWEENINFO.Time / 2, function()
self._inProcess = false
end)
end