«Как исправить PlayerPrefs не сохранять или загружать сохраненные данные» - PullRequest
1 голос
/ 11 мая 2019

Итак, я работаю с настройщиком для моей игры со змеями и использую PlayerPrefs, чтобы сохранить предпочтительный вид змеи.Теперь каждый раз, когда я тестирую игру, сохраненная строка в playerprefs не загружается, она просто пуста.

Я уже пытался получить строковые данные в Start (), Awake () и Update () и ни один из них не загружает данные.Также я добавляю PlayerPrefs.Save () в каждую строку, где я сохраняю данные.

Вот мой код для обновления всей сетки, чтобы она была такой же, как и сохраненная строка.Я поместил его в метод обновления.

lesnek = GameObject.FindGameObjectsWithTag("LeWorm");

        objName = PlayerPrefs.GetString("meshName");

        if (PlayerPrefs.HasKey("meshName"))
        {
            if (objName == PlayerPrefs.GetString("meshName"))
            {
                leMesh = Resources.Load<GameObject>(@"Models\" + objName);
            }
            else
            {
                objName = PlayerPrefs.GetString("meshName");
                leMesh = Resources.Load<GameObject>(@"Models\" + objName);
            }
        }
        if (objName != null || objName != "")
        {
            objName = "Sphere";
            leMesh = Resources.Load<GameObject>(@"Models\" + objName);
        }

        foreach (GameObject change in lesnek)
        {
            if (objName != null || objName != "")
            {
                if (change.GetComponent<MeshFilter>() == null)
                {
                    change.AddComponent<MeshFilter>();
                    change.GetComponent<MeshFilter>().mesh = leMesh.GetComponent<MeshFilter>().sharedMesh;
                    PlayerPrefs.SetString("meshName", objName);
                    PlayerPrefs.Save();
                }
                else
                {
                    change.GetComponent<MeshFilter>().mesh = leMesh.GetComponent<MeshFilter>().sharedMesh;
                    PlayerPrefs.SetString("meshName", objName);
                    PlayerPrefs.Save();
                }
            }
        }

Каждый раз, когда я запускаю этот код, я получаю сообщение об ошибке и не загружаю и не сохраняю строку в playerprefs.

Ответы [ 2 ]

0 голосов
/ 11 мая 2019

Здесь есть несколько проблем, и ваша ошибка нулевой ссылки является основным источником.

Я прокомментирую ваш код, чтобы показать вам, где вы идете не так, и предоставлю альтернативное решение.

// If possible it would be better to assign this object in the inspect rather then 
// using a GameObject.Find method, Also this is error prone due to the timing of 
// the call, for example if this is in a start this Object may not exist yet.
// Another solution would to be create an event and when you load the skin
// Have that event fire off that its been loaded and everything that needs
// to listen to it will get the change.
lesnek = GameObject.FindGameObjectsWithTag("LeWorm");

//  GetString has an alternative method where you can pass a default value
//  I would recommend using this method instead.
objName = PlayerPrefs.GetString("meshName");    // POINT A

// Honestly this check seems a tad bit redundant since you already
// attempted to load this preference.
// POINT B
if (PlayerPrefs.HasKey("meshName"))  // Since you have said this is empty playerPrefs is empty.
{
    // At this point it should equal this since you already set it to this in Point A
    if (objName == PlayerPrefs.GetString("meshName"))
    {
        leMesh = Resources.Load<GameObject>(@"Models\" + objName);
    }
    else
    {
        // This case should never get called, because of Point A and your if condition.
        objName = PlayerPrefs.GetString("meshName");
        leMesh = Resources.Load<GameObject>(@"Models\" + objName);
    }
}

if (objName != null || objName != "")  // This completely nullifies all the work in Point B
{
    objName = "Sphere";
    leMesh = Resources.Load<GameObject>(@"Models\" + objName);
}
foreach (GameObject change in lesnek)
{
    if (objName != null || objName != "")
    {
        if (change.GetComponent<MeshFilter>() == null)
        {
            change.AddComponent<MeshFilter>();
            change.GetComponent<MeshFilter>().mesh = leMesh.GetComponent<MeshFilter>().sharedMesh;
            PlayerPrefs.SetString("meshName", objName);
            PlayerPrefs.Save();
        }
        else
        {
            change.GetComponent<MeshFilter>().mesh = leMesh.GetComponent<MeshFilter>().sharedMesh;
            PlayerPrefs.SetString("meshName", objName);
            PlayerPrefs.Save();
        }
    }
}

Не вдаваясь в подробности и предполагая, что это в форме метода инициализации, а не начала, это изменения, которые я бы сделал

// This would be better as a class variable rather then a local variable
string meshName = PlayerPrefs.GetString("meshName", "Sphere");  
// Skipping point B because it is redundant
leMesh = Resources.Load<GameObject>(@"Models\" + meshName);  // Is this a GameObject or is it a Mesh???

MeshFilter leMeshFilter = leMesh.GetComponent<MeshFilter>();
if(leMeshFilter != null)
{
    foreach (GameObject change in lesnek)
    {
        MeshFilter meshFilter = change.GetComponent<MeshFilter>();
        if(meshFilter != null)
        {
            meshFilter.mesh = leMeshFilter.sharedMesh;
        }
        else
        {
            meshFilter = change.AddComponent<MeshFilter>();
            meshFilter.mesh = leMeshFilter.sharedMesh;
        }
    }
}

Единственное, что в этом примере не делается, это сохранить вашу PlayerPreference,Это то, что нужно делать только при смене скина.Поэтому, где бы вы ни делали это, сохраняйте предпочтения.

0 голосов
/ 11 мая 2019

Gameobject "leMesh" не найден.Первый шаг - убедиться, что он найден.Итак, давайте удостоверимся, что мы проинформированы о его состоянии, чтобы отладить это:

if (PlayerPrefs.HasKey("meshName"))
    {
        Debug.Log("PlayerPrefs does have the key we are looking for and it is " + PlayerPrefs.GetString("meshName"));

        /// This is redundant you just set objName to the string earlier
        /// objName = PlayerPrefs.GetString("meshName");
        if (objName == PlayerPrefs.GetString("meshName"))
        {
            leMesh = Resources.Load<GameObject>(@"Models\" + objName);
        }
        else
        {
            /// And here you do it again, constantly trying to get that string
            /// In order to find the object, of course if the string doesnt exist
            /// youll simply get an unassigned referenceException on this line:
            /// change.GetComponent<MeshFilter>().mesh = leMesh.GetComponent<MeshFilter>().sharedMesh
            objName = PlayerPrefs.GetString("meshName");
            leMesh = Resources.Load<GameObject>(@"Models\" + objName);
        }
    }

Теперь, если ваш консольный журнал сообщает вам, что meshName возвращает значение, то вы неправильно обращаетесь к ресурсам, и в этом случае вы пытаетесь удалить"@" из инфо "Моделей".В противном случае отсутствует строка playerPrefs с именем meshName.

ref

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...