เพื่อลดความซับซ้อนของคำตอบVector3เป็นแบบกำหนดเองที่กำหนดstructโดยUnityEngineเนมสเปซ เมื่อเราสร้างที่กำหนดเองclassหรือstructประเภทที่เราจะต้องยังกำหนดของผู้ประกอบการ ดังนั้นจึงไม่มีตรรกะเริ่มต้นสำหรับ>=ผู้ประกอบการ ในฐานะที่เป็นแหลมออกโดยEvgeny Vasilyev , _rect_tfm.position == _positionBทำให้ความรู้สึกที่เราโดยตรงสามารถตรวจสอบVector3.x, Vector3.yและVector3.zค่า _rect_tfm.position >= _positionBไม่สมเหตุสมผลเท่าที่ควรเนื่องจาก a Vector3ถูกแทนด้วยค่าที่ต่างกันสามค่า
เราสามารถโอเวอร์Vector3คลาสเพื่อให้มีตัวดำเนินการที่เหมาะสมในทางทฤษฎีแต่ดูเหมือนจะค่อนข้างซับซ้อน แต่มันจะง่ายขึ้นเพียงเพื่อขยายVector3ระดับที่มีความเหมาะสมวิธี ที่ถูกกล่าวว่าดูเหมือนว่าคุณตั้งใจที่จะใช้ตรรกะนี้สำหรับการเคลื่อนไหว คุณอาจพบว่าการใช้Vector3.Lerpวิธีนี้ง่ายกว่ามาก ถ้าเป็นเช่นนั้นอ่านเพิ่มเติมด้านล่าง
การเพิ่มวิธีการขยายไปยัง Vector3
ดังที่ได้กล่าวไว้ก่อนหน้าการใช้<=หรือ>=a 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ค่าสองค่าในเวลาที่กำหนด สิทธิประโยชน์เพิ่มเติมของวิธีนี้ก็คือว่าจะไม่แหกเป้าหมาย ใช้สามพารามิเตอร์ ตำแหน่งเริ่มต้นตำแหน่งสิ้นสุดและตำแหน่งปัจจุบันแสดงเป็นค่าระหว่าง 0 ถึง 1 โดยจะส่งออกตำแหน่งผลลัพธ์เป็น a ซึ่งเราสามารถตั้งค่าโดยตรงเป็นตำแหน่งปัจจุบันVector3Vector3.LerpVector3
การแก้ปัญหาของคุณผมขอเสนอการใช้ที่จะย้ายไป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มีตำแหน่งทั้งหมด (A, B, บางทีคนอื่น ๆ ในอนาคต) และการใช้ที่