টাইম.টাইম যখন ইউনিটিতে খুব বড় হয়ে যায় তখন কী ঘটে?


37

যেমনটি এখানে বলা হয়েছে :

Time.time

এই ফ্রেমের শুরুতে সময় (কেবল পঠনযোগ্য)। খেলা শুরু হওয়ার পর থেকে এটি সেকেন্ডের সময়।

এবং আমি জানি সময়টি ভাসা ভাসমান মধ্যে সংরক্ষণ করা হয়। সুতরাং, আমার প্রশ্ন হ'ল সময়ের মূল্য খুব বড় হয়ে গেলে কী হবে? এটা কি উপচে পড়তে পারে? এটি কি নির্ভুলতা হারাবে এবং বাগগুলি সৃষ্টি করবে? গেমটি কি শুধু ক্রাশ হবে নাকি?



5
@ আলেকজান্দ্রেভেল্যানকোর্ট আমাকে মনে হয় যে এখানে একটি কার্যকর প্রশ্ন রয়েছে যদি আমরা এটির ব্যাখ্যা করি "টাইম.টাইম খুব বড় হয়ে যায় তখন কি সমস্যা আছে?" আক্ষরিকভাবে "ওভারফ্লো" তে মনোনিবেশ করার বিপরীতে। আপনার প্রতিক্রিয়া জানানোর চেষ্টা করার জন্য আমি এই লাইনগুলি দিয়ে প্রশ্নটি সম্পাদনা করেছি।
ডিএমগ্রিগরি

2
@ ডিএমজি গ্রেগরি তবে প্রশ্নের উত্তর দেওয়া হয়েছে এবং ইতিমধ্যে গৃহীত হয়েছে ... আমি আপনার সম্পাদনাগুলি আরও কার্যকর প্রশ্নের জন্য তৈরি করতে সম্মত হলাম, কিছুটা দেরী।
মাইকেলহাউস

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

উত্তর:


62

একক-নির্ভুলতা ফ্লোট ব্যবহার করে সময় যথার্থতা হারাতে আসল ঝুঁকি রয়েছে

এটি এখনও 97 দিনের জন্য নিকটবর্তী দ্বিতীয়টিতে যথার্থতা বজায় রাখবে । তবে গেমগুলিতে আমরা প্রায়শই ফ্রেমের সময়কাল অনুসারে নির্ভুলতার বিষয়ে যত্নশীল।

সেকেন্ডে একটি একক-নির্ভুলতা ভাসমান সময়ের মান প্রায় 9 ঘন্টা পরে মিলিসেকেন্ড যথার্থতা হারাতে শুরু করে ।

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

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

ধরে নিচ্ছেন ityক্যটি deltaTimeউচ্চতর নির্ভুল সময়ের উত্স থেকে গণনা করা হয়েছে, যা পিটারের গবেষণাগুলি অন্য উত্তরে বহন করেছে, deltaTimeফ্রেম-স্কেল সময়গুলির জন্য নির্ভর করা তুলনামূলকভাবে নিরাপদ ( deltaTimeমানগুলি সংক্ষিপ্ত করে খুব দীর্ঘ মেয়াদী সঞ্চার সম্পর্কে সতর্ক থাকুন - এতে ছোট বর্ধন যোগ করা হয় বৃহত ফ্লোট হ'ল নির্ভুল ক্ষতির জন্য একটি সর্বোত্তম রেসিপি, এমনকি আপনি যখন বুদ্ধিমান অ্যালগরিদমের সাথে ক্ষতিপূরণ করেন )।

যেহেতু fixedDeltaTimeআপনি গতিরূপে ফ্রেম থেকে ফ্রেমে পরিবর্তনের পরিবর্তে স্থিতিযুক্ত সংবেদনশীল আচরণটি স্থিতিশীলতার শক্তিশালী গ্যারান্টি পেতে স্থির-সংবেদনশীল আচরণটি স্থির রাখতে পারবেন Since deltaTimeএই পদ্ধতিগুলিতে স্বয়ংক্রিয়ভাবে উপযুক্ত স্থির বদ্বীপ ফিরিয়ে আনবে। স্থির ও ফ্রেম আপডেটের মধ্যে একটি বীট ফ্রিকোয়েন্সি থাকতে পারে, তবে আপনি এটিকে ইন্টারপোলেশনের মাধ্যমে মসৃণ করতে পারেন

আপনি যা এড়াতে চান তা হ'ল একটি সময় থেকে অন্য টাইমস্ট্যাম্প বিয়োগ করে সময়সীকরণগুলি গণনা করা । কয়েক ঘন্টা খেলার পরে এটি বিপর্যয়কর বাতিল হতে পারে, যার ফলে আপনি রান শুরু করার চেয়ে অনেক কম নির্ভুলতার দিকে নিয়ে যান। তাহলে টাইমস্ট্যাম্প তুলনা সিস্টেমের জন্য গুরুত্বপূর্ণ, আপনার মত অন্যান্য পদ্ধতি ব্যবহার করে, আপনার নিজের উচ্চতর রিসোলিউশনের সময় মান তৈরি করতে পারেন System.Diagnostics.Stopwatchপরিবর্তে Time.time


অবাস্তাল কোড এবং ব্লুপ্রিন্ট উভয় ক্ষেত্রেই একক নির্ভুলতা ভাসমান হিসাবে গেমের সময়কে প্রকাশ করতে পছন্দ করে । আপনি রিয়েলটাইমের টাইমস্ট্যাম্পগুলির সাথে এটিকে ঘিরে কাজ করতে পারেন এবং timeক্যতে যেমন করেছেন ঠিক তেমন নিজস্ব সময়সীমাগুলিও করতে পারেন। (কেবল অবলোকন করুন অবাস্তবের টাইমস্ট্যাম্পের ধরণটি 32-বিট যুগের উপর ভিত্তি করে )। আপনি যদি এটি পছন্দ করেন তবে অবাস্তব ক্ষেত্রে সি # এর জন্য এক্সটেনশনগুলির উপস্থিতি রয়েছে।
ডিএমগ্রিগরি

[এমএস] এর জন্য, আপনি 16 484 - 32 768 ব্যান্ডের কাছাকাছি নির্ভুলতা হারাতে শুরু করেন। এটি হল আপনি 4 ঘন্টা 30 মিনিটের পরে নির্ভুলতা শিথিল করতে পারেন , 9 ঘন্টা পরে আপনি অবশ্যই এটি বিশ্বাস করতে পারবেন না।
xmedeko

প্রযুক্তিগতভাবে 4.5-9 ঘন্টা এর মধ্যে আপনার 0.98 মিলি সেকেন্ডের মধ্যে যথাযথতা রয়েছে - আমি সেই বিন্দুটিকে ফ্ল্যাগ করতে পছন্দ করেছি যেখানে ত্রুটিটি 1.00 মিলিসেকেন্ডের বেশি হয়ে গেছে। তবে বিষয়টি ভালভাবে নেওয়া হয়েছে - যথার্থতা সমস্ত পথেই হ্রাস পায়, সুতরাং আরও সংক্ষিপ্ততার প্রয়োজনের কোডটি এর আগেও দুর্ব্যবহার শুরু করতে পারে।
ডিএমগ্রিগরি

16

ভাসনের সর্বাধিক মান হ'ল 3.40282347 * 10 ^ 38, যা সেকেন্ডে পরিমাপ করা হলে 10 বা 31 বছর সমান হয় (বা 10 মিলি-সেকেন্ডে যখন পরিমাপ করা হয় তখন 10 ^ 28 বছর)। বিশ্বাস করুন, এটি উপচে পড়বে না।

অসম্পূর্ণতা কেবল প্রদর্শিত হতে পারে। তবে একক নির্ভুলতা ভাসমান পয়েন্ট সংখ্যাটির 7-8 দশমিক অঙ্কের যথার্থতা রয়েছে। এটি যদি সেকেন্ড পরিমাপ করতে ব্যবহার করে তবে এটি প্রায় 194 দিনের জন্য সঠিক। যদি মিলিসেকেন্ডগুলি পরিমাপ করা হয় তবে এটি কেবল 4,5 ঘন্টা জন্য সঠিক। সুতরাং এটি আপনার প্রয়োজনীয় যথাযথতার উপর সম্পূর্ণভাবে নির্ভর করে এবং যদি আপনি মিলিসেকেন্ডের (যা আপনি সম্ভবত না করেন) সঠিক হতে চান তবে আপনাকে বিকল্প উপায়গুলি সন্ধান করতে হবে।


7
ওল্ফ্রাম আলফা একটি বড় আকারের সেটিং ধারণা সরবরাহ করে যে কতগুলি বড় বছর এটি উল্লেখযোগ্য হতে পারে: এটি মহাবিশ্বের বর্তমান বয়সের তুলনায় প্রায় 20 মাত্রা বেশি। বিশ গুণ বেশি নয়, তবে বর্তমান বয়স আরও বিশটি শূন্য।
doppelgreener

1
@ ড্রাকো 18 গুলি unityক্যটি ডেল্টটাইমকে যেভাবে পরিমাপ করে তার উপর নির্ভর করে তবে তারা যদি প্রতিটি ফ্রেমের জন্য একটি সময়কেন্দ্র নেয় এবং সেই দুটিটি বিয়োগ করে তবে আমি মনে করি উত্তরটি একটি নির্দিষ্ট হ্যাঁ।
লুকজি

7
এই উত্তরটি মোটেও ঠিক নয়। আপনি একটি পরীক্ষা চালাতে পারেন। আপনি লুপে একের পর এক ভাসমান বর্ধন করতে পারেন। 10 000 000 এ পৌঁছানোর পরে এটি বৃদ্ধি করা বন্ধ করবে। কারণটি হ'ল আপনি যখন ভাসা নিয়ে কাজ করছেন তখন সঠিকভাবে বড় সংখ্যায় ছোট সংখ্যক যুক্ত করতে পারবেন না। সঠিক উত্তরটি একটি @ ডিএমজিগ্রিওরি দিয়েছিল
সিগল

2
@ সিগল কোথাও আমি ইনক্রিমেন্টিংয়ের বিষয়ে লিখি না। এটি একটি সত্য যে ভাসমানের দ্বারা উপস্থাপিত সর্বাধিক সংখ্যাটি প্রায় (প্রায়) 3,4 * 10 ^ 38, যাতে কঠোর অর্থে (ওপি দ্বারা বোঝানো হয়) উপচে পড়ার নিয়ম থাকে। আমি দেখতে পাচ্ছি না কেন উত্তরটি স্থির হিসাবে ভুল হবে?
লুকজি

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

12

আপনার গেমটি কত স্পষ্টতা প্রয়োজন?

একটি 32-বিট ফ্লাটে 24 বিট বিস্কুট রয়েছে। অন্য কথায়, সময়ে টি, যথার্থতা ± 2 -23 । T। (এটি হুবহু সঠিক নয়, তবে এটি নিকটতম এবং সঠিক বিবরণগুলি মারাত্মক আকর্ষণীয় নয়))

  • আপনার যদি 1 ম্যাসেজ নির্ভুলতা প্রয়োজন, তবে 1 মিমি ÷ 2 -23 = 8400 s = 2h 20 মিটার পরে, 32-বিট ভাসা আর গ্রহণযোগ্য নয়। বেশিরভাগ গেমের জন্য 1 এমএসের যথার্থতা প্রয়োজন হয় না, তবে বাদ্যযন্ত্রের অ্যাপ্লিকেশনগুলির জন্য এটি প্রয়োজনীয় বলে মনে করা হয়।

  • যদি আপনার গেমটি 144 Hz মনিটরে চলে এবং আপনি ফ্রেম-নির্ভুল গ্রাফিক্স চান, তবে 1 ÷ 144 Hz ÷ 2 -23 = 58000 s = 16h এর পরে, 32-বিট ফ্লোট আর গ্রহণযোগ্য হবে না। 16 ঘন্টা একটি গেমটি চালানোর জন্য দীর্ঘ সময়, তবে এটি অকল্পনীয় নয়। আমি বাজি রেখেছি যে আমাদের মধ্যে একটি উল্লেখযোগ্য শতাংশ একক টানা ১ single ঘন্টা খেলা চালিয়েছে - এমনকি যদি আমরা গেমটি চালানো ছেড়ে দিয়েছিলাম এবং কিছুটা ঘুম পেয়েছি। এই মুহূর্তে, অ্যানিমেশন এবং পদার্থবিজ্ঞানের আপডেটগুলি 144Hz এর নীচে কমে যাবে।

যদি ইউনিটির Time.deltaTimeউচ্চতর নির্ভুলতা ঘড়ি থেকে গণনা করা হয়, তবে আপনি এটি ব্যবহার করতে এবং এখনও পুরো নির্ভুলতা পেতে পারেন। আমি জানি না এটি সত্য কিনা না।

সাইড নোট

উইন্ডোজে গেমস এবং অন্যান্য প্রোগ্রামগুলি প্রায়শই GetTickCount()সময় নির্ধারণ করতে ব্যবহার করে। যেহেতু এটি মিলিসেকেন্ডগুলি গণনা করতে একটি 32-বিট পূর্ণসংখ্যার ব্যবহার করে, তাই আপনি যদি আপনার কম্পিউটারটি দীর্ঘ সময় ছেড়ে যান তবে এটি প্রায় 50 দিনে প্রায় গুটিয়ে যায়। আমি সন্দেহ করি যে আপনি যদি 50 দিনের খেলাতে খেলেন তবে অনেক গেমগুলি বিচিত্র উপায়ে ঝুলতে, ক্রাশ করতে বা খারাপ ব্যবহার করবে।

উইন্ডোজ'র মতো পূর্ণসংখ্যারও GetTickCount()ওভারফ্লো হওয়ার ঝুঁকি থাকে, অন্যদিকে ইউনিটির মতো ভাসমানদেরও Time.timeনির্ভুলতা হারাতে পারে।


10

অন্যান্য উত্তরগুলি কেবল অনুমান করে, তাই আমি একটি সাধারণ ityক্য প্রকল্প লিখেছিলাম এবং এটি কিছু সময়ের জন্য চলতে দেয়। কয়েক ঘন্টা পরে এই ফলাফল:

  • UnityEngine.Time.timeবরং দ্রুত নির্ভুলতা হ্রাস করে। প্রত্যাশিত হিসাবে, 4 ঘন্টা গেমটি চালানোর পরে মানগুলি 1 মিলিসেকেন্ডে লাফিয়ে যায় এবং এর পরেও ত্রুটিটি বৃদ্ধি পায়।
  • UnityEngine.Time.deltaTimeityক্য কয়েক ঘন্টা চলার পরেও এটির প্রাথমিক সাব-মিলিসেকেন্ড যথার্থতা রাখে। সুতরাং এটি কার্যত গ্যারান্টিযুক্ত যা deltaTimeপ্ল্যাটফর্ম নির্ভর উচ্চ রেজোলিউশন কাউন্টার থেকে উদ্ভূত হয়েছে (যা সাধারণত 10-1000 বছর পরে ওভারফ্লো হয়)। একটি ছোট্ট ঝুঁকি রয়েছে যা deltaTimeএখনও কিছু প্ল্যাটফর্মে নির্ভুলতা হারাবে।

সময়ের অসম্পূর্ণতা নির্ভর করে এমন সমস্ত কিছুর জন্য এটি একটি বিষয় UnityEngine.Time.time। একটি নির্দিষ্ট উদাহরণ ঘূর্ণন (যেমন একটি উইন্ডমিলের উদাহরণ), যা সাধারণত উপর নির্ভর করে UnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)। এমনকি আরও একটি ইস্যু হ'ল _Timeযা ছায়ার দ্বারা স্পষ্টভাবে অ্যানিমেশনগুলির জন্য ব্যবহৃত হয়। ত্রুটিটি চিহ্নিত হওয়ার আগে শুরু হওয়ার আগে কতটা উচ্চতা থাকা দরকার? 20-30 এমএস নির্ভুলতা (2 দিন) এমন বিন্দু হওয়া উচিত যেখানে লোকেদের সমস্যাটি সম্পর্কে সচেতন এবং গভীর মনোযোগ দেওয়া তারা লক্ষ্য করবে। 50-100 এমএসে (5-10 দিন) সংবেদনশীল লোকেরা যারা সমস্যা সম্পর্কে জানেন না তারা এটি আবিষ্কার করা শুরু করবেন। 200-300 এমএস (20-30 দিন) থেকে সমস্যাটি সুস্পষ্ট হবে।

এ পর্যন্ত আমি নির্ভুলতা পরীক্ষাও দেইনি কয়েকটা _SinTime, _CosTimeএবং Unity_DeltaTimeতাই আমি এই মন্তব্য না করতে পারেন।

এটি স্ক্রিপ্টটি আমি পরীক্ষার জন্য ব্যবহার করেছি। এটি একটি UI.Textউপাদানের সাথে সংযুক্ত , প্রকল্পের প্লেয়ার সেটিংস প্রকল্পটিকে পটভূমিতে চলার অনুমতি দেয় এবং মানের সেটিংসে ভিএসসিঙ্ক প্রতিটি দ্বিতীয় ভি খালি সেট করা থাকে:

public class Time : UnityEngine.MonoBehaviour {
    void Start () {
        LastTime = (double)UnityEngine.Time.time;
        StartTime =  System.DateTime.Now;
        LastPrintTime =  System.DateTime.Now;
    }
    double LastTime;
    System.DateTime StartTime;
    System.DateTime LastPrintTime;
    void Update () {
        double deltaTimeError = (double)UnityEngine.Time.deltaTime - ((double)UnityEngine.Time.time - LastTime);
        if (System.DateTime.Now - LastPrintTime  > System.TimeSpan.FromMilliseconds(1000))
        {
            GetComponent<UnityEngine.UI.Text>().text = "StartTime: " + StartTime.ToLongTimeString()
                + "\nCurrentTime: " + System.DateTime.Now.ToLongTimeString()
                + "\n\nTime.deltaTime: " + UnityEngine.Time.deltaTime.ToString("0.000000")
                + "\nTime.time - LastTime: " + ((float)(UnityEngine.Time.time - LastTime)).ToString("0.000000")
                + "\nAbsolute Error: " +  System.Math.Abs(deltaTimeError).ToString("0.000E0");
            LastPrintTime = System.DateTime.Now;
        }
        LastTime = UnityEngine.Time.time;       
    }
}

এখানে চিত্র বর্ণনা লিখুনএখানে চিত্র বর্ণনা লিখুনএখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

আপনি যদি 0.033203মানটি সম্পর্কে ভাবছেন তবে আমি নিশ্চিত যে 0.033203125এটি আসলে , যার বাইনারি ভাসমান পয়েন্ট উপস্থাপনা রয়েছে 001111010000100000000000000000000মান্টিসাতে অনেকগুলি লক্ষ্য করুন ।

সমাধান নীচে উপস্থিত

বেশিরভাগ জেনারগুলিকে এককভাবে কাজ করার দরকার হয় না। বেশিরভাগ খেলোয়াড় মোট 100 ঘন্টা পর্যন্ত একটি খেলা খেলবেন না, সুতরাং সমস্যা সমাধানের জন্য অর্থ বিনিয়োগ করা লোকেরা কেবল অনুমানযোগ্য কিছু দিন অবধি খেলার সময় অর্থনৈতিকভাবে টেকসই না হওয়ার পরে লক্ষ্য করবে। দুর্ভাগ্যক্রমে আমি একটি সাধারণ সর্বজনীন workaround নিয়ে আসতে পারি না যা কিছু উল্লেখযোগ্য ত্রুটিগুলি না নিয়ে সমস্যার সম্পূর্ণতা ঠিক করে দেয়।

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