加载游戏不会加载玩家的位置

时间:2019-12-17 19:44:31

标签: c# unity3d save

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

我有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

3 个答案:

答案 0 :(得分:1)

值得注意的一件事是在保存时使用Application.persistentDataPath + "player.fun";,在加载时使用Application.persistentDataPath + "/player.fun";因此,也许因此找不到要加载的文件。如您所想。就个人而言,Path.Combine是一个不错的选择,平台不特定,等等。因此,请尝试用Path.Combine(Application.persistentDataPath,"player.fun");替换

答案 1 :(得分:1)

正如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;
        }
    }
}

答案 2 :(得分:0)

根据您提供的代码,我看不到您调用Player.LoadPlayer()的部分。因此,将其添加到Player:

void Start(){
    LoadPlayer();
}

希望有帮助。