কেন ইউনিটি লেয়ার মাস্কগুলিকে বিট শিফটিং ব্যবহার করা দরকার?


10

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

mask = 1 << LayerMask.NameToLayer("Default");

যখন এই জাতীয় কিছু:

mask = LayerMask.NameToLayer("Default");

আরও স্বজ্ঞাত জ্ঞান তৈরি করে এবং ইউনিটি API এর বাকী অংশগুলির মতো কাজ করে?


2
স্ট্রিং সংস্করণটি ব্যবহার করতে আরও বেশি প্রক্রিয়াকরণ শক্তি লাগে। স্ট্রিংটি উল্লেখ না করা অভ্যন্তরীণভাবে একটি অ্যারে যা একটি রেফারেন্স টাইপ এবং আবর্জনা সংগ্রহকারীতে যুক্ত হয়।
ক্রিথিক

উত্তর:


3

এটি অত্যন্ত পারফরম্যান্ট। এর মধ্যে যা আছে তা - স্পষ্ট উদাহরণ হিসাবে স্ট্রিংগুলির তুলনা 10 এর একটি ফ্যাক্টর দ্বারা ধীরে ধীরে এবং পদার্থবিজ্ঞানের গণনাগুলি খুব অপ্টিমাইজড হতে হবে, সুতরাং এটি ভাল যে কে জানে যে কেউ এটিকে এভাবে লিখেছিল।

সুতরাং সুস্পষ্ট ফলোআপ প্রশ্ন হ'ল কেন রূপান্তর এবং বিট-শিফটিং পরিচালনা করতে এটি কোনও সহায়ক পদ্ধতিতে আবৃত নয়। আমি মনে করি আসলে এটির কাছে কেউ পৌঁছে নি - আমি আমার নিজের নিফটি হেল্পার ইউটিলিটিটি গুটিয়ে রেখেছি এবং এটি সাধারণ অনুশীলন।


1
ইউনিটি টিমের সঠিক নকশা পছন্দটি স্ট্রিংয়ের পরিবর্তে সূচক হিসাবে কোনও পূর্ণসংখ্যার ব্যবহার করা হত। যখন আমি আবর্জনা সংগ্রহকারী সম্ভবত তাদের বর্তমান বাস্তবায়ন নিয়ে চলেছে, স্ট্রিং অ্যারে বরাদ্দের উল্লেখ না করে তার সম্পর্কে কীভাবে ভাবছি তখন আমি ক্রিংজ করি।
ক্রিথিক

1
একেবারে - কোনও অ্যারে পূর্ণসংখ্যার দ্বারা সর্বোত্তমভাবে উল্লেখ করা হয়। একটি পূর্ণ এনাম দ্বারা ইন্টিজারগুলি সহজেই মানুষের পঠনযোগ্য হয়ে উঠতে পারে।
জর্দান জর্জিভ

একটি দ্রুত এবং নোংরা বাস্তবায়ন কাজ করে, তবে বড় প্রকল্পগুলির জন্য আমি [টাইপ নিরাপদ] ব্যবহার করি ( সম্পত্তির দোকান
জর্দান জর্জিভ

20

বিট শিফটিং ব্যবহার করে আপনাকে একটি পদার্থবিজ্ঞানের ক্রিয়াকলাপে একাধিক স্তর আমলে নিতে দেয়:

 Physics.Raycast(ray, out hitInfo, Mathf.Infinity, layerMask )

কিছুটা স্থানান্তরিত না করে, আপনাকে এক স্তর এবং কেবল একটিতে রাইকাস্টের অনুমতি দেওয়া হবে। বিট শিফটিংয়ের সময়, আপনি একাধিক নির্দিষ্ট স্তরগুলিতে রাইকাস্ট করতে পারেন:

layerMask = (1 << LayerMask.NameToLayer("MyLayer1")) | (1 << LayerMask.NameToLayer("MyLayer2")) ;

আপনি নির্দিষ্ট স্তরগুলি ছাড়াও প্রতিটি স্তরগুলিতে রাইকাস্ট করতে পারেন :

layerMask = (1 << LayerMask.NameToLayer("MyLayer1")) | (1 << LayerMask.NameToLayer("MyLayer2")) ;
layerMask = ~layerMask;

আপনি যদি ইউনিটির "স্তর পরিচালক" দেখেন তবে স্তরগুলিকে সাধারণ এক-মাত্রিক অ্যারের সূচক হিসাবে দেখা যেতে পারে


সম্পাদনা: আমি এটি এর আগে কখনও দেখিনি, তবে LayerMaskস্তরটির নাম দিয়ে "গণিত" স্তর মুখোশটি পেতে ক্লাসের একটি ইউটিলিটি ফাংশন রয়েছে:

Debug.Log( LayerMask.GetMask("UserLayerA", "UserLayerB") ) ;

ধরুন UserLayerAএবং UserLayerBএটি দশম এবং একাদশ স্তর। এর 10 এবং 11 এর ব্যবহারকারীর স্তর মান থাকবে। তাদের স্তর মাস্কের মান পেতে তাদের নামগুলি getMask এ দেওয়া যেতে পারে। যুক্তিটি হ'ল তাদের নামের তালিকা বা তাদের নামগুলি সংরক্ষণ করে স্ট্রিংগুলির একটি অ্যারে হতে পারে। এই ক্ষেত্রে রিটার্নের মান 2 2 10 + 2 ^ 11 = 3072 হবে।

ডকুমেন্টেশনের লিঙ্ক: https://docs.unity3d.com/ScriptReferences/LayerMask.GetMask.html


2
আপনার মুখোশগুলির ইউনিয়ন তৈরি |করার সময় পূর্ণসংখ্যার সংযোজনের পরিবর্তে বিটওয়াইস বা পরিবর্তে ব্যবহার করা উচিত +, পূর্ণসংখ্যা যোগটি অপ্রত্যাশিত আচরণ তৈরি করতে পারে।
আশ্চর্য

1
কিন্তু তারপর আবার, তারা যে অভ্যন্তরীণভাবে কাজ করেছেন এবং মত একটি পদ্ধতি প্রদান করে পারেLayerMask.NamesToLayers(params string[] layerNames)
QBrute

ভাল পয়েন্ট @ ওয়ানড্রা! ;) - হ্যাঁ, তারা এই কিউব্রুটটি করতে পারত, তবে আপনি যদি লেয়ার মাস্কটি পরিবর্তনশীলভাবে (স্তরকে সরিয়ে,
উল্টানো

বিটওয়াইজ অপারেশনগুলিও অত্যন্ত দ্রুত। এগুলি বৃহত বাইনারি ডেটা সংমিশ্রনের একটি দুর্দান্ত উপায়।
গুড্ডর

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