उत्तर को सरल बनाने के लिए, Vector3
एक कस्टम नामस्थान struct
द्वारा प्रदान किया गया UnityEngine
है। जब हम कस्टम class
या struct
प्रकार बनाते हैं, तो हमें इसके ऑपरेटरों को भी परिभाषित करना चाहिए । जैसे, ऑपरेटर के लिए कोई डिफ़ॉल्ट तर्क नहीं है । के रूप में द्वारा बताया एवगेनी वासिलयेव , समझ में आता है, हम सीधे जांच कर सकते हैं के रूप में , और मूल्यों। तथ्य यह है कि तीन अलग-अलग मूल्यों द्वारा प्रतिनिधित्व किया जाता है की वजह से ज्यादा मतलब नहीं है ।>=
_rect_tfm.position == _positionB
Vector3.x
Vector3.y
Vector3.z
_rect_tfm.position >= _positionB
Vector3
हम सिद्धांत मेंVector3
उपयुक्त ऑपरेटरों को शामिल करने के लिए कक्षा को अधिभार दे सकते हैं , लेकिन यह जटिल लगता है। इसके बजाय, यह आसान हो बस करने के लिए विस्तार एक उपयुक्त साथ वर्ग विधि । कहा जा रहा है, ऐसा लगता है कि आंदोलन के लिए इस तर्क का उपयोग करने का आपका इरादा है। जैसे, आपको विधि का उपयोग करना बहुत आसान लग सकता है ; यदि हां, तो आगे पढ़ें।Vector3
Vector3.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
विधि को कॉल करनाVector3.Lerp
हमें Vector3
एक निश्चित समय में दो मूल्यों के बीच सटीक स्थिति निर्धारित करने की अनुमति देता है । इस पद्धति का एक अतिरिक्त लाभ यह है कि यह Vector3
वसीयत अपने लक्ष्य की देखरेख नहीं करेगी । Vector3.Lerp
तीन पैरामीटर लेता है; प्रारंभ स्थिति, अंतिम स्थिति और वर्तमान स्थिति 0 और 1. के बीच मान के रूप में प्रदर्शित होती है। यह परिणामी स्थिति को एक के रूप में आउटपुट करता है Vector3
, जिसे हम सीधे वर्तमान स्थिति के रूप में सेट कर सकते हैं।
आपकी समस्या का समाधान, मैं एक का उपयोग Vector3.Lerp
करने का प्रस्ताव है targetPosition
। Move
प्रत्येक में विधि को कॉल करने के बाद 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
। अनियंत्रित छोड़ दिया, नीला घन विस्मृति में चला जाता है; जबकि लाल घन बिल्कुल वहीं रूक जाता है, जहां तक मैं चाहता हूं। आप स्टैक ओवरफ्लो प्रलेखन में इस प्रकार के आंदोलन के बारे में अधिक पढ़ सकते हैं ।
Bools
लाइक_atPosA
और का उपयोग करने से बचना चाहिए_atPosB
। अनिवार्य रूप से, आप उन दोनों को सिंक में रखते हुए एक गलती करेंगे, और इससे कीड़े पैदा होंगे।enum
भविष्य में सभी पदों (ए, बी, शायद दूसरों को शामिल करना) बनाना बेहतर है , और इसका उपयोग करते हुए