Player position not being set correctly

I’m trying to make a game saving object and I’m on the position saving part. The glowing yellow part (it will be completely transparent in the complete game) is where the player is supposed to get to when joining the game again after saving. It’s just that the player’s position doesn’t get set directly as the yellow part’s position.

Here is the script for saving:

local me = script.Parent
local tags = game:GetService("CollectionService")
local ser = game:GetService("DataStoreService")
local jingle = game.Workspace["game sounds"].SAVE

local store = ser:GetDataStore("POS")

for i, box in pairs(tags:GetTagged("SAVE POINT")) do
	local pro = box:FindFirstChildWhichIsA("ProximityPrompt")
	if pro then
		pro.Triggered:Connect(function(plr)
			jingle:Play()
			local id = tostring(plr.UserId)
			
			local char = plr.Character
			local hum = char:FindFirstChildWhichIsA("Humanoid")
			local rp = hum.RootPart
			
			local dest = box.Parent:FindFirstChild("NEW SPAWN POINT")
			
			if dest and dest:IsA("BasePart") then
				local pos = {
					X = dest.CFrame.X,
					Y = dest.CFrame.Y,
					z = dest.CFrame.Z
				}

				store:SetAsync(id, pos)
				print(pos)
				print(dest.CFrame.Position)
			end
		end)
	end
end

Here is the code for loading the position:

local me = script.Parent
local ser = game:GetService("DataStoreService")

local store = ser:GetDataStore("POS")

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		local id = tostring(plr.UserId)
		
		local pos = store:GetAsync(id)
		if pos then
			local hum = char:FindFirstChildWhichIsA("Humanoid")
			local rp = hum.RootPart
			
			rp.CFrame = CFrame.new(pos.X, pos.Y, pos.Z)
		end
	end)
end)

Here is a video showing what is happening:

2 Likes

I don’t really understand what is your error? Is there an error with saving the data or loading it? Try utilizing print statements to find the root of your error.

Also, I’d suggest you use complete variable names like position instead of pos, or HumanoidRootPart instead of rp, it helps you and others understand the script better.

The problem is that the player’s position is kinda off when spawning back in after saving.

What’s supposed to happen is that the player should be teleported to the position of the yellow glowing part upon spawning back in. The X, Y, and Z of the position of the yellow part (named “dest” for a variable) is saved to a datastore as a table when the ProximityPrompt (pro) is triggered. When the player spawns back and if the player saved, the player’s HumanoidRootPart’s CFrame has its X, Y, and Z set to those in the datastore.

There isn’t really anything showing up in the dev console.

Ey, for the SetAsync part, I would recommend putting it when you do Game.Players.PlayerRemoving or I would copy that whole for loop and put it in PlayerRemoving function without the triggered function and it will do it if the player has triggered in-game and you can set a bool value to true, so it can give a detection and when you rejoin, you can put a datastore save to that value to true. This could fix the problem with rejoining.

Now, for positioning, I would use position instead of CFrame and you don’t have to get each value individually when you can just do local posValues = rp.HumanoidRootPart.Position or you can use brackets around it to get the values that way if you want to use tables and test with that. Don’t know what will happen with the brackets part, but you can give it a try.

Let me know if this fixes it! Logic errors are a pain lmfao.

1 Like

The game is single player and so the server will close before the position can even be saved using PlayerRemoving. I also already tried setting the position instead of the CFrame and it messes up the player’s position in the server side. There isn’t really a problem with the saving too since the values are being saved as intended.

1 Like

I would suggest to use a :Move or :MoveTo and see if that would teleport the player automatically to that position when putting it inside the brackets, so you can get the player’s model or humanoidrootpart and move it. It’ll move along the player.

For the server part, you can wrap a pcall around the getasync part and you can also try the setasync part too.

You can also add in a game:BindToClose function and copy the saving part in there without the prompt part, but rely on a bool value to make sure the data is saved properly through server shutdowns or last player leaving.

There are going to be multiple of them saving cubes around my game’s map and so it’s better to save right upon interacting with them where data can be immediately overwritten and stuff. MoveTo() and Move() pretty much makes a character walk by the way, not teleport.

1 Like

Thanks for the mention on MoveTo and Move. I think the major issue is revolving around the position values that get saved to further be assigned to replace the humanoidrootpart’s current position to that yellow part position. Do a separate local test script to retrieve those values if you got the yellow part values and you can do an event where the humanoid root part will be transported over there. Add a wait at the beginning for a few secs to see results.

Test script… Not sure if this is what you’re looking for.

--ServerScript in ServerScriptService
local pad = workspace:WaitForChild("Pad") --move to part/pad

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoid = character:WaitForChild("Humanoid") --loaded pause

		task.wait(3) --pause to see the move for this test

		character:MoveTo(pad.CFrame.p + Vector3.new(0, 3, 0)) --move and height trim
		character:SetPrimaryPartCFrame(CFrame.new(character.PrimaryPart.Position) 
			* CFrame.Angles(0, math.rad(45), 0)) --facing angle
	end)
end)
Camera angle test
--LoaclScript in StarterGui (this is only a test for setting camera angle)
task.wait(4) --pause works with testing pause from other script.
--you would need to be a bit more tricky than this, this is just for testing.
--this moves the Camera behind the players current angle.

local cam = workspace.CurrentCamera
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")

cam.CameraSubject = humanoid
cam.CameraType = "Custom"

local _, ang, _ = char.PrimaryPart.CFrame:ToEulerAnglesYXZ()
local pos = math.deg(ang)

cam.CFrame = CFrame.new(cam.CFrame.Position) * CFrame.Angles(0, math.rad(pos), 0)
1 Like

Problem is likely because of mismatch in your saved position table, in your saving code you create the table like this:

local pos = {
    X = dest.CFrame.X,
    Y = dest.CFrame.Y,
    z = dest.CFrame.Z
}

And later in your loading code you try to access it as pos.Z as uppercase letter. Tables are sensitive, so “z” and “Z” are two different keys. If you change that bit to this below, it might work.

local pos = {
    X = dest.CFrame.X,
    Y = dest.CFrame.Y,
    Z = dest.CFrame.Z
}

After tring this, tell me if there are any errors in output, peace!

3 Likes

Oh my goodness I am going to strangle my shift key (your correction worked)

1 Like

I tested this script out. What does the MoveTo do?

Glad it worked out for you, small issues are often the cause of bugs like this.

1 Like

A pad like a part on the workspace you set up … I was more trying a quick test set up so I could work on the calls to get the move and angle right. Sure didn’t catch what Astro saw… good call.

By saying Test Script, I mean a fresh new project with just these scripts testing on run.
The other script is after the move, would have to quickly trigger that to a LocalScript.

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.