Saya mencoba meluncurkan objek pada target, mengingat posisinya, posisi targetnya, kecepatan peluncuran, dan gravitasi. Saya mengikuti formula ini dari Wikipedia :
Saya telah menyederhanakan kode dengan kemampuan terbaik saya, tetapi saya masih tidak dapat secara konsisten mencapai target. Saya hanya mempertimbangkan lintasan yang lebih tinggi, dari dua yang tersedia dari + - pilihan dalam rumus.
Adakah yang tahu apa yang saya lakukan salah?
using UnityEngine;
public class Launcher : MonoBehaviour
{
public float speed = 10.0f;
void Start()
{
Launch(GameObject.Find("Target").transform);
}
public void Launch(Transform target)
{
float angle = GetAngle(transform.position, target.position, speed, -Physics2D.gravity.y);
var forceToAdd = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * speed;
GetComponent<Rigidbody2D>().AddForce(forceToAdd, ForceMode2D.Impulse);
}
private float GetAngle(Vector2 origin, Vector2 destination, float speed, float gravity)
{
float angle = 0.0f;
//Labeling variables to match formula
float x = Mathf.Abs(destination.x - origin.x);
float y = Mathf.Abs(destination.y - origin.y);
float v = speed;
float g = gravity;
//Formula seen above
float valueToBeSquareRooted = Mathf.Pow(v, 4) - g * (g * Mathf.Pow(x, 2) + 2 * y * Mathf.Pow(v, 2));
if (valueToBeSquareRooted >= 0)
{
angle = Mathf.Atan((Mathf.Pow(v, 2) + Mathf.Sqrt(valueToBeSquareRooted)) / g * x);
}
else
{
//Destination is out of range
}
return angle;
}
}
Jawaban:
Saya agak skeptis menggunakan di
atan
sini, karena rasio singgung melesat hingga tak terbatas pada sudut tertentu, dan dapat menyebabkan kesalahan numerik (bahkan di luar undefined / bagi dengan nol case untuk pemotretan lurus ke atas / bawah).Menggunakan rumus yang dikerjakan dalam jawaban ini , kita dapat menentukan ini dalam hal waktu (awalnya tidak diketahui) untuk berdampak
T
,, menggunakan inisialspeed
dari proyektil:Anda dapat memilih T_min atau T_max (atau sesuatu di antaranya jika Anda ingin menjalankan dengan kecepatan hingga tetapi tidak harus sama dengan beberapa maksimum)
(
T_min
Adalah lintasan merah dangkal di bagian bawah, danT_max
merupakan lintasan hijau tinggi. Setiap lintasan di antara mereka layak pada beberapa kecepatan yang layak. Ketika keduanya bergabung ke lintasan kuning, objek berada di luar jangkauan.)Sekarang kami telah menghitung nilai untuk
T
, sisanya mudah:Anda dapat menggunakan kecepatan ini secara langsung (memiliki panjang yang sama
speed
dengan konstruksi), atau jika Anda benar-benar perlu mengetahui sudutnya, Anda dapat menggunakanatan2(vy, vx)
Edit: untuk menjadikan ini berlaku untuk lebih banyak kasus, inilah versi 3D:
sumber
discRoot
adalah akar kuadrat dari diskriminan , yang merupakan bagian yang muncul di bawah tanda akar kuadrat dalam rumus kuadratik .b
adalah -1 kali variabel b dalam rumus kuadratik. Sayangnya saya tidak tahu nama yang lebih deskriptif untuk itu. (Saya mengalikannya dengan -1 saat menetapkan untuk menghapus langkah-langkah selanjutnya, karena minus utama sudah dipanggang dan tidak memengaruhi kuadrat). Lihat jawaban lain untuk derivasi penuh, meskipun beberapa kotak hilang (akan segera diperbaiki)Berkat DMGregory, saya sekarang memiliki skrip ekstensi C # yang dapat digunakan untuk ini. Versi terbaru dapat ditemukan di GitHub .
sumber
Secara pribadi, saya bahkan tidak akan repot menggunakan segala jenis formula rumit.
Itu hanya menembak ke arah target. Dan jika Anda ingin mengkompensasi gravitasi, jarak, dll, setel
someSortOfMultiplier()
menjadi fungsi yang mengembalikan float yang akan mengkompensasi ketika dikalikan dengan kode di atas.sumber