Ok so, I have a voxel character that likes hops around, and I’m trying to make it where if an object intersects a ray that goes in the direction the voxel is about to hop towards, then it doesn’t move in that direction. It sometimes works, but the ray will detect a part right next to it instead of in front of it sometimes, and other times detect a part diagonal to it.
Here is the entire code, but I believe the problem is in the moveVoxelEnded.OnServerEvent portion, but I’m probably wrong since I’ve been starring at it for like 3 hours.
Code
--[[
Created By: PlantMaker123
Started On: 6/18/2020
Finished On: N/A
Purpose: To move the voxelCharacter Associated
with the player.
]]
----Services----
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RepStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
----Assigned Variables----
local playerFolder = Workspace.PlayerFolder
local carFolder = Workspace.CarFolder
local moveVoxel = RepStorage.MoveVoxel
local moveVoxelEnded = RepStorage.MoveVoxelEnded
----Custom Variables----
local TIME_TO_CROUCH = .3
local CROUCH_HEIGHT = 3.5 --max of 5
local JUMP_HEIGHT = 1 --stud
local JUMP_LENGTH = .3
local MOVEMENT_UPDATE_IN_SEC = 1
----Function----
local crouchHieghtCorrection = (5 - CROUCH_HEIGHT)/2
moveVoxel.OnServerEvent:Connect(function(player, direction, voxel)
local voxelMesh = voxel.Mesh
local moveDirection = voxel.Direction
local isCrouching = voxel.IsCrouching
local waitForMove = voxel.WaitForMove
if not waitForMove.Value then
local crouchTweenInfo = TweenInfo.new(
TIME_TO_CROUCH,
Enum.EasingStyle.Quint,
Enum.EasingDirection.Out,
0,
false,
0
)
local crouchGoals = {
Size = Vector3.new(5, CROUCH_HEIGHT, 5)
}
local crouchMeshGoals = {
Scale = Vector3.new(5, CROUCH_HEIGHT, 5)
}
if direction == "Up" then
if isCrouching.Value == true then
crouchGoals.Position = voxel.Position
else
crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
end
crouchGoals.Orientation = Vector3.new(0,0,0)
local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
tween:Play()
meshTween:Play()
isCrouching.Value = true
moveDirection.Value = "Up"
elseif direction == "Down" then
if isCrouching.Value == true then
crouchGoals.Position = voxel.Position
else
crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
end
if moveDirection.Value == "Down" then
print("hey")
crouchGoals.Orientation = nil
else
crouchGoals.Orientation = Vector3.new(0, 180, 0)
end
local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
tween:Play()
meshTween:Play()
isCrouching.Value = true
moveDirection.Value = "Down"
elseif direction == "Right" then
if isCrouching.Value == true then
crouchGoals.Position = voxel.Position
else
crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
end
crouchGoals.Orientation = Vector3.new(0,-90,0)
local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
tween:Play()
meshTween:Play()
isCrouching.Value = true
moveDirection.Value = "Right"
elseif direction == "Left" then
if isCrouching.Value == true then
crouchGoals.Position = voxel.Position
else
crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
end
crouchGoals.Orientation = Vector3.new(0,90,0)
local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
tween:Play()
meshTween:Play()
isCrouching.Value = true
moveDirection.Value = "Left"
end
end
end)
moveVoxelEnded.OnServerEvent:Connect(function(player, direction, voxel)
local voxelMesh = voxel.Mesh
local moveDirection = voxel.Direction
local hit = voxel.Hit
local isCrouching = voxel.IsCrouching
local waitForMove = voxel.WaitForMove
if not waitForMove.Value then
waitForMove.Value = true
print(voxel.Position)
--rays
local confirmMoveUp = Ray.new(voxel.Position, voxel.Position + Vector3.new(0, 0, -5))
local confirmMoveDown = Ray.new(voxel.Position, voxel.Position + Vector3.new(0, 0, 5))
local confirmMoveRight = Ray.new(voxel.Position, voxel.Position + Vector3.new(5, 0, 0))
local confirmMoveLeft = Ray.new(voxel.Position, voxel.Position + Vector3.new(-5, 0, 0))
--Creates Ignore table for ray
local ignoreRayList = carFolder:GetChildren()
table.insert(ignoreRayList, 1, voxel)
--TweenInfo and Goals
local standTweenInfo = TweenInfo.new(
.01,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out,
0,
false,
0
)
local standGoals = {
Size = Vector3.new(5, 5, 5);
Position = Vector3.new(voxel.Position.X, 0, voxel.Position.Z)
}
local standMeshGoals = {
Scale = Vector3.new(5, 5, 5)
}
if moveDirection.Value == "Up" and direction == "Up" then
hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveUp, ignoreRayList)
standGoals.Orientation = Vector3.new(0,0,0)
local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
tween:Play()
meshTween:Play()
print(hit.Value)
if not hit.Value then
tween.Completed:Connect(function()
for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC do
local y = -.16*i^2+.8*i
voxel.Position = Vector3.new(voxel.Position.X, y, voxel.Position.Z - 1/MOVEMENT_UPDATE_IN_SEC)
wait(.0025)
end
waitForMove.Value = false
isCrouching.Value = false
end)
else
waitForMove.Value = false
isCrouching.Value = false
end
elseif moveDirection.Value == "Down" and direction == "Down" then
hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveDown, ignoreRayList)
if moveDirection.Value == "Down" then
print("hey")
standGoals.Orientation = nil
else
standGoals.Orientation = Vector3.new(0,180,0)
end
local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
tween:Play()
meshTween:Play()
print(hit.Value)
if not hit.Value then
tween.Completed:Connect(function()
for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC do
local y = -.16*i^2+.8*i
voxel.Position = Vector3.new(voxel.Position.X, y, voxel.Position.Z + 1/MOVEMENT_UPDATE_IN_SEC)
wait(.0025)
end
waitForMove.Value = false
isCrouching.Value = false
end)
else
waitForMove.Value = false
isCrouching.Value = false
end
elseif moveDirection.Value == "Right" and direction == "Right" then
hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveRight, ignoreRayList)
standGoals.Orientation = Vector3.new(0,270,0)
local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
tween:Play()
meshTween:Play()
print(hit.Value)
if not hit.Value then
tween.Completed:Connect(function()
for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC do
local y = -.16*i^2+.8*i
voxel.Position = Vector3.new(voxel.Position.X + 1/MOVEMENT_UPDATE_IN_SEC, y, voxel.Position.Z)
wait(.0025)
end
waitForMove.Value = false
isCrouching.Value = false
end)
else
waitForMove.Value = false
isCrouching.Value = false
end
elseif moveDirection.Value == "Left" and direction == "Left" then
hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveLeft, ignoreRayList)
standGoals.Orientation = Vector3.new(0,90,0)
local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
tween:Play()
meshTween:Play()
print(hit.Value)
if not hit.Value then
tween.Completed:Connect(function()
for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC do
local y = -.16*i^2+.8*i
voxel.Position = Vector3.new(voxel.Position.X - 1/MOVEMENT_UPDATE_IN_SEC, y, voxel.Position.Z)
wait(.0025)
end
waitForMove.Value = false
isCrouching.Value = false
end)
else
waitForMove.Value = false
isCrouching.Value = false
end
else
waitForMove.Value = false
end
end
end)
Some more info on the code: A local script on the player sends the player input along with the player object as the parameter.
And a visual representation for you:
FYI, it doesn’t show it in the video, but the character is able to go back to the starting position.