Запоминание покупок игрока

124
28 марта 2021, 08:00

Хочу узнать как я могу "запоминать" покупки игрока.
Есть магазин в котором игрок должен покупать скины(сама покупка уже реализована).

//Скрипт сильно упростил ,но логика та же.

public int Money

public void ChangeSkin(int Skins)
{
    switch (Skins)
        {         
            case 1:
             if (Money >= 10)
             {
               Логика покупки
             }
             break;
    case 2:
             if (Money >= 10)
             {
               Логика покупки
             }
             break;
    case 3:
             if (Money >= 10)
             {
               Логика покупки
             }
             break;
    case 4:
             if (Money >= 10)
             {
               Логика покупки
             }
             break;
        }
}

Как я могу после покупки "запоминать", что игрок уже это купил?
После запуска игры в Start() я уже должен знать все купленные предметы для изменения на них иконок.

Answer 1

Для сохранения значений, в том числе и между заходами в игру, в Unity3D есть такой класс как PlayerPrefs. Он позволяет сохранять значения (int, string, float), просматривать их, удалять и перезаписывать.

В логике покупки вы можете написать следующее (имя ключа - название под которым вы сохранили/сохраните значение покупки - 1 или непокупки - 0 конкретного предмета/скина):

//code...
case 1:
     if (Money >= Цена)
     {
         if (PlayerPrefs.HasKey(имя ключа)) // существует ли эта переменная
         {
             if (PlayerPrefs.GetInt(имя ключа) == 0) // не куплено
             {
                 /*покупка*/
                 Money -= skin.Price;
                 GetComponent<SpriteRenderer>().sprite = Sprite1;
                 PlayerPrefs.SetInt(имя ключа, 1); // куплен
             }
             else { /*сообщение о том что предмет уже куплен*/ }
         }
         else
         {
             /*покупка*/
             Money -= skin.Price;
             GetComponent<SpriteRenderer>().sprite = Sprite1;
             PlayerPrefs.SetInt(имя ключа, 1); // куплен
         }
     }
break;
//code...

Также я советую вам сделать отдельный класс Skin. Его приблизительный код:

[System.Serializable]
public class Skin : MonoBehaviour
{
    public readonly string Name; // задать в редакторе либо вне класса [УНИКАЛЬНОЕ ДЛЯ КАЖДОГО СКИНА]
    public int Price;            // задать в редакторе либо вне класса
    public Sprite SkinSprite;    // задать в редакторе либо вне класса
    public bool WasBuy
    {
        get
        {             
            if (PlayerPrefs.HasKey(Name + "_wasbuy")) // существует ли эта переменная            
                return PlayerPrefs.GetInt(Name + "_wasbuy");
            else
            {
                PlayerPrefs.SetInt(Name + "_wasbuy", 0);
                return false;
            }
        }
        set
        {
            PlayerPrefs.SetInt(Name + "_wasbuy", Convert.ToInt32(value));
        }
    }
}

И тогда метод ChangeSkin будет иметь следующий вид:

// using System.Linq
void ChangeSkin(string Name, Skin[] allSkins) // allSkins - все скины для данного предмета
{
    try
    {
        var skin = allSkins.First((skin) => skin.Name == Name);
        if (skin.WasBuy)
            GetComponent<SpriteRenderer>().sprite = skin.SkinSprite;
        else if (Money >= skin.Price)
        {
            Money -= skin.Price;
            skin.WasBuy = true;
            GetComponent<SpriteRenderer>().sprite = skin.SkinSprite;
        }
        else
            // нехватает денег
    }
    catch(System.Exception)
    {
        // скин не существует
    }
}
Answer 2

Попробуй хранить файл с покупками.Можно даже количество туда добавить.Пример: Класс который будет сохраняться:

[System.Serializable]
public class ShopData
{ 
public int ID;
public int Count;
}

К примеру,потом с помощью классов JsonUtility считывай обратно в файл и записывай в него.И всегда сможешь знать,кто что купил.

Answer 3

Лично мне решение KuzCode не понравилось.

Причина проста: можно игрушку хакать тупо через блокнот. Если это не играет роли - то плевать и можно использовать и его подход. Но т.к. ответ, все таки, решает вопрос, то минуса он не заслуживает :)

Если же важно что бы покупки невозможно(окей, менее легко) было хакнуть - нужно использовать запрос на сервер который будет подтверждать что этот вот чувак купил вот эту вот покупку. Можно через простой http реквест и информация которая кодировалась бы под неким ключем, но передавалась, например, чрез JSON.

Делать запрос на старте программы. И тогда уже обновлять данные локально.

Но, подозреваю, что возможно это же есть в каких-то апи магазинов. Вроде эплстора или же плеймаркета. Сам я с таким не сталкивался и не работал, но в документации поискал бы информацию про это однозначно. Как минимум с него можно тягнуть информацию о юзере. Какой-то айдишник. Что бы привязывать конкретного юзера к игре, а не девайс.

READ ALSO
Ошибка при выводе роли

Ошибка при выводе роли

В проекте используется стандартная аутентификация Individual User AccountsДобавил программно роль:

126
Работа со сборщиком мусора в c# [дубликат]

Работа со сборщиком мусора в c# [дубликат]

Хотелось бы узнать некоторые нюансы работы со сборщиком мусора:

119
Unity3d. Ошибка: Object reference not set to an instance of an object

Unity3d. Ошибка: Object reference not set to an instance of an object

Есть карта, сгенерированная из перфаба(2д текстура), при создании поочередно дается название ( 1, 2

118
Тайм-аут подключения к контейнеру с mysql из go

Тайм-аут подключения к контейнеру с mysql из go

Установил Docker Desktop for MacOSЗапустил контейнер с mysql:docker run --name mysqlserver -e MYSQL_ROOT_PASSWORD=pass -d mysql:latest

131