কেন আমি ভেক্টর 3 এর সাথে অপারেটর '> =' ব্যবহার করতে পারি না?


9

আমি দুই অবস্থানের আমি পড়ুন মধ্যে সরাতে একটি আয়তক্ষেত্র পেতে চেষ্টা করছি _positionAএবং _positionB। দুটোই টাইপের Vector3। আয়তক্ষেত্রটি ঠিকঠাক হয়ে যায়। যাইহোক, এটি পৌঁছালে _positionBএটি বিপরীত দিকে অগ্রসর হয় না, যেমন এটি করা উচিত।

আমি একবার দেখে কোডটিতে ফিরে গেলাম। আমি এই সিদ্ধান্তে পৌঁছেছি যেহেতু বস্তুটি সরানো হয়েছিল, ifকোডে থাকা বিবৃতিগুলি ফ্রেমটি মিস করেছে যেখানে পুনরায় অবস্থানের সমান ছিল _positionB। আমি সংশোধন করার কোডটি সংশোধন করার সিদ্ধান্ত নিয়েছি যদি রিসেটের অবস্থানের চেয়ে বড় বা সমান হয় _positionB । আমার কোডটি খুব বেশি দীর্ঘ নয়, তাই আমি এটি নীচে প্রদর্শন করব:

using UnityEngine;
using System.Collections;

public class Rectangle : MonoBehaviour 
{
    private Vector3 _positionA = new Vector3(-0.97f, -4.28f); //Start position
    private Vector3 _positionB = new Vector3(11.87f, -4.28f); //End position
    private Transform _rect_tfm;
    private bool _atPosA = false, _atPosB = false;

    public Vector2 speed = new Vector2(1f, 0f);

    private void Start()
    {
        _rect_tfm = gameObject.GetComponent<Transform>();
        _rect_tfm.position = _positionA;
        _atPosA = true;
    }

    private void Update()
    {
        /*NOTE: Infinite loops can cause Unity to crash*/
        Move();
    }

    private void Move()
    {
        if (_atPosA)
        {
            _rect_tfm.Translate(speed * Time.deltaTime);

            if (_rect_tfm.position == _positionB)
            {
                _atPosA = false;
                _atPosB = true;
            }
        }

        if (_atPosB)
        {
            _rect_tfm.Translate(-speed * Time.deltaTime);

            if (_rect_tfm.position == _positionA)
            {
                _atPosA = true;
                _atPosB = false;
            }
        }    
    }
}

আমি যখন এটি পরিবর্তন করেছি, তবে এটি আমাকে নীচের ত্রুটি বার্তা সম্পর্কে সতর্ক করেছিল:

অপারেটর> = ভেক্টর 3 এবং ভেক্টর 3 প্রকারের অপারেন্ডগুলিতে প্রয়োগ করা যাবে না।

এটি আমাকে দুটি কারণে বিভ্রান্ত করে; প্রথমত, উভয় মান একই ডাটা টাইপের type দ্বিতীয়ত, ==দুটি মানতে তুলনা অপারেটর ( ) ব্যবহার করা ত্রুটি ছাড়াই কাজ করে। কেন আমি এস >=দিয়ে অপারেটরটি ব্যবহার করতে পারি না Vector3?


পার্শ্ব নোট: আপনার 2 টি Boolsপছন্দ _atPosAএবং এড়ানো উচিত _atPosB। অনিবার্যভাবে, আপনি তাদের উভয়কে সিঙ্কে রেখে ভুল করবেন এবং এটি বাগের দিকে নিয়ে যাবে। এটি একটি করতে ভালো enumসব অবস্থানের (এ, বি, সম্ভবত ভবিষ্যতে অন্যদের) ধারণকারী, এবং যে ব্যবহার
পুনর্বহাল মনিকা - আলেকজান্ডার

5
একটি >=মানে কি Vector3? উপাদান অনুসারে তুলনা করুন? এটি মোট অর্ডার হবে না। Vector3.MoveTowards
ব্যবহারগুলি

4
এটি বিবেচনা করুন: var vec1 = new Vector3(1, 0, 0)এবং var vec2 = new Vector3(0, 1 ,0)। কি vec1 >= vec2সত্য বা মিথ্যা?
gronostaj

উত্তর:


16

উত্তরটি সহজ করার জন্য, নামস্থান দ্বারা সরবরাহিত Vector3একটি কাস্টম । আমরা যখন কাস্টম তৈরি বা ধরনের, আমরা আবশ্যক এছাড়াও তার সংজ্ঞায়িত অপারেটার । এই হিসাবে, অপারেটরের জন্য কোনও ডিফল্ট যুক্তি নেই । হিসাবে দ্বারা নির্দিষ্ট Evgeny Vasilyev , জ্ঞান করে তোলে, আমরা সরাসরি পরীক্ষা করতে পারবেন যেমন , এবং মান। একটি তিনটি পৃথক মান দ্বারা প্রতিনিধিত্ব করা হয় যে কারণে, ততটা অর্থবোধ করে না ।structUnityEngineclassstruct>=_rect_tfm.position == _positionBVector3.xVector3.yVector3.z_rect_tfm.position >= _positionBVector3

তত্ত্বেরVector3 উপযুক্ত অপারেটরগুলি রাখতে আমরা ক্লাসটি ওভারলোড করতে পারি , তবে এটি জটিল বলে মনে হচ্ছে। পরিবর্তে, এটা সহজ হবে কেবল যাবে প্রসারিত উপযুক্ত সঙ্গে বর্গ পদ্ধতি । বলা হচ্ছে, মনে হচ্ছে আপনার এই যুক্তিটি চলাচলের জন্য ব্যবহার করার ইচ্ছা রয়েছে। এই হিসাবে, আপনি পদ্ধতিটি ব্যবহার করা আরও সহজ মনে করতে পারেন ; যদি তা হয় তবে নীচে আরও পড়ুন।Vector3Vector3.Lerp

এতে এক্সটেনশন পদ্ধতি যুক্ত করা হচ্ছে Vector3

পূর্বে উল্লিখিত হিসাবে, প্রয়োগ <=বা >=একটি Vector3প্রায়শই অযৌক্তিক হয়। চলাচলের জন্য, আপনি সম্ভবত Vector3.Lerpপদ্ধতিটির জন্য আরও পড়তে চান । এটি বলেছিল, আপনি <= =>অন্যান্য কারণে পাটিগণিত প্রয়োগ করতে চাইতে পারেন , তাই আমি আপনাকে একটি সহজ বিকল্প দেব।

পরিবর্তে যুক্তি প্রয়োগের Vector3 <= Vector3বা Vector3 >= Vector3, আমি ব্যাপ্ত প্রস্তাব Vector3জন্য পদ্ধতি অন্তর্ভুক্ত করা বর্গ isGreaterOrEqual(Vector3 other)এবং isLesserOrEqual(Vector3)। আমরা পারি এক্সটেনশন মেথড যোগ একটি থেকে structবা classতাদের মধ্যে ঘোষণা করে staticবর্গ যে উত্তরাধিকারী নেই। আমরা কীওয়ার্ডটি ব্যবহার করে লক্ষ্যটিকে classবা structপ্রথম পরামিতি হিসাবে অন্তর্ভুক্ত করি this। নোট আমার উদাহরণে, আমি অনুমান যে আপনি তা নিশ্চিত করার জন্য সব তিনটি প্রধান মান (অর্থ x, yএবং z) হয় সব যথাক্রমে বড় বা সমান, বা ক্ষুদ্রতর বা সমান। আপনার প্রয়োজন অনুসারে আপনি এখানে নিজের যুক্তি সরবরাহ করতে পারেন।

public static class ExtendingVector3
{
    public static bool IsGreaterOrEqual(this Vector3 local, Vector3 other)
    {
        if(local.x >= other.x && local.y >= other.y && local.z >= other.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public static bool IsLesserOrEqual(this Vector3 local, Vector3 other)
    {
        if(local.x <= other.x && local.y <= other.y && local.z <= other.z)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

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

Vector3 left;
Vector3 right;

// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);

// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);

Vector3সঙ্গে চলন্তVector3.Lerp

কলিং পদ্ধতি আমাদের দুজনের মধ্যে সঠিক অবস্থান নির্ধারণ করতে পারবেন একটি নির্দিষ্ট সময়ে মান। এই পদ্ধতিটির একটা অতিরিক্ত লাভ করে তার লক্ষ্য লক্ষ্য অতিক্রম করা হবে না । তিনটি পরামিতি লাগে; শুরুর অবস্থান, শেষের অবস্থান এবং বর্তমান অবস্থান 0 এবং 1 এর মধ্যে একটি মান হিসাবে প্রতিনিধিত্ব করে It এটি ফলাফল হিসাবে একটি হিসাবে আউটপুট দেয় , যা আমরা সরাসরি বর্তমান অবস্থান হিসাবে সেট করতে পারি।Vector3.LerpVector3Vector3Vector3.LerpVector3

আপনার সমস্যা সমাধান করে, আমি এ- Vector3.Lerpতে সরানোর জন্য প্রস্তাব দিই targetPositionMoveপ্রতিটিটিতে পদ্ধতিটি কল করার পরে Update, আমরা লক্ষ্যমাত্রায় পৌঁছেছি কিনা তা পরীক্ষা করতে পারি; ওভারশুট Lerp.Vector3করবে না , তাই transform.position == targetPositionনির্ভরযোগ্য হয়ে ওঠে। আমরা এখন অবস্থানটি যাচাই করতে পারি এবং ততক্ষণে আন্দোলনটি পরিবর্তন targetPositionকরতে leftPositionবা পরিবর্তন করতে পারি rightPosition

public Vector3 leftPosition, rightPosition;
public float speed;
public Vector3 targetPosition;

private void Awake()
{
    targetPosition = rightPosition;
}

private void Update()
{
    Move();

    if(transform.position == targetPosition)
    {
        // We have arrived at our intended position. Move towards the other position.
        if(targetPosition == rightPosition)
        {
            // We were moving to the right; time to move to the left.
            targetPosition = leftPosition;
        }
        else
        {
            // We were moving to the left; time to move to the right.
            targetPosition = rightPosition;
        }
    }
}

private void Move()
{
    // First, we need to find out the total distance we intend to move.
    float distance = Vector3.Distance(transform.position, targetPosition);

    // Next, we need to find out how far we intend to move.
    float movement = speed * Time.deltaTime;

    // We find the increment by simply dividing movement by distance.
    // This will give us a decimal value. If the decimal is greater than
    // 1, we are moving more than the remaining distance. Lerp 
    // caps this number at 1, which in turn, returns the end position.
    float increment = movement / distance;

    // Lerp gives us the absolute position, so we pass it straight into our transform.
    transform.position = Vector3.Lerp(transform.position, targetPosition, increment);
}

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

বাম যাচাই না করা, নীল ঘনকটি বিস্মৃতিতে চলে যায়;  যখন লাল ঘনক্ষেত্রটি ঠিক যেখানে থামাতে চাইছে সেখানেই থামছে।


বাহ, আপনি সত্যিই অতিরিক্ত মাইল গিয়েছিলেন, আপনাকে অনেক ধন্যবাদ!
জাভিয়ের মার্টিনেজ

27

কোনও প্রকারের >=জন্য সংজ্ঞা দেওয়া Vector3কোনও অর্থহীন নয়। একটি ভেক্টর অন্যের চেয়ে বড় কিনা তা নির্ধারণ করে? তাদের দৈর্ঘ্য বা তাদের পৃথক x, y, z উপাদানগুলি?

একটি ভেক্টর একটি দৈর্ঘ্য এবং একটি দিক। সুতরাং কোনটি আরও বেশি নির্ধারণ করে?

আপনার যদি ব্যবহার করতে পারেন সেই মাপের তুলনা করার প্রয়োজন হয় sqrMagnitude

এই ক্ষেত্রে বিভিন্ন উপাদানগুলি একই কিনা তা কেবল তুলনা করতে Vector3ওভাররাইডগুলি ==। (একটি দ্বার মধ্যে)

এটি একই কারণে দুটি ভেক্টর ব্যবহার করে গুণ করা *সম্ভব নয়। এটি করার কোনও গাণিতিক উপায় নেই। কিছু লোক *বিন্দু প্রোডাক্টের জন্য ব্যবহার করে তবে এটি একটি অস্পষ্ট API নকশা।


Ityক্য Vector3হ'ল একটি struct, সুতরাং রেফারেন্স তুলনা সম্পর্কে অনুচ্ছেদটি ঠিক সঠিক নয়।
31eee384

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

এটি জাভা নয়। সমষ্টি অপারেটর সংজ্ঞায়িত যেখানে স্ট্রাক্ট বা ক্লাসে রেফারেন্স তুলনাটি সত্য নয়
গুস্তাভো ম্যাকিয়েল

সেই অংশটি সরিয়ে দিতে আমি আমার উত্তরটি পরিবর্তন করেছি। তবে সি # জাভা ছিল এক পর্যায়ে। যতদূর আমি জানি ক্লাসগুলির মূলটি এখনও একইভাবে কাজ করে এবং == যদি এটি লিখিত না হয় তবে এটি জাভাতে ঠিক কেমন আচরণ করবে।
ইজজেনি ভ্যাসিলিভ 14

2

এটি একটি পুরানো প্রশ্ন তবে কম প্রযুক্তিগত শর্তাবলী রাখতে, একটি ভেক্টর 3 হ'ল 3 ভাসমান মানগুলির জন্য "ধারক" - এক্স, ওয়াই, জেড।

আপনি পৃথক মানগুলির সাথে তুলনা করতে পারেন, যেমন দুটি ভেক্টর 3 এর x মানগুলির তুলনা করতে, কারণ সেগুলি কেবল সংখ্যা।

যাইহোক, একটি সম্পূর্ণ ভেক্টর 3 এর সাথে অন্য ভেক্টর 3 এর সাথে তুলনা করা যায় না কারণ দুটির তুলনা করতে ব্যবহার করা যেতে পারে এমন একটি মান নেই।


0

ভেক্টর 3 ক্লাসে এক্সটেনশন পদ্ধতি যুক্ত করার বিষয়ে, জেনমলক যা পোস্ট করেছেন কেবল তা জুড়েছেন । সেখানে ইউনিটি মধ্যে একটি বিষয় (এবং আমি নিশ্চিত অন্যান্য খেলা ইঞ্জিন আছি) যখন নির্দিষ্ট তুলনা অপারেটর ব্যবহার করে ( ==, <=এবং >=) দুই ভাসা মানের মধ্যে, কিভাবে ফ্লোটিং পয়েন্ট হিসাব পরিচালিত হয় কারণে। Mathf.Approximatelyপরিবর্তে ব্যবহার করা উচিত, সুতরাং দুটি ভেক্টর একে অপরের সাথে> = বা <= হয় কিনা তা পরীক্ষা করার জন্য নিম্নলিখিত এক্সটেনশন পদ্ধতিগুলি যুক্ত করা যেতে পারে:

using UnityEngine;

public static class ExtendingVector3
{
    public static bool IsGreaterOrEqual(this Vector3 local, Vector3 other)
    {
        bool xCond = local.x > other.x || Mathf.Approximately(local.x, other.x);
        bool yCond = local.y > other.y || Mathf.Approximately(local.y, other.y);
        bool zCond = local.z > other.z || Mathf.Approximately(local.z, other.z);

        if(xCond && yCond && zCond)
            return true;

        return false;
    }

    public static bool IsLesserOrEqual(this Vector3 local, Vector3 other)
    {
        bool xCond = local.x < other.x || Mathf.Approximately(local.x, other.x);
        bool yCond = local.y < other.y || Mathf.Approximately(local.y, other.y);
        bool zCond = local.z < other.z || Mathf.Approximately(local.z, other.z);

        if(xCond && yCond && zCond)
            return true;

        return false;
    }
}

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

0

আমি এই প্রশ্নের ব্যাখ্যা করার একটি ভিন্ন উপায় প্রস্তাব করতে চাই। এর মতো একটি কোড প্যাটার্ন:

if(myPosition >= patrolEnd || myPosition <= patrolStart)
    TurnAround();

মূলত >=/ <=অপারেটরগুলি "বাম দিকটি ডানদিকে পৌঁছেছে বা পাশ দিয়ে গেছে ?" হিসাবে ব্যবহার করার চেষ্টা করছে ? পরীক্ষা।

"পৌঁছেছে বা উত্তীর্ণ" মানে >=/ ব্যবহার <=করার অর্থ এক-মাত্রিক অর্থে বোধগম্য হয়, যদি আমার অবস্থানটি কেবল ভাসা:

if(myX >= rightEnd || myX <= leftEnd)
    TurnAround();

তবে 3 ডি স্পেসে আমাদের সাথে কোন দিকটি পরিমাপ করার জন্য কোনও লাইন নেই, কোন দিকটি "উচ্চ / দীর্ঘ" এবং কোন দিকটি "কম / নিকটে" রয়েছে তা নির্ধারণ করার জন্য। উদাহরণস্বরূপ, আমরা পয়েন্টগুলির মধ্যে টহল দেওয়ার চেষ্টা করতে পারি

patrolStart = (-10,  0,  5)
patrolEnd   = ( 10,  0, -5)

সুতরাং এখন আমরা patrolStart <= myPosition <= patrolEndএক্স অক্ষের উপর আশা করি তবে patrolEnd <= myPosition <= patrolStartজেড অক্ষের উপরে। আমাদের "পৌঁছেছে বা উত্তীর্ণ" অপারেটরটি একটি অক্ষ থেকে অন্য অক্ষরে পৃথক, সুতরাং একটি প্রান্তিকতা এবং একটি সাধারণ বৈষম্য পরীক্ষা পাস করার আমাদের ধারণার মধ্যে আর স্পষ্ট ম্যাপিং নেই।

তবে, এমন একটি উপায় আছে যা আমরা 3 ডি স্পেসে কেবল একটি লাইন বেছে নিতে পারি এবং আমাদের >=/ <=এই পছন্দটিকে এই লাইনের সাথে একক ফ্লোট কেসের মতো আচরণ করতে পারি:

// Here we select the directed line from our start point to our end point.
Vector3 axis = patrolEnd - patrolStart;

// We can make a single number representing the "low" end of our range
// by taking the dot product of this axis with our start point.
float low = Vector3.Dot(axis, patrolStart);

// And the "high" end by dotting this axis with the end point.
float high = Vector3.Dot(axis, patrolEnd);

// And our progress between is the dot product of the axis with our position.
float progress = Vector3.Dot(axis, myPosition);

// Now we can use our turn-around logic just like we were in the 1D case:
if(progress >= high || progress <= low)
    TurnAround();

বোনাস হিসাবে, আপনি যদি অক্ষর ভেক্টর ব্যবহারের আগে এটি স্বাভাবিক করেন, তবে সমস্ত বিন্দু পণ্যগুলি দূরত্বকে উপস্থাপন করে, তাই আপনি ভ্রমণের অক্ষটি বরাবর আপনি উভয় প্রান্ত থেকে ঠিক কতটা দূরে রয়েছেন তা পরিমাপ করতে পারবেন।

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