Unity new UI - Secara dinamis mengubah fungsi yang disebut oleh elemen GUI

17

Mencari untuk secara dinamis mengubah nilai pada tombol OnClick dan slider On Value Changed Contoh 1 contoh 2.

Jika saya harus menebak bagaimana hal ini dilakukan, dapatkan referensi ke elemen tombol / gui. Selanjutnya dapatkan komponen skrip Tombol dan akses daftar panggilan fungsi tersebut. Namun saya tidak yakin bagaimana mengubah daftar itu. Adakah yang punya ide?

Lebih detail yang mungkin membantu:

  • Fungsi yang dipanggil terpisah dari komponen skrip khusus
  • Menggunakan opsi variabel 'dinamis' untuk bilah geser
  • Dapat digunakan untuk membuat tombol dinamis
sampai jumpa
sumber

Jawaban:

23

Ada cara super sederhana untuk mengubah acara:

EDIT

Lihat jawaban saya yang lain untuk cara cepat dan mudah menambahkan acara hanya untuk OnClickacara tersebut. Untuk acara lain, seperti OnDraglihat di bawah.


Selain itu, jika Anda membutuhkan lebih dari sekadar acara yang disediakan secara default, saya sarankan sebagai gantinya melampirkan EventTriggerobjek game Anda. Ini memberi kami akses ke BaseEventDataobjek yang dikembalikan dari acara, memberi tahu kami hal-hal seperti objek yang membuat acara. Maka Anda dapat melakukan sesuatu seperti:

//Create an event delegate that will be used for creating methods that respond to events
public delegate void EventDelegate(UnityEngine.EventSystems.BaseEventData baseEvent);

Kemudian kita dapat membuat metode untuk menangani acara, tanda tangan harus cocok dengan delegasi kami. Jadi, perlu kembali voiddan menerima BaseEventDatasebagai parameter pertama dan satu-satunya:

public void DropEventMethod(UnityEngine.EventSystems.BaseEventData baseEvent) {
    Debug.Log(baseEvent.selectedObject.name + " triggered an event!");
    //baseEvent.selectedObject is the GameObject that triggered the event,
    // so we can access its components, destroy it, or do whatever.
}

Akhirnya, untuk menambahkan acara secara dinamis:

//Get the event trigger attached to the UI object
EventTrigger eventTrigger = buttonObject.GetComponent<EventTrigger>();

//Create a new entry. This entry will describe the kind of event we're looking for
// and how to respond to it
EventTrigger.Entry entry = new EventTrigger.Entry();

//This event will respond to a drop event
entry.eventID = EventTriggerType.Drop;

//Create a new trigger to hold our callback methods
entry.callback = new EventTrigger.TriggerEvent();

//Create a new UnityAction, it contains our DropEventMethod delegate to respond to events
UnityEngine.Events.UnityAction<BaseEventData> callback =
    new UnityEngine.Events.UnityAction<BaseEventData>(DropEventMethod);

//Add our callback to the listeners
entry.callback.AddListener(callback);

//Add the EventTrigger entry to the event trigger component
eventTrigger.delegates.Add(entry);

Jika Anda menggunakan versi 5.3.3 atau lebih tinggi, gunakan baris ini sebagai ganti baris terakhir di atas, delegasi disusutkan :

eventTrigger.triggers.Add(entry); 
MichaelHouse
sumber
Tampaknya ketika Anda menambahkan handler secara dinamis, tampaknya tidak muncul di inspektur. Laci masih menampilkan "Daftar kosong" untuk para delegasi
vexe
Itu benar. Penangan yang ditambahkan dari kode terpisah dari penangan "persisten" yang diperlihatkan dalam inspektur; Selain itu, Anda bertanggung jawab untuk membersihkan penangan-penangan ini (tidak seperti yang persisten, yang ditangani Unity untuk Anda).
Joe Strout
11

Kata itu adalah bahwa delegate{}sintaks yang ditemukan dalam jawaban saya sebelumnya sudah usang, ada cara lain untuk melakukan ini menggunakan notasi lambda:

void buttonSetup(Button button) {
    //Remove the existing events
    button.onClick.RemoveAllListeners();
    //Add your new event using lambda notation
    button.onClick.AddListener (handleButton);
}

void handleButton() {
    Debug.Log("Button pressed!");
}

Atau Anda dapat melewati tombol untuk membuat hal-hal sedikit lebih dinamis:

void buttonSetup(Button button) {
    button.onClick.RemoveAllListeners();
    //Add your new event
    button.onClick.AddListener(() => handleButton(button));
}

void handleButton(Button b) {
    Debug.Log("Button '" + b.name + "' pressed!");
}
MichaelHouse
sumber
Perlu diingat, strategi ini hanya untuk OnClickacara. Untuk menambahkan acara lain secara dinamis, Anda harus mengikuti instruksi di jawaban saya yang lain.
MichaelHouse
0

Buat skrip baru, di sepanjang baris:

public class EventHandler : MonoBehaviour, IPointerClickHandler
{
    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("Element: " +
                   eventData.selectedObject.name +
                   " was clicked at " +
                   eventData.position.ToString());
    }
}

Script ini mengimplementasikan antarmuka IPointerClickHandler (di antara banyak antarmuka lain yang tersedia ). Cukup dengan melampirkan skrip ini ke elemen UI akan memungkinkan skrip ini untuk mencegat acara klik (atau acara apa pun yang Anda implementasikan untuk antarmuka).

Langkah selanjutnya adalah menambahkan skrip ini secara dinamis sebagai komponen ke elemen UI yang Anda inginkan:

myButton.AddComponent<EventHandler>();

Ini akan menambahkan skrip sebagai komponen myButton dan pada saat saya mengklik tombol, saya akan mendapatkan informasi tentang tombol mana yang diklik, dan di mana klik itu terjadi.

Ini memberikan informasi paling banyak tentang acara tersebut dibandingkan dengan jawaban saya yang lain.

MichaelHouse
sumber
0

Bagaimana unity mengimplementasikan UI sama seperti komponen unity lainnya. Anda menambahkan GameObject dan melampirkan komponen UI ke dalamnya. Setelah Anda memiliki objek game, Anda bisa mendapatkan komponen UI darinya dan mengubah propertinya.

Referensi API untuk UI dapat ditemukan di bawah namespace UnityEngine.UI, referensi API untuk BUtton adalah http://docs.unity3d.com/ScriptReference/UI.Button.html

Lihat posting http://blog.trsquarelab.com/2015/03/new-ui-implementation-using-c-scripts.html untuk informasi lebih lanjut tentang mengakses UI dari skrip C #

Ranjith
sumber