কোনও গেম অবজেক্টের উপাদানটি ধ্বংস হতে পারে কিনা তা পরীক্ষা করে দেখুন


11

Ityক্যে একটি গেম বিকাশ করে, [RequireComponent(typeof(%ComponentType%))]উপাদানগুলির সমস্ত নির্ভরতা মেটাতে পারে তা নিশ্চিত করার জন্য আমি উদার ব্যবহার করছি ।

আমি এখন একটি টিউটোরিয়াল সিস্টেম প্রয়োগ করছি যা বিভিন্ন UI অবজেক্টগুলিকে হাইলাইট করে। হাইলাইট করার জন্য, আমি GameObjectদৃশ্যের মধ্যে একটি রেফারেন্স নিচ্ছি , তারপরে আমি এটিকে ইনস্ট্যানিয়েট () দিয়ে ক্লোন করে রেখেছি এবং তারপরে পুনরাবৃত্তভাবে সমস্ত উপাদানগুলি সরিয়ে ফেলি যা প্রদর্শনের জন্য প্রয়োজন হয় না। সমস্যাটি হ'ল RequireComponentএই উপাদানগুলির উদার ব্যবহারের ফলে অনেকগুলি কোনও ক্রমে সরানো যায় না, যেহেতু তারা অন্যান্য উপাদানগুলির উপর নির্ভর করে, যা এখনও মুছে ফেলা হয়নি।

আমার প্রশ্ন হ'ল: এটির সাথে সংযুক্ত থাকার সাথে কোনওটিকে Componentসরানো যেতে পারে কিনা তা নির্ধারণ করার কোনও উপায় আছে কি GameObject?

আমি যে কোডটি পোস্ট করছি তা প্রযুক্তিগতভাবে কাজ করে, তবে এটি ইউনিটির ত্রুটি ছুঁড়ে ফেলেছে (চিত্রটিতে যেমন দেখানো হয়েছে তেমন চেষ্টা-ধরার ব্লকে ধরা পড়েনি)

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

কোডটি এখানে:

public void StripFunctionality(RectTransform rt)
{
    if (rt == null)
    {
        return;
    }

    int componentCount = rt.gameObject.GetComponents<Component>().Length;
    int safety = 10;
    int allowedComponents = 0;
    while (componentCount > allowedComponents && safety > 0)
    {
        Debug.Log("ITERATION ON "+rt.gameObject.name);
        safety--;
        allowedComponents = 0;
        foreach (Component c in rt.gameObject.GetComponents<Component>())
        {
            //Disable clicking on graphics
            if (c is Graphic)
            {
                ((Graphic)c).raycastTarget = false;
            }

            //Remove components we don't want
            if (
                !(c is Image) &&
                !(c is TextMeshProUGUI) &&
                !(c is RectTransform) &&
                !(c is CanvasRenderer)
                )
            {
                try
                {
                    DestroyImmediate(c);
                }
                catch
                {
                    //NoOp
                }
            }
            else
            {
                allowedComponents++;
            }
        }
        componentCount = rt.gameObject.GetComponents<Component>().Length;
    }

    //Recursive call to children
    foreach (RectTransform childRT in rt)
    {
        StripFunctionality(childRT);
    }
}

পথ তাই এই কোড ডিবাগ লগ শেষ তিন লাইন উত্পন্ন নিম্নোক্ত উপরে: এটা ইনপুট হিসেবে গ্রহণ GameObjectদুই উপাদান সঙ্গে Buttonএবং PopupOpenerPopupOpenerঅনুরোধ করে যে কোনও Buttonউপাদান একই গেমবজেক্টের সাথে উপস্থিত রয়েছে:

[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
    ...
}

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

সুতরাং আমার প্রশ্নটি হল যে কোনও নির্দিষ্ট উপাদানকে তার বর্তমান থেকে সরিয়ে নেওয়া GameObject, বিনা অনুরোধে Destroy()বা না করে যদি সময়ের আগে পরীক্ষা করা সম্ভব হয় কিনা DestroyImmediate()। ধন্যবাদ.


মূল সমস্যা সম্পর্কে - জিইউআই উপাদান (গুলি) এর অ-ইন্টারেক্টিভ অনুলিপি (= ভিজ্যুয়াল) তৈরির লক্ষ্য কি?
আশ্চর্যজনকভাবে

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

আমার Unক্য নিয়ে অভিজ্ঞতা নেই তবে আমি ভাবছি যদি পুরো জিনিসটি ক্লোনিং করে এবং জিনিসগুলি সরিয়ে না দিয়ে আপনি কেবল আপনার প্রয়োজনীয় অংশগুলি অনুলিপি করতে পারেন?
জ্যান লিংস

আমি এটি পরীক্ষা করে দেখিনি, তবে Destroyফ্রেমের শেষে উপাদানটি সরিয়েছি ( Immediateলির বিপরীতে )। DestroyImmediateযাইহোক, খারাপ শৈলী হিসাবে বিবেচনা করা হয়, তবে আমি ভাবছি এতে স্যুইচ করা Destroyআসলে এই ত্রুটিগুলি দূর করতে পারে।
CAD97

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

উত্তর:


9

এটা স্পষ্টভাবে সম্ভব, কিন্তু এটা বেশ legwork অনেকটা প্রয়োজন: আপনি না পরীক্ষা করতে যদি একটি Componentসংযুক্ত GameObjectযা হয়েছে একটি Attributeটাইপ RequireComponentযা তার অন্যতম m_Type#ক্ষেত্র কম্পোনেন্ট ধরনের সরাতে চলেছেন করার হস্তান্তরযোগ্য। সমস্ত একটি এক্সটেনশন পদ্ধতিতে আবৃত:

static class GameObjectExtensions
{
    private static bool Requires(Type obj, Type requirement)
    {
        //also check for m_Type1 and m_Type2 if required
        return Attribute.IsDefined(obj, typeof(RequireComponent)) &&
               Attribute.GetCustomAttributes(obj, typeof(RequireComponent)).OfType<RequireComponent>()
               .Any(rc => rc.m_Type0.IsAssignableFrom(requirement));
    }

    internal static bool CanDestroy(this GameObject go, Type t)
    {
        return !go.GetComponents<Component>().Any(c => Requires(c.GetType(), t));
    }
}

GameObjectExtensionsপ্রকল্পের যে কোনও জায়গায় ড্রপ করার পরে (বা বিকল্পভাবে এটি স্ক্রিপ্টে একটি নিয়মিত পদ্ধতি হিসাবে তৈরি করুন), আপনি কোনও উপাদান অপসারণ করতে পারবেন কিনা তা পরীক্ষা করে দেখতে পারেন, যেমন:

rt.gameObject.CanDestroy(c.getType());

তবে আন-ইন্টারেক্টিভ জিইউআই অবজেক্ট তৈরি করার অন্যান্য উপায়ও থাকতে পারে - উদাহরণস্বরূপ, এটি টেক্সচারে রেন্ডারিং, প্রায় স্বচ্ছ প্যানেল দিয়ে এটি আবৃত করা যা ক্লিকগুলিকে বা অকার্যকর করে দেবে (ধ্বংসের পরিবর্তে) সমস্ত Componentপ্রাপ্ত MonoBehaviourবা থেকে প্রাপ্ত IPointerClickHandler


ধন্যবাদ! আমি ভাবছিলাম যে ityক্যের সাথে একটি তৈরি সমাধান সমাধানে পাঠানো হয় তবে আমি অনুমান করি না :) আপনার কোডের জন্য আপনাকে ধন্যবাদ!
লিয়াম লাইম

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

7

ক্লোনটির উপাদানগুলি অপসারণের পরিবর্তে, কেবল সেগুলি স্থাপন .enabled = falseকরে আপনি সেগুলি অক্ষম করতে পারেন । এটি নির্ভরতা পরীক্ষাগুলি ট্রিগার করবে না, কারণ নির্ভরতা পূরণের জন্য কোনও উপাদান সক্ষম করার দরকার নেই।

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

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