Apa yang saya coba pahami dan pelajari di sini adalah hal yang sangat mendasar: apa cara yang paling umum dan paling halus untuk membedakan dengan benar klik tunggal dan klik ganda untuk 3 tombol mouse utama di Unity, menggunakan C #?
Penekanan saya pada kata dengan benar bukan untuk apa-apa. Meskipun saya terkejut bahwa ini sepertinya belum pernah ditanyakan di situs web ini sebelumnya, tentu saja saya telah mencari dan menemukan banyak pertanyaan serupa di forum Unity dan halaman tanya jawab sendiri. Namun, seperti yang sering terjadi dengan jawaban yang diposting di sumber daya ini, mereka semua tampaknya salah atau paling tidak terlalu amatir.
Biarkan saya jelaskan. Solusi yang diajukan selalu memiliki salah satu dari dua pendekatan dan kelemahan yang sesuai:
- setiap kali klik terjadi, hitung delta waktu sejak klik terakhir dan jika lebih kecil dari ambang yang diberikan, klik ganda akan terdeteksi. Namun, solusi ini menghasilkan klik cepat yang terdeteksi sebelum klik dua kali terdeteksi, yang tidak diinginkan di sebagian besar situasi karena kemudian mengaktifkan tindakan klik tunggal dan ganda.
Contoh kasar:
float dclick_threshold = 0.25f;
double timerdclick = 0;
if (Input.GetMouseButtonDown(0)
{
if (Time.time - timerdclick) > dclick_threshold)
{
Debug.Log("single click");
//call the SingleClick() function, not shown
} else {
Debug.Log("double click");
//call the DoubleClick() function, not shown
}
timerdclick = Time.time;
}
- menetapkan penundaan waktu tunggu untuk klik tunggal yang akan diaktifkan, yang berarti, pada setiap klik, hanya mengaktifkan tindakan klik tunggal jika penundaan waktu sejak klik terakhir di atas ambang yang diberikan. Namun, ini memberikan hasil yang lamban, karena menunggu sebelum dimungkinkan untuk melihat menunggu sebelum satu klik terdeteksi. Lebih buruk dari itu, solusi semacam ini menderita ketidaksesuaian antar mesin, karena tidak memperhitungkan seberapa lambat atau seberapa cepat pengaturan kecepatan klik dua kali pengguna pada level OS.
Contoh kasar:
float one_click = false;
float dclick_threshold = 0.25f;
double timerdclick = 0;
if (one_click && ((Time.time - timerdclick) > dclick_threshold))
{
Debug.Log("single click");
//call the SingleClick() function, not shown
one_click = false;
}
if (Input.GetMouseButtonDown(0))
{
if (!one_click)
{
dclick = -1;
timerdclick = Time.time;
one_click = true;
}
else if (one_click && ((Time.time - timerdclick) < dclick_threshold))
{
Debug.Log("double click");
//call the DoubleClick() function, not shown
one_click = false;
}
}
Karena itu, pertanyaan saya menjadi sebagai berikut. Apakah ada cara yang lebih halus dan dapat diandalkan untuk mendeteksi klik ganda di Unity menggunakan C #, selain solusi ini, dan yang menangani masalah yang disebutkan di atas?
Jawaban:
Coroutine menyenangkan:
sumber
Saya tidak bisa membaca bahasa Inggris. Tetapi UniRx mungkin dapat membantu Anda.
https://github.com/neuecc/UniRx#introduction
sumber
Control Panel → Mouse
.Penundaan klik ganda standar Windows adalah 500ms = 0,5 detik.
Secara umum dalam gim, lebih mudah menangani klik dua kali pada kontrol yang diklik, bukan secara global. Jika Anda memutuskan untuk menangani klik ganda secara global, Anda harus menerapkan solusi untuk menghindari 2 efek samping yang sangat tidak diinginkan:
Jika Anda harus menggunakan implementasi global, Anda harus melihat lokasi klik juga - jika mouse bergerak terlalu jauh itu bukan klik ganda. Anda biasanya akan menerapkan pelacak fokus yang mereset penghitung klik dua kali setiap kali fokus berubah.
Untuk pertanyaan apakah Anda harus menunggu hingga batas waktu klik dua kali berlalu, ini perlu ditangani secara berbeda untuk setiap kontrol. Anda memiliki 4 acara berbeda:
Jika memungkinkan, Anda mencoba mendesain interaksi GUI sedemikian rupa sehingga acara terakhir tidak akan digunakan: Windows File Explorer akan memilih item pada satu klik segera, dan akan membukanya pada klik ganda, dan tidak akan melakukan apa pun pada single yang dikonfirmasi klik.
Dengan kata lain: Anda menggunakan kedua opsi yang Anda sarankan, tergantung pada apa perilaku kontrol yang diinginkan.
sumber
Solusi di atas berfungsi untuk klik yang dilakukan di seluruh layar. Jika Anda ingin mendeteksi klik dua kali pada masing-masing tombol, saya menemukan modifikasi ini untuk jawaban di atas berfungsi dengan baik:
Lampirkan skrip ini ke tombol sebanyak yang Anda inginkan. Kemudian di bagian On Click editor (untuk setiap tombol yang Anda lampirkan ini), klik '+', tambahkan tombol itu sendiri sebagai objek game, dan kemudian pilih "DoubleClickTest -> startClick () 'sebagai fungsi untuk memanggil ketika tombol ditekan.
sumber
Saya sedang mencari penangan klik satu-dua yang tepat. Saya telah menemukan topik ini dan mengumpulkan beberapa ide yang sangat bagus. Jadi akhirnya saya datang dengan solusi berikut dan saya ingin membaginya dengan Anda. Saya harap Anda menemukan metode ini bermanfaat.
Saya pikir ini adalah pendekatan yang bagus untuk menggunakan inspektur Unity, karena dengan cara ini kode Anda lebih fleksibel karena Anda dapat mereferensikan objek permainan Anda secara visual dan aman.
Pertama-tama tambahkan komponen Sistem Acara ke salah satu objek game Anda. Ini juga akan menambahkan komponen Modul Input Mandiri . Ini akan menangani acara input seperti klik dan sentuhan mouse. Saya merekomendasikan untuk melakukan ini pada objek game individual.
Selanjutnya tambahkan komponen Event Trigger ke salah satu objek game yang diaktifkan raycast Anda . Seperti elemen UI atau sprite, objek 3D dengan collider . Ini akan mengirimkan acara klik ke skrip kami. Tambahkan Pointer Click event type dan atur objek game penerima yang memiliki komponen skrip Click Controller di atasnya dan akhirnya pilih metode onClick () -nya . (Anda juga dapat mengubah skrip untuk menerima semua klik dalam Pembaruan () dan lewati langkah ini.)
Jadi objek game penerima, yang tentu saja dapat menjadi pemicu acara, akan melakukan apa saja dengan peristiwa klik tunggal atau doudle.
Anda dapat mengatur batas waktu untuk klik dua kali, tombol yang diinginkan dan acara khusus untuk klik tunggal dan ganda. Satu-satunya batasan adalah Anda hanya dapat memilih satu tombol pada satu waktu untuk satu objek game .
Script itu sendiri memulai coroutine pada setiap klik pertama dengan dua timer. The FirstClickTime dan currentTime di sinkronkan dengan yang pertama.
Coroutine ini berputar sekali pada akhir setiap frame hingga batas waktu berakhir. Sementara itu metode onClick () terus menghitung klik.
Ketika batas waktu kedaluwarsa itu memanggil acara satu atau dua kali klik sesuai dengan clickCounter. Kemudian ia menetapkan penghitung ini ke nol sehingga coroutine dapat selesai dan seluruh proses dimulai dari awal.
sumber
Saya pikir tidak ada cara untuk membaca pikiran pengguna baik dia akan mengklik tunggal atau ganda, setelah semua kita harus menunggu input. Meskipun Anda dapat mengatur menunggu 0,01 detik (serendah) untuk klik kedua. Dalam hal ini saya akan memilih opsi menunggu.
Dan YA
Coroutines
menyenangkan ...Sebuah alternatif
sumber