দৃশ্যের মধ্যে ডেটা হ্যান্ডেল করার সঠিক উপায় কী?


52

আমি ইউনিটিতে আমার প্রথম 2 ডি গেমটি বিকাশ করছি এবং আমি কী গুরুত্বপূর্ণ প্রশ্ন বলে মনে করি তা পেরেছি।

আমি কীভাবে দৃশ্যের মধ্যে ডেটা পরিচালনা করব?

এর বিভিন্ন উত্তর বলে মনে হচ্ছে:

  • কেউ প্লেয়ারপ্রেস ব্যবহার করার কথা উল্লেখ করেছেন , অন্য লোকেরা আমাকে বলেছিল এটি অন্যান্য জিনিস যেমন পর্দার উজ্জ্বলতা সঞ্চয় করতে ব্যবহার করা উচিত।

  • কেউ আমাকে বলেছেন যে সর্বোত্তম উপায় হ'ল আমি দৃশ্যের পরিবর্তে যতবারই সেভগেমে সমস্ত কিছু লিখেছি এবং তা নিশ্চিত করা যে যখন নতুন দৃশ্যটি লোড হবে তখন সেভগেম থেকে আবার তথ্যটি পাওয়া যাবে। এটি আমার কাছে পারফরম্যান্সে অপ্রয়োজনীয় মনে হয়েছিল। আমি কি ভুল ছিলাম?

  • অন্য সমাধানটি, যা আমি এখনও অবধি প্রয়োগ করেছি এটি হ'ল একটি গ্লোবাল গেম অবজেক্ট যা দৃশ্যের মধ্যে ধ্বংস হয় না, দৃশ্যের মধ্যে সমস্ত ডেটা পরিচালনা করে। সুতরাং গেমটি শুরু হওয়ার সাথে সাথে আমি একটি স্টার্ট সিন লোড করি যেখানে এই বস্তুটি লোড হয় ed এটি শেষ হওয়ার পরে এটি প্রথম আসল গেমের দৃশ্যটি সাধারণত একটি প্রধান মেনু লোড করে।

এটি আমার বাস্তবায়ন:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class GameController : MonoBehaviour {

    // Make global
    public static GameController Instance {
        get;
        set;
    }

    void Awake () {
        DontDestroyOnLoad (transform.gameObject);
        Instance = this;
    }

    void Start() {
        //Load first game scene (probably main menu)
        Application.LoadLevel(2);
    }

    // Data persisted between scenes
    public int exp = 0;
    public int armor = 0;
    public int weapon = 0;
    //...
}

এই অবজেক্টটি আমার অন্যান্য ক্লাসে এভাবে পরিচালনা করা যেতে পারে:

private GameController gameController = GameController.Instance;

যদিও এটি এখন পর্যন্ত কাজ করেছে, এটি আমাকে একটি বড় সমস্যার মুখোমুখি করেছে: আমি যদি সরাসরি কোনও দৃশ্য লোড করতে চাই, তবে উদাহরণস্বরূপ গেমের চূড়ান্ত স্তরটি বলতে পারি, আমি এটি সরাসরি লোড করতে পারি না, যেহেতু সেই দৃশ্যে এটি থাকে না does বিশ্বব্যাপী খেলা বস্তু

আমি কি এই সমস্যাটি ভুলভাবে পরিচালনা করছি? এই জাতীয় চ্যালেঞ্জের জন্য আরও ভাল অনুশীলন আছে? আমি এই বিষয়ে আপনার মতামত, চিন্তাভাবনা এবং পরামর্শ শুনতে পছন্দ করি।

ধন্যবাদ

উত্তর:


64

এই অবস্থার পরিচালনার মৌলিক উপায়গুলি এই উত্তরে তালিকাভুক্ত। যদিও, এই পদ্ধতির বেশিরভাগটি বড় প্রকল্পগুলিতে ভাল স্কেল করে না। আপনি যদি আরও কিছু স্কেলযোগ্য কিছু করতে চান এবং আপনার হাত নোংরা হওয়ার ভয় না পান তবে নির্ভরতা ইঞ্জেকশন ফ্রেমওয়ার্কগুলি সম্পর্কে লেয়া হেইসের উত্তরটি দেখুন


1. শুধুমাত্র তথ্য রাখার জন্য একটি স্ট্যাটিক স্ক্রিপ্ট

আপনি কেবল ডেটা ধরে রাখতে একটি স্ট্যাটিক স্ক্রিপ্ট তৈরি করতে পারেন। যেহেতু এটি স্থিতিশীল, আপনার এটি গেমবজেক্টে অর্পণ করার দরকার নেই। আপনি সহজেই আপনার ডেটা অ্যাক্সেস করতে পারেন ScriptName.Variable = data;ইত্যাদি etc.

পেশাদাররা:

  • কোনও উদাহরণ বা সিঙ্গলটনের প্রয়োজন নেই।
  • আপনি আপনার প্রকল্পের যে কোনও জায়গা থেকে ডেটা অ্যাক্সেস করতে পারেন।
  • দৃশ্যের মধ্যে মানগুলি পাস করার জন্য কোনও অতিরিক্ত কোড নেই।
  • একক ডাটাবেসের মতো স্ক্রিপ্টের সমস্ত ভেরিয়েবল এবং ডেটা এগুলি হ্যান্ডেল করা সহজ করে।

কনস:

  • আপনি স্ট্যাটিক স্ক্রিপ্টের অভ্যন্তরে কোনও কর্টিন ব্যবহার করতে সক্ষম হবেন না।
  • আপনি ভালভাবে সংগঠিত না করলে আপনি সম্ভবত একক শ্রেণিতে বিশাল আকারের ভেরিয়েবলগুলি শেষ করবেন।
  • আপনি সম্পাদকের ভিতরে ক্ষেত্র / ভেরিয়েবল বরাদ্দ করতে পারবেন না।

একটি উদাহরণ:

public static class PlayerStats
{
    private static int kills, deaths, assists, points;

    public static int Kills 
    {
        get 
        {
            return kills;
        }
        set 
        {
            kills = value;
        }
    }

    public static int Deaths 
    {
        get 
        {
            return deaths;
        }
        set 
        {
            deaths = value;
        }
    }

    public static int Assists 
    {
        get 
        {
            return assists;
        }
        set 
        {
            assists = value;
        }
    }

    public static int Points 
    {
        get 
        {
            return points;
        }
        set 
        {
            points = value;
        }
    }
}

2. ডন্টডেস্ট্রয়অনলয়েড

যদি আপনার স্ক্রিপ্টটি কোনও গেমওজেক্টে অর্পণ করার প্রয়োজন হয় বা মনো-বিহেভিয়ার থেকে নেওয়া হয়েছে, তবে আপনি DontDestroyOnLoad(gameObject);নিজের ক্লাসে লাইন যুক্ত করতে পারেন যেখানে এটি একবার কার্যকর করা যেতে পারে ( এটিতে প্রবেশ করানো সাধারণত এটির Awake()জন্য যাওয়ার উপায়)

পেশাদাররা:

  • সমস্ত মনোবিহ্যাভোর কাজ (উদাহরণস্বরূপ Coroutines) নিরাপদে করা যেতে পারে।
  • আপনি সম্পাদকের ভিতরে ক্ষেত্র বরাদ্দ করতে পারেন।

কনস:

  • স্ক্রিপ্টের উপর নির্ভর করে আপনার সম্ভবত আপনার দৃশ্যটি সামঞ্জস্য করতে হবে।
  • আপডেট বা অন্যান্য সাধারণ ক্রিয়াকলাপ / পদ্ধতিতে কী করবেন তা নির্ধারণ করার জন্য আপনার সম্ভবত কোনও দৃশ্য লোড হয়েছে কিনা তা খতিয়ে দেখতে হবে। উদাহরণস্বরূপ, আপনি আপডেট () তে ইউআইয়ের সাথে কিছু করছেন, তবে আপনাকে কাজটি করার জন্য সঠিক দৃশ্যের লোড করা হয়েছে কিনা তা খতিয়ে দেখা উচিত। এটি if-অন্যথায় বা স্যুইচ-কেস চেকগুলির বোঝা সৃষ্টি করে।

3. প্লেয়ারপ্রিফস

গেমটি বন্ধ হয়ে গেলেও আপনি যদি আপনার ডেটা সংরক্ষণ করতে চান তবে আপনি এটি বাস্তবায়ন করতে পারেন।

পেশাদাররা:

  • ইউনিটি সমস্ত পটভূমি প্রক্রিয়া পরিচালনা করার পর থেকে পরিচালনা করা সহজ।
  • আপনি কেবল দৃশ্যের মধ্যেই নয়, উদাহরণগুলির মধ্যেও (গেম সেশন) ডেটা পাস করতে পারেন।

কনস:

  • ফাইল সিস্টেম ব্যবহার করে।
  • প্রিফেস ফাইল থেকে ডেটা সহজেই পরিবর্তন করা যায়।

4. একটি ফাইল সংরক্ষণ করা

দৃশ্যের মধ্যে মানগুলি সংরক্ষণ করার জন্য এটি কিছুটা ওভারকিল। আপনার যদি এনক্রিপশনের প্রয়োজন না হয় তবে আমি আপনাকে এই পদ্ধতি থেকে নিরুৎসাহিত করব।

পেশাদাররা:

  • প্লেয়ারপ্রিফগুলির বিপরীতে আপনি সংরক্ষণ করা ডেটা নিয়ন্ত্রণে রয়েছেন।
  • আপনি কেবল দৃশ্যের মধ্যেই নয়, উদাহরণগুলির মধ্যেও (গেম সেশন) ডেটা পাস করতে পারেন।
  • আপনি ফাইলটি স্থানান্তর করতে পারেন (ব্যবহারকারী-উত্পাদিত সামগ্রী ধারণা এটির উপর নির্ভর করে)।

কনস:

  • স্লো।
  • ফাইল সিস্টেম ব্যবহার করে।
  • সংরক্ষণের সময় স্ট্রিম বিঘ্নিত হয়ে পড়ার / লোড দ্বন্দ্বগুলি পড়ার সম্ভাবনা।
  • আপনি কোনও এনক্রিপশন (যা কোডটি আরও ধীরে ধীরে করে দেবে) প্রয়োগ না করা হলে ফাইল থেকে ডেটা সহজেই পরিবর্তন করা যায়)

5. একক প্যাটার্ন

সিঙ্গেলটন প্যাটার্ন হ'ল অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ে একটি সত্যই গরম বিষয়। কিছু এটি প্রস্তাব দেয়, এবং কিছু না। এটি নিজেই গবেষণা করুন এবং আপনার প্রকল্পের অবস্থার উপর নির্ভর করে উপযুক্ত কল করুন।

পেশাদাররা:

  • সেট আপ এবং ব্যবহার উভয়ই সহজ।
  • আপনি আপনার প্রকল্পের যে কোনও জায়গা থেকে ডেটা অ্যাক্সেস করতে পারেন।
  • একক ডাটাবেসের মতো স্ক্রিপ্টের সমস্ত ভেরিয়েবল এবং ডেটা এগুলি হ্যান্ডেল করা সহজ করে।

কনস:

  • প্রচুর বয়লারপ্লেট কোড যার একমাত্র কাজ সিঙ্গলটন উদাহরণটি বজায় রাখা এবং সুরক্ষিত করা।
  • আছে Singleton প্যাটার্ন ব্যবহারের বিরুদ্ধে শক্তিশালী আর্গুমেন্ট । সতর্কতা অবলম্বন করুন এবং আগেই আপনার গবেষণা করুন।
  • দুর্বল প্রয়োগের কারণে ডেটা সংঘর্ষের সম্ভাবনা।
  • ইউনিটি একটি অসুবিধা Singleton নিদর্শন হ্যান্ডলিং থাকতে পারে 1

1 : এর সংক্ষেপে বলা OnDestroyপদ্ধতি একক স্ক্রিপ্ট সমন্বয়সাধন করা উইকি সরবরাহ করা , আপনি লেখক বর্ণনা দেখতে পারেন প্রেতাত্মা বস্তু যা রানটাইম থেকে এডিটর মধ্যে রক্ত ঝরা:

যখন ইউনিটি প্রস্থান করে, এটি এলোমেলো ক্রমে বস্তুগুলি ধ্বংস করে। নীতিগতভাবে, অ্যাপ্লিকেশনটি প্রস্থান করার সময় কেবলমাত্র একটি সিঙ্গলটন ধ্বংস হয়। যদি কোনও স্ক্রিপ্ট ইন্সট্যান্সটিকে ধ্বংস হওয়ার পরে কল করে তবে এটি একটি বাগি ভূত অবজেক্ট তৈরি করবে যা অ্যাপ্লিকেশনটি বন্ধ করে দেওয়ার পরেও সম্পাদক দৃশ্যে থাকবে। সত্যিই খারাপ! সুতরাং, এটি নিশ্চিত করার জন্য তৈরি করা হয়েছিল যে আমরা সেই বগি ভূত অবজেক্টটি তৈরি করছি না।


8

কিছুটা আরও উন্নত বিকল্পটি জেনজেক্টের মতো কাঠামোর সাথে নির্ভরতা ইনজেকশন সম্পাদন করা ।

এটি আপনাকে আপনার অ্যাপ্লিকেশনটি কাঠামো মুক্ত রাখতে দেয় তবে আপনি চান; এই ক্ষেত্রে,

public class PlayerProfile
{
    public string Nick { get; set; }
    public int WinCount { get; set; }
}

তারপরে আপনি টাইপটি আইওসি (নিয়ন্ত্রণের বিপরীতমুখী) ধারকটিতে আবদ্ধ করতে পারেন। জেনজেক্টের সাথে এই ক্রিয়াটি একটি MonoInstallerবা একটি এর মধ্যে সম্পাদিত হয় ScriptableInstaller:

public class GameInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        this.Container.Bind<PlayerProfile>()
            .ToSelf()
            .AsSingle();
    }
}

এর সিঙ্গলটন উদাহরণটি PlayerProfileতখন অন্য ক্লাসগুলিতে ইনজেকশন করা হয় যা জেনজেটের মাধ্যমে ইনস্ট্যান্ট হয়। আদর্শভাবে কনস্ট্রাক্টর ইনজেকশনের মাধ্যমে তবে সম্পত্তি এবং ক্ষেত্রের ইনজেকশনগুলি জেনজেক্টের Injectবৈশিষ্ট্য সহ এগুলি জানিয়েও সম্ভব ।

পরবর্তী বৈশিষ্ট্য কৌশলটি আপনার দৃশ্যের গেম অবজেক্টগুলি স্বয়ংক্রিয়ভাবে ইনজেক্ট করতে ব্যবহৃত হয় যেহেতু ityক্য এই বিষয়গুলি আপনার জন্য ইনস্ট্যান্ট করে:

public class WinDetector : MonoBehaviour
{
    [Inject]
    private PlayerProfile playerProfile = null;


    private void OnCollisionEnter(Collision collision)
    {
        this.playerProfile.WinCount += 1;
        // other stuff...
    }
}

যে কোনও কারণে আপনি প্রয়োগের ধরণের পরিবর্তে ইন্টারফেসের মাধ্যমে কোনও প্রয়োগকে বাঁধতে চাইতে পারেন। (অস্বীকৃতি, নিম্নলিখিতটি একটি আশ্চর্যজনক উদাহরণ হিসাবে অনুমিত হয় না; আমি সন্দেহ করি আপনি এই নির্দিষ্ট স্থানে সংরক্ষণ / লোড পদ্ধতিগুলি চাইবেন ... তবে এটি বাস্তবায়নে আচরণে কীভাবে পরিবর্তিত হতে পারে তার একটি উদাহরণ দেখায়)।

public interface IPlayerProfile
{
    string Nick { get; set; }
    int WinCount { get; set; }

    void Save();
    void Load();
}

[JsonObject]
public class PlayerProfile_Json : IPlayerProfile
{
    [JsonProperty]
    public string Nick { get; set; }
    [JsonProperty]
    public int WinCount { get; set; }


    public void Save()
    {
        ...
    }

    public void Load()
    {
        ...
    }
}

[ProtoContract]
public class PlayerProfile_Protobuf : IPlayerProfile
{
    [ProtoMember(1)]
    public string Nick { get; set; }
    [ProtoMember(2)]
    public int WinCount { get; set; }


    public void Save()
    {
        ...
    }

    public void Load()
    {
        ...
    }
}

যা পূর্বের মতো একইভাবে IoC ধারকটির সাথে আবদ্ধ হতে পারে:

public class GameInstaller : MonoInstaller
{
    // The following field can be adjusted using the inspector of the
    // installer component (in this case) or asset (in the case of using
    // a ScriptableInstaller).
    [SerializeField]
    private PlayerProfileFormat playerProfileFormat = PlayerProfileFormat.Json;


    public override void InstallBindings()
    {
        switch (playerProfileFormat) {
            case PlayerProfileFormat.Json:
                this.Container.Bind<IPlayerProfile>()
                    .To<PlayerProfile_Json>()
                    .AsSingle();
                break;

            case PlayerProfileFormat.Protobuf:
                this.Container.Bind<IPlayerProfile>()
                    .To<PlayerProfile_Protobuf>()
                    .AsSingle();
                break;

            default:
                throw new InvalidOperationException("Unexpected player profile format.");
        }
    }


    public enum PlayerProfileFormat
    {
        Json,
        Protobuf,
    }
}

3

আপনি জিনিসগুলি একটি ভাল উপায়ে করছেন। এটি আমি এটিই করি এবং স্পষ্টতই অনেকে যেভাবে এটি করেন কারণ এই অটোলিয়াডার স্ক্রিপ্ট (আপনি যখন প্লেতে যাবেন তখনই স্বয়ংক্রিয়ভাবে লোড করার জন্য একটি দৃশ্য সেট করতে পারেন) উপস্থিত রয়েছে: http://wiki.une3d.com/index.php/ SceneAutoLoader

প্রথম দুটি বিকল্প উভয়ই আপনার গেমটি সেশনের মধ্যে গেমটি সংরক্ষণের জন্য প্রয়োজন হতে পারে তবে এটি এই সমস্যার জন্য ভুল সরঞ্জাম।


আপনার পোস্ট করা লিঙ্কটি আমি কেবলমাত্র পড়েছি। দেখে মনে হচ্ছে এমন কোনও উপায় আছে যেখানে আমি গ্লোবাল গেম অবজেক্টটি লোড করছি, এমন ইনসিকিয়াল দৃশ্যের অটোলোড করার উপায় আছে। এটি কিছুটা জটিল দেখায় তাই আমার সমস্যাটি সমাধান করার মতো কিছু কিনা তা সিদ্ধান্ত নিতে আমার কিছুটা সময় প্রয়োজন need আপনার প্রতিক্রিয়ার জন্য ধন্যবাদ!
এনরিক মোরেনো তাঁবু

আমি যে স্ক্রিপ্টটি বাছাই করেছিলাম তা সেই সমস্যার সমাধান করে, আপনি প্রতিবার স্টার্টআপ দৃশ্যে পাল্টে যাওয়ার চেয়ে মনে রাখার চেয়ে যে কোনও দৃশ্যে নাটকটি হিট করতে পারেন। এটি এখনও শেষ পর্যায়ে সরাসরি শুরু করার চেয়ে বরং শুরু থেকেই গেমটি শুরু করে; আপনাকে যে কোনও স্তরে এড়াতে বা গেমের স্তরটি পাস করার জন্য অটোলোড স্ক্রিপ্টটি সংশোধন করার জন্য আপনি প্রতারণা করতে পারেন।
0

হ্যাঁ, ভাল। আরম্ভের দৃশ্যে স্যুইচ করতে মনে রাখার মতো ঝামেলাটি তেমন "বিরক্তি" ছিল না, যতটা নির্দিষ্ট পর্যায়ে মাথায় রাখতে লোকেটিকে হ্যাক করতে হয়েছিল। যাই হোক ধন্যবাদ!
এনরিক মোরেনো তাঁবুটি

1

দৃশ্যের মধ্যে ভেরিয়েবলগুলি সংরক্ষণ করার একটি আদর্শ উপায় হ'ল সিঙ্গলটন ম্যানেজার শ্রেণির মাধ্যমে। অবিরাম ডেটা সঞ্চয় করার জন্য একটি শ্রেণি তৈরি করে এবং সেই শ্রেণিটি সেট করেDoNotDestroyOnLoad() , আপনি নিশ্চিত করতে পারেন যে এটি অবিলম্বে অ্যাক্সেসযোগ্য এবং দৃশ্যের মধ্যে স্থির থাকে।

আপনার কাছে অন্য একটি বিকল্প রয়েছে PlayerPrefsক্লাসটি ব্যবহার করা । PlayerPrefsআপনাকে প্লে সেশনের মধ্যে ডেটা সংরক্ষণ করার অনুমতি দেওয়ার জন্য ডিজাইন করা হয়েছে , তবে এটি এখনও দৃশ্যের মধ্যে ডেটা সংরক্ষণের মাধ্যম হিসাবে কাজ করবে

একটি সিঙ্গলটন ক্লাস এবং ব্যবহার করে DoNotDestroyOnLoad()

নিম্নলিখিত স্ক্রিপ্টটি একটি অবিরাম সিঙ্গলটন ক্লাস তৈরি করে। একটি সিঙ্গলটন ক্লাস এমন একটি বর্গ যা একই সময়ে কেবলমাত্র একটি একক দৌড়ানোর জন্য নকশাকৃত। এই জাতীয় কার্যকারিতা সরবরাহ করে, আমরা ক্লাসটি যে কোনও জায়গা থেকে অ্যাক্সেস করতে নিরাপদে একটি স্থিতিশীল স্ব-রেফারেন্স তৈরি করতে পারি। এর অর্থ আপনি শ্রেণীর DataManager.instanceঅভ্যন্তরে যে কোনও পাবলিক ভেরিয়েবলগুলি সহ সরাসরি ক্লাসে প্রবেশ করতে পারবেন ।

using UnityEngine;

/// <summary>Manages data for persistance between levels.</summary>
public class DataManager : MonoBehaviour 
{
    /// <summary>Static reference to the instance of our DataManager</summary>
    public static DataManager instance;

    /// <summary>The player's current score.</summary>
    public int score;
    /// <summary>The player's remaining health.</summary>
    public int health;
    /// <summary>The player's remaining lives.</summary>
    public int lives;

    /// <summary>Awake is called when the script instance is being loaded.</summary>
    void Awake()
    {
        // If the instance reference has not been set, yet, 
        if (instance == null)
        {
            // Set this instance as the instance reference.
            instance = this;
        }
        else if(instance != this)
        {
            // If the instance reference has already been set, and this is not the
            // the instance reference, destroy this game object.
            Destroy(gameObject);
        }

        // Do not destroy this object, when we load a new scene.
        DontDestroyOnLoad(gameObject);
    }
}

আপনি নীচে সিঙ্গেলটন কর্মে দেখতে পাচ্ছেন। মনে রাখবেন যে আমি প্রথম দৃশ্যটি চালানোর সাথে সাথে ডেটা ম্যানেজার অবজেক্টটি দৃশ্য-নির্দিষ্ট শিরোনাম থেকে ক্রমবর্ধমান ভিউতে "DontDestroyOnLoad" শিরোনামে চলে আসে।

একাধিক দৃশ্যের লোড হচ্ছে এমন স্ক্রিন রেকর্ডিং, যখন ডেটা ম্যানেজারটি "DoNotDestroyOnLoad" শিরোনামের অধীনে থেকে যায়।

PlayerPrefsক্লাস ব্যবহার করে

কল করা মৌলিক অবিরাম ডেটা পরিচালনা করার জন্য ইউনিটির একটি বিল্ট ইন ক্লাস রয়েছেPlayerPrefsPlayerPrefsফাইলটিতে প্রতিশ্রুতিবদ্ধ কোনও ডেটা গেম সেশনে জুড়ে থাকবে , তাই স্বাভাবিকভাবেই, এটি দৃশ্যগুলিতে ডেটা ধরে রাখতে সক্ষম।

PlayerPrefsফাইল ধরনের ভেরিয়েবল সংরক্ষণ করতে পারেন string, intএবং float। আমরা যখন PlayerPrefsফাইলে মান সন্নিবেশ করি তখন আমরা stringকী হিসাবে একটি অতিরিক্ত সরবরাহ করি । আমরা পরে PlayerPrefফাইল থেকে আমাদের মানগুলি পুনরুদ্ধার করতে একই কী ব্যবহার করি ।

using UnityEngine;

/// <summary>Manages data for persistance between play sessions.</summary>
public class SaveManager : MonoBehaviour 
{
    /// <summary>The player's name.</summary>
    public string playerName = "";
    /// <summary>The player's score.</summary>
    public int playerScore = 0;
    /// <summary>The player's health value.</summary>
    public float playerHealth = 0f;

    /// <summary>Static record of the key for saving and loading playerName.</summary>
    private static string playerNameKey = "PLAYER_NAME";
    /// <summary>Static record of the key for saving and loading playerScore.</summary>
    private static string playerScoreKey = "PLAYER_SCORE";
    /// <summary>Static record of the key for saving and loading playerHealth.</summary>
    private static string playerHealthKey = "PLAYER_HEALTH";

    /// <summary>Saves playerName, playerScore and 
    /// playerHealth to the PlayerPrefs file.</summary>
    public void Save()
    {
        // Set the values to the PlayerPrefs file using their corresponding keys.
        PlayerPrefs.SetString(playerNameKey, playerName);
        PlayerPrefs.SetInt(playerScoreKey, playerScore);
        PlayerPrefs.SetFloat(playerHealthKey, playerHealth);

        // Manually save the PlayerPrefs file to disk, in case we experience a crash
        PlayerPrefs.Save();
    }

    /// <summary>Saves playerName, playerScore and playerHealth 
    // from the PlayerPrefs file.</summary>
    public void Load()
    {
        // If the PlayerPrefs file currently has a value registered to the playerNameKey, 
        if (PlayerPrefs.HasKey(playerNameKey))
        {
            // load playerName from the PlayerPrefs file.
            playerName = PlayerPrefs.GetString(playerNameKey);
        }

        // If the PlayerPrefs file currently has a value registered to the playerScoreKey, 
        if (PlayerPrefs.HasKey(playerScoreKey))
        {
            // load playerScore from the PlayerPrefs file.
            playerScore = PlayerPrefs.GetInt(playerScoreKey);
        }

        // If the PlayerPrefs file currently has a value registered to the playerHealthKey,
        if (PlayerPrefs.HasKey(playerHealthKey))
        {
            // load playerHealth from the PlayerPrefs file.
            playerHealth = PlayerPrefs.GetFloat(playerHealthKey);
        }
    }

    /// <summary>Deletes all values from the PlayerPrefs file.</summary>
    public void Delete()
    {
        // Delete all values from the PlayerPrefs file.
        PlayerPrefs.DeleteAll();
    }
}

নোট করুন যে PlayerPrefsফাইলটি পরিচালনা করার সময় আমি অতিরিক্ত সতর্কতা অবলম্বন করি :

  • আমি প্রতিটি কী এক হিসাবে সংরক্ষণ করেছি private static string। এটি আমাকে গ্যারান্টি দেওয়ার অনুমতি দেয় আমি সর্বদা সঠিক কীটি ব্যবহার করছি এবং এর অর্থ হ'ল যদি আমাকে কোনও কারণে কীটি পরিবর্তন করতে হয় তবে আমার এটির সমস্ত উল্লেখ পরিবর্তন করার বিষয়টি নিশ্চিত করার দরকার নেই।
  • আমি PlayerPrefsফাইলটি ডিস্কে লেখার পরে সেভ করি। আপনি যদি প্লে সেশন জুড়ে ডেটা অধ্যবসায় বাস্তবায়ন না করেন তবে এটি সম্ভবত কোনও তাত্পর্য তৈরি করবে না। একটি সাধারণ অ্যাপ্লিকেশন বন্ধ হওয়ার সময় ডিস্কে সংরক্ষণ PlayerPrefs করবে , তবে আপনার গেমটি ক্র্যাশ হয়ে গেলে এটি স্বাভাবিকভাবে কল করতে পারে না।
  • আমি আসলে পরীক্ষা প্রতিটি চাবি বিদ্যমান মধ্যে PlayerPrefs, আগে আমি এর সাথে জড়িত একটি মান পুনরুদ্ধার করতে চেষ্টা করে। এটি অর্থহীন ডাবল-চেকিংয়ের মতো মনে হতে পারে তবে এটি হওয়া ভাল অনুশীলন।
  • আমার একটি Deleteপদ্ধতি রয়েছে যা তত্ক্ষণাত্ PlayerPrefsফাইলটি মুছে দেয় । আপনি যদি প্লে সেশন জুড়ে ডেটা অধ্যবসায় অন্তর্ভুক্ত না করতে চান, আপনি এই পদ্ধতিটি কল করার বিষয়ে বিবেচনা করতে পারেন Awake। ক্লিয়ারিং দ্বারা PlayerPrefsপ্রতিটি গেম শুরুতে ফাইল, আপনি নিশ্চিত করুন যে এমন যে কোনো ডেটা হয়নি পূর্ববর্তী সেশন থেকে জিদ ভুল করে থেকে তথ্য যেমন ঘাঁটা নয় বর্তমান সেশন।

আপনি PlayerPrefsনীচে, ক্রিয়ায় দেখতে পারেন । মনে রাখবেন যে আমি যখন "ডেটা সংরক্ষণ করুন" ক্লিক করি তখন আমি সরাসরি Saveপদ্ধতিটি কল করি এবং আমি যখন "লোড ডেটা" ক্লিক করি তখন আমি সরাসরি Loadপদ্ধতিটিতে কল করছি । আপনার নিজস্ব বাস্তবায়ন সম্ভবত পৃথক হবে, তবে এটি বেসিকগুলি দেখায়।

সেভ () এবং লোড () ফাংশনগুলির মাধ্যমে পরিদর্শকের কাছ থেকে ওভাররাইট করা স্থির থাকা ডেটার স্ক্রিন রেকর্ডিং।


একটি চূড়ান্ত নোট হিসাবে, আমি নির্দেশ করতে হবে যে আপনি PlayerPrefsআরও দরকারী ধরণের সঞ্চয় করতে, বেসিক উপর প্রসারিত করতে পারেন । JPTheK9 একটি অনুরূপ প্রশ্নের উত্তরের উত্তর সরবরাহ করে , যাতে তারা একটি PlayerPrefsফাইলের মধ্যে সংরক্ষণের জন্য স্ট্রিং ফর্মে অ্যারে সিরিয়াল দেওয়ার জন্য একটি স্ক্রিপ্ট সরবরাহ করে । তারা আমাদের ইউনিফাইড সম্প্রদায় উইকির দিকেও ইঙ্গিত করে , যেখানে একজন ব্যবহারকারীPlayerPrefsX আরও বিভিন্ন ধরণের যেমন ভেক্টর এবং অ্যারে সমর্থন করার জন্য আরও বিস্তৃত স্ক্রিপ্ট আপলোড করেছেন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.