首页 > 解决方案 > 加载游戏不会加载玩家的位置

问题描述

我一直在尝试在我的游戏中实现保存游戏功能。当我从保存中加载游戏时,它不会加载玩家的位置。

我有 2 个主要场景:游戏发生的场景和主菜单场景。主菜单使用了我的加载功能,它应该读取我的保存文件并将播放器放在给定位置,但是,它只是在默认位置加载场景。没有错误被抛出,没有警告消息。这是我的所有代码:

这是我的保存游戏系统:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;



public static class SaveSystem 
{
    public static void SavePlayer (Player player)
    {
        BinaryFormatter formatter = new BinaryFormatter();
    string path = Application.persistentDataPath + "player.fun";
    FileStream stream = new FileStream(path, FileMode.Create);

    PlayerData data = new PlayerData(player);

    formatter.Serialize(stream, data);
    stream.Close();
}

public static PlayerData LoadPlayer ()
{

    string path = Application.persistentDataPath + "/player.fun";

    if (File.Exists(path))
    {
        BinaryFormatter formatter = new BinaryFormatter();
        FileStream stream = new FileStream(path, FileMode.Open);

        PlayerData data = formatter.Deserialize(stream) as PlayerData;
        stream.Close();
        return data;
    }
    else
    {
        Debug.LogError("Save file not in " + path);
        return null;
    }
    }
}

玩家数据的容器:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PlayerData 
{
    public int level;
    public int health;
    public float[] position;
    public int stamina;

    public PlayerData (Player player)
    {
        level = player.level;
        health = player.health;
        stamina = player.stamina;
        position = new float[3];

        position[0] = player.transform.position.x;
        position[1] = player.transform.position.y;
        position[2] = player.transform.position.z;
    }


}

我的场景更改脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneChanger : MonoBehaviour
{
    public static bool Isload = false;
    public void gotoWelwardLoad()
    {
        SceneManager.LoadScene("Welward");
        bool Isload = true;
    }
    public void gotoWelward()
    {
        SceneManager.LoadScene("Welward");
    }
    public void gotomainmenu()
    {
        SceneManager.LoadScene("Menu");
    }
}

我的播放器脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MonoBehaviour
{
    public int health = 1;
    public int stamina = 1;
    public int level = 1;

    public void SavePlayer ()
    {
        SaveSystem.SavePlayer(this);
    }

    public void LoadPlayer ()
    {
        SceneManager.LoadScene("Welward");
        PlayerData data = SaveSystem.LoadPlayer();
        level = data.level;
        health = data.health;
        stamina = data.stamina;

        Vector3 position;
        position.x = data.position[0];
        position.y = data.position[1];
        position.z = data.position[2];
        transform.position = position;
    }

    public static void gotomenu ()
    {
        SceneManager.LoadScene("Menu");
    }

    public static void Welward()
    {
        SceneManager.LoadScene("Welward");
        SaveSystem.LoadPlayer();
    }
}

与完整的统一项目文件链接: https ://drive.google.com/open?id=1mFH5aNklC0qMWeJjMT4KD0CbTTx65VRp

标签: c#unity3dsave

解决方案


正如BugFinder正确指出的那样,您的保存路径与加载路径不同。

尝试更改Application.persistentDataPath + "player.fun";Application.persistentDataPath + "/player.fun";以匹配您的加载代码。或者您可以将该string path变量作为 const 向上移动到类中,然后引用它,因为它将保证匹配。

但是,在那之后,您还需要在Player.LoadPlayer()某个地方调用,因为在您现有的项目中,您不会在我能找到的任何地方这样做,并且当您当前调用它时,它会重新加载场景(这可能也不是您想要的行为)。我会SceneManager.LoadScene("Welward");从那个方法中删除。

using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

public static class SaveSystem
{
    // This is a way to make sure your path is the same, and not about to get overwritten
    public static string Path => Application.persistentDataPath + "/player.fun";

    public static void SavePlayer (Player player)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        FileStream stream = new FileStream(Path, FileMode.Create);

        PlayerData data = new PlayerData(player);

        formatter.Serialize(stream, data);
        stream.Close();

        // It's helpful to print out where this is going
        Debug.Log($"Wrote to {Path}");
    }

    public static PlayerData LoadPlayer ()
    {
        if (File.Exists(Path))
        {
            BinaryFormatter formatter = new BinaryFormatter();
            FileStream stream = new FileStream(Path, FileMode.Open);

            PlayerData data = formatter.Deserialize(stream) as PlayerData;
            stream.Close();

            // It's also helpful to print out that it worked, not just log errors if it fails
            Debug.Log($"Successfully read from {Path}");
            return data;
        }
        else
        {
            Debug.LogError("Save file not in " + Path);
            return null;
        }
    }
}

推荐阅读