2017-10-05 20 views
7

Tôi có một hình bán nguyệt như đối tượng trò chơi mà tôi đã tạo bằng cách đặt hai cung trong một đối tượng trò chơi trống (SCircle) và xoay 15 ° (trái arc) và -15 ° (đối với hình cung bên phải) như hình dưới đây.Làm thế nào để xoay đối tượng con trong khi xoay đối tượng con đến một góc nhất định bằng coroutines

enter image description here

SCircle có một enum Orientation với hai giá trị Left (quay SCircle đến 45 °) và Right (quay SCircle tới -45 °) như đã thấy trong hình dưới đây.

enter image description here

tôi sử dụng coroutine sau để di chuyển SCircle giữa định hướng.

IEnumerator RotateLeftOrRight(Vector3 byAngles, float inTime) 
{ 
    Quaternion fromAngle = gameObject.transform.rotation ; 
    Quaternion toAngle = Quaternion.Euler (transform.eulerAngles); 


    if (circOrientation == Orientation.Left) { 
     toAngle = Quaternion.Euler (gameObject.transform.eulerAngles - byAngles); 
     circOrientation = Orientation.Right; 

    } 
    else if (circOrientation == Orientation.Right) { 

     toAngle = Quaternion.Euler (gameObject.transform.eulerAngles + byAngles); 
     circOrientation = Orientation.Left; 
    } 


    for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime) 
    { 
     gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ; 
     yield return null ; 

    } 
    gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1); 
} 

Tôi cũng sử dụng một coroutine rất giống với di chuyển vòng cung cá nhân bằng 30 ° (theo hướng ngược nhau) từ nói, Định hướng Left, như bên dưới trong coroutine và hình ảnh:

IEnumerator RotateArc(GameObject arcGO, Vector3 byAngles, float inTime) 
{ 
    Quaternion fromAngle = arcGO.transform.rotation ; 
    Quaternion toAngle = Quaternion.Euler (arcGO.transform.eulerAngles); 

    if (rightArc.arcOrientation == Arc.Orientation.Down) { 
     toAngle = Quaternion.Euler (arcGO.transform.eulerAngles + byAngles); 
     rightArc.arcOrientation = Arc.Orientation.Up; 

    } 
    else if (rightArc.arcOrientation == Arc.Orientation.Down) { 

     toAngle = Quaternion.Euler (arcGO.transform.eulerAngles - byAngles); 
     rightArc.arcOrientation = Arc.Orientation.Up; 
    } 


    for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime) 
    { 
     arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ; 
     yield return null ; 

    } 
    arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1); 

} 

enter image description here

Kể từ khi SCircle Coroutine được kích hoạt bằng cách nhấp chuột, tôi có trường hợp cá thể vòng cung coroutine được chạy và trước khi hoàn thành phụ huynh SCircle coroutine là cũng chạy. Trong trường hợp này, vòng cung sẽ chuyển động từ Left sang A, không phải là hành vi tôi cần. Tôi muốn hành vi của họ kết thúc tại B khi di chuyển từ Left. Tương tự như vậy, từ B, khi SCircle coroutine được chạy trong khi corcsine vòng cung đang được tiến hành, hướng quay sẽ trở về Left.

Xin lưu ý rằng mũi tên màu xanh biểu thị chuyển động của Arc bên trái, màu đỏ thể hiện Arc bên phải và màu đen biểu thị chuyển động của SCircle - đối tượng mẹ.

enter image description here

+1

Chỉ cần chắc chắn, bạn muốn di chuyển hai cung này cùng một lúc nhưng theo hướng khác nhau và bạn cũng muốn chuyển động kết thúc tại cùng một thời điểm? Nếu có, đối tượng nào là cha mẹ của người khác? – Programmer

+0

@Programmer 'SCircle' là đối tượng cha, được tạo từ một đối tượng trống chứa cả vòng cung trái và phải. Tôi sẽ không muốn chuyển động kết thúc cùng lúc bởi vì vòng quay coroutine của vòng cung con bắt đầu trước khi coroutine quay của bố mẹ 'SCircle'. Do đó vòng xoay vòng cung của con sẽ kết thúc trước cha mẹ. Chỉ cần rằng sẽ có một điểm trong thời gian khi cả hai coroutines đang chạy đồng thời. Nói chung, mỗi coroutine nên cho thời gian của nó. – Bane

+0

vui lòng chỉ cho chúng tôi mã để quay vòng cung 30 độ. Bạn có đặt vòng quay vòng cung thay vì xoay vòng cục bộ không? – lockstock

Trả lời

0

tôi tin rằng các vấn đề bạn đang gặp phải là do thực tế rằng khi bạn xoay vòng cung cá nhân, những gì họ đang quay xung quanh cũng đang quay chính nó.

Nói cách khác, các trục của SCircle đang quay và các cung của bạn đang sử dụng các trục đó để xác định các phép quay của riêng chúng. Vì vậy, nếu bạn nhìn vào ví dụ A của bạn, bạn bảo nó xoay trong không gian thế giới bằng -90, sau đó ngay lập tức nói để xoay trong không gian thế giới bằng 30. Để giải quyết điều này, bạn muốn để có được vòng cung xoay tại địa phương, không phải trong không gian thế giới .

Tôi nghĩ rằng bạn có thể giải quyết việc này bằng cách thiết lập cấu trúc này:

Rỗng GameObject SCircle

------ Rỗng gameObject BlueArcCenter -> vị trí 0,0,0

- --------- arc màu xanh -> thay đổi vị trí ở đây để làm cho nó bù đắp từ số không cũ: (bán kính, 0, 0)

------ Empty gameObject RedArcCenter -> position (0, 0,0)

----------- hồ quang màu đỏ -> thay đổi vị trí ở đây để làm cho nó bù đắp từ zero ví dụ: (- bán kính, 0, 0)

Bây giờ thay đổi mã của bạn để:

Để xoay các vòng cung màu xanh dương và đỏ riêng lẻ, bạn xoay vòng cung của chúng,

Để xoay toàn bộ cấu hình, xoay vòng tròn. Điều này sẽ lần lượt xoay cả hai ArcCenters, mà sẽ lần lượt xoay cả hai vòng cung không phụ thuộc vào cách chúng được định hướng tương đối với nhau, hoặc cho dù chúng đang xoay mình.

Lưu ý: Ngoài ra, tôi đã đọc rằng mọi người đang sử dụng Quatern ít hơn rất nhiều trong những ngày này vì chúng thực sự không có ý nghĩa khi bạn đọc mã. Bạn có thể muốn thay đổi mã của mình thành các phép quay bình thường để làm cho nó dễ đọc hơn.

Nếu bạn đã thiết lập được liệt kê ở trên, sử dụng một cái gì đó như:

để quay vòng tròn:

thisSCircle.transform.Rotate(0, -90, 0, Space.Self); 

để xoay vòng cung xung quanh trung tâm chung của họ:

blueArcCenter.transform.Rotate(0, -30, 0, Space.Self) 
redArcCemter.transform.Rotate(0, 30, 0, Space.Self) 

(bạn muốn cần phải thêm lerps vào và các công cụ nhưng điều này sẽ giúp bạn bắt đầu).

Các vấn đề liên quan