การจัดการการชนด้วยฟิสิกส์มาตรฐาน (2D)
สภาพแวดล้อมการตรวจสอบ
- หน้าต่าง
-
- หน้าต่าง 11
- บรรณาธิการ Unity
-
- ปี 2021.3.3f1
- แพ็คเกจระบบอินพุต
-
- 1.3.0
ข้อกําหนดเบื้องต้นสําหรับเคล็ดลับนี้
การตั้งค่าต่อไปนี้ได้ทําไว้ล่วงหน้าเพื่อเป็นหลักฐานสําหรับคําอธิบายของเคล็ดลับนี้
ทีแรก
เคล็ดลับนี้วางวัตถุสองชิ้นเพื่อให้คุณสามารถใช้พฤติกรรมในการจัดการวัตถุหนึ่งและใช้ฟิสิกส์มาตรฐานของ Unity เพื่อผลักอีกวัตถุหนึ่งเมื่อสัมผัสกับอีกวัตถุหนึ่ง
อย่างไรก็ตามการตั้งค่าส่วนใหญ่จะเหมือนกับขั้นตอนที่อธิบายไว้ในบทความก่อนหน้านี้ "การพิจารณาว่าวัตถุชนกัน (2D)" หรือไม่
การตระเตรียม
ขั้นตอนที่นี่เกือบจะเหมือนกับเคล็ดลับก่อนหน้านี้ ดังนั้นเรามาไหลอย่างราบรื่น
หลังจากสร้างโครงการแล้วให้เตรียมภาพสไปรท์สองภาพที่จะเป็นวัตถุและเพิ่มเข้าไป ชื่อคือ "UnityTips" และ "UnityTips_2" ตามลําดับ
เพิ่มไฟล์ภาพสองไฟล์โดยวางลงในมุมมอง
เพิ่มสคริปต์เพื่อย้ายวัตถุด้านซ้ายด้วยแป้นพิมพ์ ชื่อ Player
สคริปต์คือ .
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
// 一定時間ごとに呼ばれます
void FixedUpdate()
{
// キーボードの情報を取得
var keyboard = Keyboard.current;
// スプライトの移動処理
if (keyboard.leftArrowKey.isPressed)
{
transform.Translate(-0.1f, 0, 0, Space.World);
}
if (keyboard.rightArrowKey.isPressed)
{
transform.Translate(0.1f, 0, 0, Space.World);
}
if (keyboard.upArrowKey.isPressed)
{
transform.Translate(0, 0.1f, 0, Space.World);
}
if (keyboard.downArrowKey.isPressed)
{
transform.Translate(0, -0.1f, 0, Space.World);
}
}
}
แนบกับวัตถุที่คุณต้องการเรียกใช้สคริปต์
เรียกใช้เกมและตรวจสอบว่าใช้งานได้กับปุ่มเคอร์เซอร์บนแป้นพิมพ์ของคุณหรือไม่
สุดท้ายวางวัตถุข้อความเพื่อแสดงสถานะการตรวจจับการชนกัน
ชื่อ TextState
วัตถุคือ .
การตั้งค่าการจัดการการชน
จากที่นี่คุณสามารถกําหนดการตั้งค่าที่เกี่ยวข้องกับการชน
ขั้นแรกให้เลือกวัตถุที่คุณต้องการย้าย" UnityTips" และคลิก "เพิ่มส่วนประกอบ" จากตัวตรวจสอบ
เลือกจาก Physics 2D
รายการ Physics
เป็นวัตถุ 3 มิติดังนั้นอย่าทําผิดพลาด
Physics 2D
Box Collider 2D
เลือกจาก . เนื่องจากสไปรท์นี้เป็นรูปสี่เหลี่ยมผืนผ้า Box จึงถูกเลือก แต่ถ้าเป็นรูปวงกลม ให้เลือกรูปร่างอื่นๆ เช่น วงกลม
ครั้งสุดท้ายฉันต้องการรับข้อมูลเท่านั้นว่าฉันตีหรือไม่ดังนั้นฉันจึงตรวจสอบ "ทําให้มันทริกเกอร์" แต่คราวนี้ฉันจะไม่ทํา สิ่งนี้ทําให้สามารถจัดการการชนกันในฟิสิกส์ได้
Rigidbody 2D
จากนั้นเพิ่มส่วนประกอบของ . คุณสามารถเพิ่มได้จาก "ฟิสิกส์ 2D -> Rigidbody 2D"
Rigidbody
ให้ข้อมูลCollider
ทางฟิสิกส์แก่วัตถุและยังสามารถกําหนดการชนกับวัตถุที่มี .
ตั้งค่ามาตราส่วนแรงโน้มถ่วงเป็น 0 เพื่อป้องกันการตกอิสระด้านล่าง
ในทํานองเดียวกันให้เพิ่มส่วนประกอบลงในวัตถุอื่น "UnityTips_2" เพื่อทําเครื่องหมาย Box Collider 2D
ความนิยม
นอกจากนี้คราวนี้มีความจําเป็นต้องเคลื่อนที่ด้วยแรงของฝ่ายตรงข้ามRigidbody 2D
ดังนั้นเพิ่ม . ระดับแรงโน้มถ่วงควรเป็น 0
นั่นคือทั้งหมดที่มีไป ไม่จําเป็นต้องใช้โปรแกรมในขณะนี้ เรียกใช้เกมและลองสัมผัสวัตถุอื่น
ฉันคิดว่าคุณสามารถยืนยันได้ว่าถ้าคุณผลักคู่ต่อสู้ในลักษณะนี้ฝ่ายตรงข้ามจะทําตัวราวกับว่าเขาถูกผลัก มันง่ายมากที่จะใช้ฟิสิกส์ของฟังก์ชันมาตรฐานเพราะไม่จําเป็นต้องใช้โปรแกรม
ป้องกันไม่ให้วัตถุหมุน
คุณสามารถดูได้เมื่อคุณสัมผัส แต่ถ้าจุดตีเลื่อนแม้เพียงเล็กน้อยวัตถุแต่ละชิ้นจะหมุน ในฐานะที่เป็นเกมมันมักจะไม่เป็นธรรมชาติดังนั้นคุณต้องตั้งค่าเพื่อไม่ให้หมุน
Rigidbody 2D
ส่วนประกอบมีรายการที่เรียกว่า "การหมุนคงที่" ใน "ข้อ จํากัด " ดังนั้นตรวจสอบ Z
ตอนนี้คุณสามารถทํางานได้เพื่อไม่ให้หมุน ลองตั้งค่าเป็นวัตถุสองชิ้นและเรียกใช้เกมเพื่อตรวจสอบ
ฉันคิดว่าคุณสามารถมั่นใจได้ว่ามันจะไม่หมุนไม่ว่าคุณจะผลักมันจากมุมใด
ทําอะไรบางอย่างเมื่อวัตถุชนกัน
ตัวอย่างเช่นคุณอาจต้องการใช้กระสุนที่โจมตีศัตรูในขณะที่ผลักคู่ต่อสู้ในขณะที่ลดสุขภาพของศัตรู นี่เป็นวิธีเดียวกับเคล็ดลับก่อนหน้านี้ เนื่องจากเหตุการณ์จะเกิดขึ้นเพื่อให้คุณสามารถจัดการกับมันได้
Player
เปิดสคริปต์และเพิ่มแต่ละฟิลด์และวิธีการโดยใช้ดังนี้:
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class Player : MonoBehaviour
{
<summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;
// 中略
<summary>衝突した瞬間に呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
}
เนื่องจากเราต้องการแสดงข้อมูลว่าโดนหรือไม่เราจึงทําให้สามารถแสดงในวัตถุข้อความได้ดังนี้
<summary>状態表示用テキストオブジェクト。</summary>
[SerializeField] private Text TextState;
กระบวนการตรวจจับการชนกันอธิบายไว้ดังนี้
<summary>衝突した瞬間に呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionEnter2D(Collision2D partner)
{
TextState.text = $"OnCollisionEnter2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突している間呼ばれます。ただしスリープモードになった場合は呼ばれません。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionStay2D(Collision2D partner)
{
TextState.text = $"OnCollisionStay2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
<summary>衝突状態でなくなったタイミングで呼ばれます。</summary>
<param name="partner">衝突した相手のコリジョン情報。</param>
private void OnCollisionExit2D(Collision2D partner)
{
TextState.text = $"OnCollisionExit2D : {partner.collider.tag} {DateTime.Now:HH:mm:ss.fff}{Environment.NewLine}{TextState.text}";
}
คล้ายกับเคล็ดลับก่อนหน้านี้------, แต่ชื่อวิธีการตอนนี้คือ "OnCollision------2D" แทนที่จะเป็น "OnTrigger2D"
Rigidbody 2D
แต่ละเหตุการณ์ข้างต้นเกิดขึ้นเมื่อวัตถุที่ชนกับวัตถุ Collider 2D
อื่นที่มี .
สิ่งนี้จะช่วยให้คุณกําหนดและประมวลผลว่าถูกต้องหรือไม่
มีสามเหตุการณ์ซึ่งแต่ละเหตุการณ์จะถูกเรียกในเวลาต่อไปนี้
OnCollisionEnter2D | เมื่อวัตถุชนกัน |
OnCollisionStay2D | ในขณะที่วัตถุกําลังตีกัน |
OnCollisionExit2D | เมื่อวัตถุออกจากสถานะการชน |
ในทั้งสองกรณีวัตถุฝ่ายตรงข้ามจะได้รับวัตถุของฝ่ายตรงข้ามเป็นอาร์กิวเมนต์ดังนั้นคุณสามารถรับวัตถุของCollision2D
ฝ่ายตรงข้ามได้โดยค้นหาCollider2D.gameObject
ประเภทของเป้าหมายที่ถูกโจมตีโดย (ศัตรูCollider2D.collider.tag
ไอเท็ม ฯลฯ )
OnCollisionEnter2D
จากสามเหตุการณ์ข้างต้นและOnCollisionExit2D
เรียกว่าหนึ่งครั้งต่อการชนกัน
OnCollisionStay2D
เรียกว่าทุกเฟรมระหว่างการชน แต่เหตุการณ์จะไม่ถูกเรียกอีกต่อไปหลังจากเวลาผ่านไประยะหนึ่งเนื่องจากวัตถุทั้งสองหยุดลง
นี่เป็นเพราะมันถือว่าได้เข้าสู่สถานะการนอนหลับและถือว่าเป็นการสูญเสียการประมวลผลเพื่อคํานวณการชนทุกเฟรมกับสิ่งที่ไม่เคลื่อนที่
หากคุณ Rigidbody 2D
ไม่ต้องการให้เข้าสู่โหมดสลีป ให้เปลี่ยนโหมดสลีปของพารามิเตอร์เป็น "อย่าสลีป"
หลังจากเปลี่ยนรหัสแล้วให้ตั้งค่าข้อความสําหรับการแสดงข้อมูล
เรียกใช้เกมและย้ายวัตถุด้วยแป้นพิมพ์เพื่อสัมผัสสไปรท์อื่น คุณจะเห็นว่ามีการเรียกฟังก์ชั่นสามอย่างสําหรับแต่ละฟังก์ชัน
โดยวิธีการถ้าคุณสัมผัสวัตถุแล้วหยุดเคลื่อนไหววิธีการจะถูกเรียกในช่วงเวลา OnCollisionStay2D
สั้น ๆ
คุณควรจะเห็นว่าวิธีการนี้ไม่ได้ถูกเรียกอีกต่อไปหลังจาก OnCollisionStay2D
ระยะเวลาหนึ่ง
สิ่งนี้บ่งชี้ว่าคุณได้เข้าสู่สถานะสลีปแล้ว แต่ถ้าคุณต้องการเปลี่ยนเวลาจนกว่าคุณจะเข้าสู่โหมดสลีปนี้คุณสามารถเปลี่ยนได้โดยเลือก "ฟิสิกส์ 2 มิติ" จากการตั้งค่าโครงการและระบุพารามิเตอร์ "เวลาสลีป" เป็นวินาที
ไม่สามารถตั้งค่าเป็น 0 ได้ แต่ถ้า OnCollisionStay2D
ตั้งค่าให้เล็กลงอย่างไม่มีที่สิ้นสุดวิธีการนั้นจะไม่ถูกเรียก