เพื่อลดความซับซ้อนของคำตอบ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 ซึ่งเราสามารถตั้งค่าโดยตรงเป็นตำแหน่งปัจจุบันVector3
Vector3.Lerp
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
มีตำแหน่งทั้งหมด (A, B, บางทีคนอื่น ๆ ในอนาคต) และการใช้ที่