2011-09-09 24 views
8

Trong sự thống nhất, tôi có một cây vợt được cho là để đánh bóng, và vợt được điều khiển trực tiếp bằng chuột, tức là dơi đang được di chuyển bởi chuột sử dụng các trục chuột và hàm transform.translate() sử dụng để di chuyển vợt. Tôi dự kiến ​​rằng vật lý của Unity3d sẽ không dịch chuyển động của vợt trực tiếp một cách thích hợp bằng trực tiếp bằng chuột và tác động đến quả bóng, và tôi sẽ phải viết một thứ gì đó tùy chỉnh, và hóa ra nó là đúng.Vấn đề với phát hiện va chạm của một quả bóng chuyển động nhanh với một cây vợt được điều khiển bằng chuột

Nhưng va chạm của quả bóng không được phát hiện đúng khi vợt đang di chuyển. Khi nó vẫn còn, tất cả mọi thứ là tốt, và bóng hành xử như tôi muốn.

Bây giờ tôi đã đi xa như viết một kịch bản vật lý tùy chỉnh (tôi sử dụng C# cho kịch bản), trong đó tôi đính kèm 4 raycast có chiều dài 0.6F vào bóng, và sau khi thực hiện một số tính toán vector phức tạp, tính toán vận tốc của quả bóng sau khi nhấn vợt, và áp dụng nó trực tiếp với vận tốc của quả bóng bằng cách sử dụng rigidbody.velocity = calculateVelocity(). Bây giờ nó là một lần nữa làm việc tốt khi vợt không di chuyển, nhưng không phải khi tôi di chuyển vợt. Vấn đề chính xác (triệu chứng của) là:

Sử dụng Vật lý tích hợp và phát hiện va chạm: Khi vợt đang di chuyển, quả bóng đôi khi đi thẳng qua vợt và đôi khi nó chậm lại (đến mức không thể tin được).

Sử dụng tập lệnh của tôi để tính toán vận tốc: Vấn đề là như nhau, nhưng nó cho phép tôi xác định những gì là sai khi tôi in bình thường của máy va chạm (vợt). Đôi khi nó cho phép bình thường, và đôi khi đưa ra âm tính của vectơ bình thường, có nghĩa là nó đang đi thẳng qua bề mặt trên cùng và phát hiện cú đánh với mặt dưới của máy va chạm (vợt).

Những điều tôi đã cố gắng:

  1. Tăng kích thước của máy gia tốc (nó hoạt động với các máy gia tốc hộp rộng hơn trên vợt, nhưng sau đó rõ ràng là quả bóng di chuyển từ một khoảng cách khá xa vợt, và kịch bản của riêng tôi hoạt động ở đây, mặc định vật lý cho kết quả lạ khi vợt được di chuyển), trong ngắn hạn tôi không nhận được thực tế mà tôi muốn.

  2. Giảm dấu thời gian cố định thành 0,001, cải thiện đáng kể mọi thứ, nhưng vẫn còn rất xa so với kết quả tôi muốn, và quả bóng lại một lần nữa thường chọn mặt sai của quả bóng.

  3. Thay đổi phát hiện va chạm thành động liên tục. Mà cũng không cải thiện được gì.

Và ngoài các bên sai nhặt tại va chạm, một vấn đề khác tôi đã quan sát thấy là sau khi nảy ra khỏi vợt, bóng là di chuyển nhưng vợt được di chuyển nhanh hơn, nó thay vì di chuyển trong một vòng cung hoàn chỉnh hoặc dòng, bằng cách nào đó xuất hiện ở phía trước của quả bóng, dẫn đến hai lượt truy cập. Nó là một phỏng đoán dựa trên những gì có thể nhìn thấy được.

Ngoài ra, rõ ràng là khía cạnh "chuyển động" của vợt không được đọc bởi vật liệu dựng sẵn của Unity3d, dẫn đến hành vi lạ khi vợt di chuyển bằng chuột chạm vào quả bóng.

Tôi bị kẹt, tôi không biết di chuyển từ đâu đến đây. Xin cho tôi biết tôi đang làm gì sai.

Trả lời

8

Như những người khác đã chỉ ra, vấn đề là bóng đi từ đang ở trên một bên của pad trong một khung để được ở phía bên kia trong kế tiếp. Đối tượng chuyển động nhanh có xu hướng làm điều đó nếu rào cản quá mỏng.

Có ba giải pháp rất đơn giản cho vấn đề này:

  • Tăng kích thước của pad hoặc bóng, đó là những gì đã xảy ra khi bạn thay đổi kích thước máy gia tốc.
  • Thiết lập tốc độ tối đa cho quả bóng, để nó không bao giờ có thể di chuyển đủ nhanh để đi qua các tấm lót.
  • Tăng tần suất mà Unity tính toán vật lý của nó. Nó có thể được thay đổi trong Time Manager, giảm giá trị của Fixed Timestep. Cẩn thận với việc giảm quá nhiều, hoặc động cơ vật lý sẽ không thể hoàn thành một cuộc gọi trước khi vòng tiếp theo là vụ phải bắt đầu và nó sẽ không bao giờ có thể bắt kịp với trò chơi.

Đặt tốc độ tối đa cho các đối tượng chuyển động là điều luôn phải được thực hiện. Bạn không thể mạo hiểm có một vật thể quan trọng trong trò chơi và để mọi thứ trong trạng thái không kiểm soát được.

+0

Tôi đã thử đặt tốc độ tối đa cho cả vợt và quả bóng, tôi có thể tăng kích thước của toàn bộ môi trường, có lẽ điều này có thể cho cơ hội phát hiện phía bên phải của máy va chạm tốt hơn. Tôi sẽ thực hiện cả hai giải pháp được đưa ra bởi Justin808 và tăng kích thước của tất cả mọi thứ. – SpeedBirdNine

+0

Điều này làm việc rất rực rỡ, tôi tăng gấp đôi kích thước của tất cả mọi thứ, và bây giờ nó không phải là thiếu một vụ va chạm. Tôi vẫn còn vấn đề khác mà Justin808 nói đến, rằng vợt tại một thời điểm là ở phía trước của quả bóng và khung tiếp theo nó là đằng sau quả bóng, nhưng ít nhất tôi thấy hai va chạm riêng biệt, có thể được xử lý bằng mã! Cảm ơn rất nhiều! Tôi chỉ mất 2 phút để làm. Bây giờ tôi sẽ thực hiện giải pháp của Justin để giải quyết hai vụ va chạm. Bởi thời gian này nếu ai đó có lời giải thích khác, xin vui lòng chia sẻ nó quá! – SpeedBirdNine

+0

Ok vấn đề được giải quyết, tôi đã không phải đặt một raycast giữa vị trí trước đó và tiếp theo của quả bóng như bây giờ các va chạm của vợt là không thiếu bóng. Điều khác là chuyển động vợt thông qua chuột không dịch lực bổ sung áp dụng cho quả bóng. Tôi đã phải viết phần này bản thân mình, và thiết lập istrigger là đúng cho máy va chạm vợt để vật lý ban đầu không can thiệp. Nhưng bây giờ đã có một vấn đề đánh nhiều lần, tôi giải quyết nó bằng cách sử dụng một lá cờ, mà trở thành sai khi nhấn lần đầu tiên, và đúng một lần nữa sau 1 giây, hoặc khi bóng chạm một đối tượng khác. Những công việc này! – SpeedBirdNine

3

Đây không phải là câu trả lời hoàn chỉnh, nhưng tôi nhớ đã giải quyết một vấn đề như thế này nhiều năm trước trên các máy chậm hơn.

Sự cố đang sử dụng phát hiện va chạm dựa trên sprite; dựa vào điểm ảnh cho sprite và chướng ngại vật được hiển thị ở cùng tọa độ. Nếu tốc độ khung hình quá thấp đến mức kích thước của vật cản nhiều hơn kích thước của vật cản trong một khung hình, bạn sẽ gặp phải các tình huống ở đó (ví dụ) bên trái của chướng ngại vật trong một khung và bên phải của chướng ngại vật trong khung tiếp theo mà không bao giờ chiếm cùng một pixel.

Trong trường hợp này, các va chạm dựa trên sprite không hoạt động, bạn phải dựa vào xung đột trên vectơ. Thay vì kiểm tra từng pixel sprite cho va chạm, ghi lại vị trí và vỏ lồi của sprite. Sau mỗi khung, tính toán một vectơ từ vị trí cũ đến vị trí mới và cắt nó với thân lồi của mỗi chướng ngại vật.

Có nhiều lối tắt bạn có thể thực hiện, như so sánh chỉ với hộp giới hạn lúc đầu và tính toán thân tàu chỉ khi véc-tơ cắt một hộp giới hạn, nhưng đây là ý tưởng cơ bản. Chúc may mắn.

+1

Ý tưởng có vẻ là một điểm khởi đầu tốt, nhưng bất kỳ ý tưởng nào về cách triển khai nó trong Unity3d bằng cách sử dụng càng nhiều công cụ được tích hợp càng tốt (tại đó được tối ưu hóa). Và về máy chậm, tôi đã thử nghiệm nó trên một máy i7 lõi ​​với 6 GB DDR3 RAM và 1 GB card đồ họa ATI Radeon HD5890, và FPS không bao giờ giảm xuống dưới 70. Và hãy giải thích phát hiện va chạm dựa trên sprite là gì và Unity3d này sử dụng ? Kể từ khi tôi đang sử dụng Unity3d, tôi không nghĩ rằng tôi sẽ có thể kiểm soát các chi tiết cụ thể của cơ chế phát hiện va chạm đến mức này – SpeedBirdNine

+1

Xin lỗi, chưa sử dụng Unity. Đồ họa dựa trên Sprite sử dụng bộ đệm khung thực tế để tính toán; nếu bạn đang sử dụng OpenGL hoặc ActiveX, có lẽ bạn không sử dụng sprites. Tuy nhiên, khái niệm kiểm tra vectơ chống lồi cho va chạm được áp dụng cho đồ họa chế độ được giữ lại. Tôi tưởng tượng Unity có một cách nhìn thấy nếu một vector cắt một thân tàu. –

+0

Có câu trả lời nào khác không? – SpeedBirdNine

5

Điều tôi nghĩ đang xảy ra là mỗi khoảng thời gian xảy ra bóng/vợt được di chuyển và sau đó kiểm tra xem có va chạm hay không. Vấn đề là bóng/vợt di chuyển đến xa trong một khoảng thời gian duy nhất và bỏ lỡ vụ va chạm.

1) Ball before racquet 
2) Ball after racquet 

not 

1) Ball before racquet 
2) Ball touching racquet 

Vì vậy, những gì bạn phải làm là trong phương thức FixedUpdate() của bóng GameObject của bạn được truyền một tia từ vị trí bóng hiện tại đến vị trí bóng trước đó. Nếu có bất cứ điều gì giữa hai điểm đó nên đã bị đánh (tức là vợt) di chuyển quả bóng trở lại điểm nhấn được báo cáo trên tia. Điều này sẽ kích hoạt công cụ phát hiện va chạm hiện tại của bạn.

Lý do làm tăng kích thước của máy va chạm cũng là do quả bóng không bỏ qua máy va chạm lager. Điều này có những hạn chế mà bạn đã đề cập trong câu hỏi của bạn. Việc đúc ray tránh được vấn đề này và cho phép bóng/vợt di chuyển nhanh hoặc chậm khi cần.

0

Tôi cũng đang làm việc trên trò chơi pong 3d và đã gặp phải các vấn đề tương tự. Tôi sẽ cố gắng mở rộng mọi thứ như các bạn đã làm. Đối với tốc độ bổ sung của mái chèo và quay sang quả bóng, tôi bị bối rối bởi điều này cho đến khi tôi nhận ra rằng việc thay đổi vị trí của mái chèo không làm thay đổi vận tốc của nó. Nếu paddle ở vận tốc bằng không trước khi nó được di chuyển, nó sẽ bằng 0 khi động cơ vật lý nhìn vào khung tiếp theo.Un kiểm tra là kenimatic và kiểm soát paddle trực tiếp thông qua tài sản vận tốc cố định vấn đề. Nó gây ra các paddle jitter khi đánh tường, nhưng tôi cố định rằng bằng cách loại bỏ các bức tường từ lớp mái chèo và xử lý ranh giới bằng tay trong LateUpdate. Ngoài ra, khi bạn cập nhật vận tốc, trước tiên hãy lưu tốc độ mong muốn mới trong Cập nhật để các điều khiển hoạt động trơn tru, sau đó cam kết các thay đổi trong FixedUpdate.

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