Để đơn giản hóa câu trả lời, Vector3
là một tùy chỉnh struct
được cung cấp bởi UnityEngine
không gian tên. Khi chúng ta tạo tùy chỉnh class
hoặc struct
loại, chúng ta cũng phải xác định toán tử của nó . Như vậy, không có logic mặc định cho >=
toán tử. Như đã chỉ ra bởi Evgeny Vasilyev , _rect_tfm.position == _positionB
có ý nghĩa, như chúng ta có thể trực tiếp kiểm tra Vector3.x
, Vector3.y
và Vector3.z
các giá trị. _rect_tfm.position >= _positionB
không có ý nghĩa nhiều như vậy, do thực tế là a Vector3
được biểu thị bằng ba giá trị riêng biệt.
Chúng ta có thể quá tải Vector3
lớp để chứa các toán tử phù hợp trong lý thuyết , nhưng điều đó có vẻ khá phức tạp. Thay vào đó, nó sẽ dễ dàng hơn chỉ đơn giản là mở rộng các Vector3
lớp học với một phù hợp phương pháp . Điều đó đang được nói, có vẻ như bạn có ý định sử dụng logic này cho chuyển động. Như vậy, bạn có thể thấy việc sử dụng Vector3.Lerp
phương thức này dễ dàng hơn nhiều ; nếu vậy, đọc thêm bên dưới.
Thêm phương thức mở rộng vào Vector3
Như đã đề cập trước đây, áp dụng <=
hoặc >=
cho một Vector3
thường là phi logic. Đối với chuyển động, có lẽ bạn muốn đọc thêm cho Vector3.Lerp
phương pháp. Điều đó nói rằng, bạn có thể muốn áp dụng <=
=>
số học cho các lý do khác, vì vậy tôi sẽ cung cấp cho bạn một sự thay thế dễ dàng.
Thay vì áp dụng logic của Vector3 <= Vector3
hoặc Vector3 >= Vector3
, tôi đề xuất mở rộng Vector3
lớp để bao gồm các phương thức cho isGreaterOrEqual(Vector3 other)
và isLesserOrEqual(Vector3)
. Chúng ta có thể thêm các phương thức mở rộng vào một struct
hoặc class
bằng cách khai báo chúng trong một static
lớp không kế thừa. Chúng tôi cũng bao gồm mục tiêu class
hoặc struct
là tham số đầu tiên, sử dụng this
từ khóa. Lưu ý rằng trong ví dụ của tôi, tôi cho rằng bạn có nghĩa là để đảm bảo rằng tất cả ba giá trị chính ( x
, y
và z
) là tất cả lớn hơn hoặc bằng, hoặc thấp hơn hoặc tương đương, tương ứng. Bạn có thể cung cấp logic của riêng bạn, ở đây, như bạn yêu cầu.
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;
}
}
}
Khi chúng ta cố gắng gọi các phương thức này từ Vector3
lớp, local
sẽ đại diện cho Vector3
thể hiện mà chúng ta đang gọi phương thức từ đó. Bạn sẽ lưu ý rằng các phương thức là static
; phương thức mở rộng phải có static
, nhưng bạn vẫn phải gọi chúng từ một thể hiện. Với các phương thức mở rộng ở trên, bây giờ bạn có thể áp dụng chúng trực tiếp cho các Vector3
loại của mình .
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Di chuyển Vector3
vớiVector3.Lerp
Kêu gọi các Vector3.Lerp
phương pháp cho phép chúng ta xác định vị trí chính xác giữa hai Vector3
giá trị tại một thời điểm nhất định. Một lợi ích gia tăng của phương pháp này là các Vector3
sẽ không vọt lố mục tiêu của nó . Vector3.Lerp
lấy ba tham số; vị trí bắt đầu, vị trí kết thúc và vị trí hiện tại được biểu thị dưới dạng giá trị từ 0 đến 1. Nó xuất ra vị trí kết quả là a Vector3
, mà chúng ta có thể đặt trực tiếp làm vị trí hiện tại.
Giải quyết vấn đề của bạn, tôi đề xuất sử dụng Vector3.Lerp
để chuyển sang a targetPosition
. Sau khi gọi Move
phương thức trong mỗi phương thức Update
, chúng ta có thể kiểm tra xem chúng ta đã đạt được mục tiêu đã nói chưa; Lerp.Vector3
sẽ không vượt quá, vì vậy transform.position == targetPosition
trở nên đáng tin cậy. Bây giờ chúng ta có thể kiểm tra vị trí và thay đổi targetPosition
thành leftPosition
hoặc rightPosition
đảo ngược chuyển động, theo đó.
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);
}
Bạn có thể thấy điều này được thể hiện trong hình ảnh động sau đây. Tôi dịch khối lập phương màu xanh với Vector3.LerpUnclamped
, cho chúng ta một kết quả tương tự với bản dịch đơn giản không được kiểm tra. Tôi dịch khối lập phương màu đỏ bằng cách sử dụng Vector3.Lerp
. Không được kiểm soát, khối màu xanh chuyển sang quên lãng; trong khi khối màu đỏ dừng lại chính xác nơi tôi dự định. Bạn có thể đọc thêm về loại chuyển động này trong tài liệu Stack Overflow .
Bools
like_atPosA
và_atPosB
. Chắc chắn, bạn sẽ phạm sai lầm khi giữ cả hai đồng bộ hóa và điều đó sẽ dẫn đến lỗi. Tốt hơn là tạo mộtenum
vị trí chứa tất cả các vị trí (A, B, có thể là các vị trí khác trong tương lai) và sử dụng vị trí đó