Seite 1 von 1

Unity - Drag and Drop

Verfasst: 30.05.2018, 21:06
von Raven280438
Hi,

Ich habe ein kleines Inventar-Fenster gebaut. Darin wird in einem Scrollrect Verschiedene Panels angezeigt, die mein Intentar repräsentieren.
Jedem Slot haben ich ein Skript hinzugefügt, dass die Item-Informationen enthält.
Jetzt möchte ich die ganze Sache per Drag&Drop erweitern.

Code: Alles auswählen

public class ItemSlotData : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
        public Item item { get; set; }
        public int amount { get; set; }

        void Awake()
        {
            this.item = null;
            this.amount = 0;
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            Debug.Log("DRAG START");
        }

        public void OnDrag(PointerEventData eventData)
        {
            throw new System.NotImplementedException();
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            throw new System.NotImplementedException();
        }
    }
Die OnBeginDrag-Methode wird aber nicht ausgeführt. Woran liegt das? Liegt es daran, dass die einzelnen Slots sich in einem ScrollRect befinden?



Gruß

Re: Unity - Drag and Drop

Verfasst: 01.06.2018, 09:08
von nerem
Hallo,

ich habe das ganze kurz ausprobiert, und bei mir funktioniert das tadellos. Ich habe die Exceptions mal rausgenommen und hier ebenfalls Debug.Logs verwendet:

Code: Alles auswählen

using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine;

public class ItemSlotData : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
	public int item { get; set; }
	public int amount { get; set; }

	void Awake()
	{
		this.item = 0;
		this.amount = 0;
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		Debug.Log("DRAG START");
	}

	public void OnDrag(PointerEventData eventData)
	{
		Debug.Log("DRAGGING");
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		Debug.Log("END DRAG");
	}
}
Tut absolut, auch in einem Scrollview (ich nehme an, das meinst du mit Scrollrect?). Zu beachten ist höchstens, dass nach OnBeginDrag sofort und ständig OnDrag aufgerufen wird, d.h. ich musste in meinem Log ziemlich weit nach oben scrollen, um die OnBeginDrag Meldung zu sehen. Kann es sein, dass du das einfach übersehen hast?

Re: Unity - Drag and Drop

Verfasst: 01.06.2018, 11:42
von Raven280438
Hi,

danke für die Antwort.

Dann muss irgendwas Anderes falsch sein.
Könnte es sein, dass es Probleme gibt weil ich die einzelnen Slot-Panels in einer Schleife (insgesamt 96 Panels) im Programm-Code erzeuge?

Was Anderes fällt mir nicht ein...


Gruß

Re: Unity - Drag and Drop

Verfasst: 01.06.2018, 14:45
von nerem
Hey,

auch das Erzeugen von den DragSlots im Code habe ich jetzt mal versucht, und das klappt bei mir genauso. Da ich jetzt nicht genau weiß, was du machst und warum es eventuell Probleme gibt, habe ich das Miniprojekt mal kurz auf GITHUB gestellt:

https://github.com/nerem/DragTest

Ein einfaches Programm, bei dem man mit einem Button weitere DragSlots innerhalb des ScrollViews hinzufügen kann und die allesamt, wie gewünscht, draggable sind.

Ich hoffe, das hilft dir weiter.

Liebe Grüße
Felix

Re: Unity - Drag and Drop

Verfasst: 01.06.2018, 19:47
von Raven280438
Hi,

danke für dein Beispiel, ich hab mein Script etwas umgebaut und jetzt gehn die D&D Events.

Ein weiteres Problem ist aber, dass der Viewport des ScrollRect eine Mask hat.
Das führt dazu, dass die Icons beim Drag&Drop mit unter verschwinden.

Kann man das noch irgendwie umgehn?


Gruß

Re: Unity - Drag and Drop

Verfasst: 03.06.2018, 15:30
von nerem
Hey,

mir ist jetzt nicht ganz klar, was du mit verschwinden meinst. Was verschwindet wann wie wohin? Kannst du das Problem bitte etwas genauer beschreiben? Ich weiß gerade schlicht nicht, was du meinst ;-)

Liebe Grüße
Felix

Re: Unity - Drag and Drop

Verfasst: 03.06.2018, 16:10
von Raven280438
Hi,

also dadurch, dass das Panel in dem das Scrollrect drin ist eine Mask hat, also nicht komplett angezeigt wird, verschwinden die Panels beim Drag&Drop auch falls ich sie aus dem Panel rausziehe.
Ich möchte sie aber auch gerne zB in ein anderes Fenster verschieben (zB ins Charakter/Ausrüstungsfenster).

Gruß

Re: Unity - Drag and Drop

Verfasst: 03.06.2018, 17:02
von Raven280438
Hi,

ich hab jetzt ein bisschen rumgespielt.

Code: Alles auswählen

  public void OnBeginDrag(PointerEventData eventData)
          {
                Destroy(this.DragImage);
                if (this.item != null)
                {
                  Image img = this.transform.Find("Item").GetComponent<Image>();
                  if (img != null)
                  {
                    this.DragImage = Instantiate(this.transform.parent.Find("DragDrop").gameObject);
                    this.DragImage.SetActive(true);
                    this.DragImage.GetComponent<Image>().sprite = this.item.Sprite;
                    this.DragImage.GetComponent<Image>().color = new Color(1, 1, 1, 1);
                    this.DragImage.transform.position = Input.mousePosition;
                }
            }
        }

        public void OnDrag(PointerEventData eventData)
        {
            
            if (this.DragImage != null)
            {
                this.DragImage.transform.position = Input.mousePosition;
            }
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            Destroy(this.DragImage);
        }
Das DragImage Objekt wird richtig erstellt. Allerdings wird es mir nicht angezeigt. Die Koordinaten sollten aber richtig sein.
Eigendlich sollte das Image doch immer am Mauszeiger angezeigt werden, oder?


Gruß

Re: Unity - Drag and Drop

Verfasst: 03.06.2018, 20:35
von Raven280438
Hi,

hab den Fehler gefunden ;)

Ich musste den Parent auf die Canvas setzen.


Gruß

Re: Unity - Drag and Drop

Verfasst: 04.06.2018, 09:56
von nerem
Und hat sich das mit dem verschieben in andere Fenster auch erledigt? Ansonsten probiere ich das heute Abend eventuell aus. Noch ein Tipp: Wenn du hier im Forum Code reinpackst und den "

Code: Alles auswählen

" Tag durch "[code=cs]" ersetzt, gehen die Einrückungen nicht verloren.

LG
Felix

Re: Unity - Drag and Drop

Verfasst: 04.06.2018, 10:13
von Raven280438
Hi,

ja, das Problem hat sich erledigt.
Wenn ich als Parent die Canvas angeben, kann ich es überall hin verschieben.

Vielen Dank für die Hilfe.


Gruß

Re: Unity - Drag and Drop

Verfasst: 04.06.2018, 14:30
von nerem
Alles klar, sehr gerne :)

Re: Unity - Drag and Drop

Verfasst: 05.06.2018, 21:23
von Raven280438
Hi,

ich hab noch ein Problem.

Hier erstmal mein Drag&Drop Skript

Code: Alles auswählen

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

    public class ItemSlotData : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler
    {
        public Item item { get; set; }
        public int amount { get; set; }
        public int SlotID { get; set; }
        private GameObject DragImage { get; set; } 

        void Awake()
        {
            this.item = null;
            this.amount = 0;
            this.SlotID = 0;
            this.DragImage = null;
        }

        public void FillData(Item item, int amount, int slotid)
        {
            this.item = item;
            this.amount = amount;
            this.SlotID = slotid;
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            Destroy(this.DragImage);
            if (this.item != null)
            {
                Image img = this.transform.Find("Item").GetComponent<Image>();
                if (img != null)
                {
                    this.DragImage = Instantiate(this.transform.parent.Find("DragDrop").gameObject);
                    this.DragImage.transform.SetParent(GameObject.Find("GUI/Canvas").transform);
                    this.DragImage.SetActive(true);
                    this.DragImage.GetComponent<Image>().sprite = this.item.Sprite;
                    this.DragImage.GetComponent<Image>().color = new Color(1, 1, 1, 1);
                    this.DragImage.transform.position = eventData.position;
                    Debug.Log(this.DragImage);
                    try
                    {
                        this.DragImage.GetComponent<ItemSlotData>().FillData(this.item, this.amount, this.SlotID);
                    }
                    catch { };
                }
            }
        }

        public void OnDrag(PointerEventData eventData)
        {
            if (this.DragImage != null)
            {
                this.DragImage.transform.position = eventData.position;
            }
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            Destroy(this.DragImage);
        }

        public void OnDrop(PointerEventData eventData)
        {
            Debug.Log("BLA"+this.SlotID);
            ItemSlotData droppendItem = eventData.pointerDrag.GetComponent<ItemSlotData>();
        }
    }
Ich hab also die Drag- und Drop Routinen im selben Skript.

Eigendlich solle in der OnDrop()-Methode doch this.SlotID (der Slot wo hingezogen wird) und droppendItem.SlotID (der Slot von dem aus gezogen wurde) unterschiedlich sein.
Bei mir sind aber immer beide gleich.

Wo liegt mein Denkfehler?


PS: Ich hab grad rausgefunden, dass das DragImage wohl immer mit der Maus mitbewegt wird und deshalb dann immer das Ziel von OnDrop ist. Wie kann ich das verhindern? Kann man die DragImage irgendwie als Ziel von OnDrop verhindern?

Gruß