unity tutorial hacer desplegable crear como c# unity3d unity3d-ui

c# - tutorial - unity 3d ui



UI de Unity3D, cálculo de posición arrastrando un elemento? (3)

En primer lugar, todas las otras respuestas en esta publicación están funcionando muy bien. Trabajé en esto durante tanto tiempo y solo quería publicarlo aquí. Agrega una forma de evitar que otros objetos de IU no deseados sean arrastrados.

Mi objetivo oficial era proporcionar una forma de hacer esto sin usar bool beingDragged = false; . Simplemente no sabrá qué Button o Image se está arrastrando si lo hace así.

Arrastrando la IU :

Convierta Screenpoint a punto local en RectTransform con la ayuda de RectTransformUtility luego use Canvas.transform.TransformPoint para averiguar dónde está exactamente la interfaz de usuario secundaria.

public Canvas parentCanvasOfImageToMove; Vector2 pos; RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvasOfImageToMove.transform as RectTransform, eventData.position, parentCanvasOfImageToMove.worldCamera, out pos); UIToMove.transform.position = parentCanvasOfImageToMove.transform.TransformPoint(pos);

El código de arrastre parece más complicado que otro código de arrastre en otras respuestas, pero parece estar funcionando en todos los modos de cámara Canvas.

Detectar qué objeto está a punto de ser arrastrado :

La forma más fácil de hacerlo es crear una variable global que pueda usar para guardar qué objeto desea arrastrar el usuario en la función OnBeginDrag , luego puede arrastrar ese objeto en OnDrag . Establezca ese objeto en nulo cuando se llama a OnEndDrag .

objectToBeDragged = eventData.pointerCurrentRaycast.gameObject;

Esto debe hacerse una vez en la función OnBeginDrag luego guardarse en una variable global.

No puede hacer lo siguiente en la función OnDrag

if (eventData.pointerCurrentRaycast.gameObject == someOtherUI) { someOtherUI....drag }

Aunque se supone que funciona, a veces no lo hace. Incluso devuelve nulo a veces durante OnDrag . Es por eso que debe hacerse en la función OnBeginDrag .

Detectar y arrastrar la imagen del botón Vs :

Detectar si la interfaz de usuario es solo una Image y arrastrar una Image es muy fácil.

objectToBeDragged = eventData.pointerCurrentRaycast.gameObject; Button tempButton = objectToBeDragged.GetComponent<Button>(); Image tempImage = objectToBeDragged.GetComponent<Image>();

Si tempImage no es null y tempButton es null entonces esa es una imagen.

Detectar si la interfaz de usuario es solo un Button y arrastrar un Button NO es fácil. Cuando se hace clic en un botón en el lateral / borde , se devuelve el nombre del Button lo cual está bien. Pero la mayoría de las veces, un clic en un Button ocurre en el medio del Button que no devuelve la instancia o el nombre del botón, sino que devuelve el Text (objeto secundario). NO PUEDE mover un texto como un botón. No funcionará

objectToBeDragged = eventData.pointerCurrentRaycast.gameObject; Button tempButton = objectToBeDragged.GetComponent<Button>(); Image tempImage = objectToBeDragged.GetComponent<Image>(); Text tempText = objectToBeDragged.GetComponent<Text>();

si tempText no es nulo, obtenga el GetComponentInParent of Image and Button del texto. Si la Image no es nula y el Button no es nulo, entonces es un Button .

if (tempText != null) { tempButton = tempText.GetComponentInParent<Button>(); tempImage = tempText.GetComponentInParent<Image>(); if (tempButton != null && tempImage != null) { //This is a Button } }

A continuación se muestra la secuencia de comandos completa de arrastrar la imagen / panel de UI y el botón. Cualquier botón que deba arrastrarse debe colocarse en la matriz UIButtons y cualquier Panel / Imagen que deba arrastrarse debe colocarse en la matriz UIPanels . Ignorará otras IU que no están en la matriz.

public class UIDRAGGER : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public Canvas parentCanvasOfImageToMove; //10 UI Buttons (Assign in Editor) public Button[] UIButtons; //2 UI Panels/Images (Assign in Editor) public Image[] UIPanels; //Hold which Button or Image is selected private Button selectedButton; private Image selectedUIPanels; //Used to make sure that the UI is position exactly where mouse was clicked intead of the default center of the UI Vector3 moveOffset; //Used to decide which mode we are in. Button Drag or Image/Panel Mode private DragType dragType = DragType.NONE; void Start() { parentCanvasOfImageToMove = gameObject.GetComponent<Canvas>(); } //Checks if the Button passed in is in the array bool buttonIsAvailableInArray(Button button) { bool _isAValidButton = false; for (int i = 0; i < UIButtons.Length; i++) { if (UIButtons[i] == button) { _isAValidButton = true; break; } } return _isAValidButton; } //Checks if the Panel/Image passed in is in the array bool imageIsAvailableInArray(Image image) { bool _isAValidImage = false; for (int i = 0; i < UIPanels.Length; i++) { if (UIPanels[i] == image) { _isAValidImage = true; break; } } return _isAValidImage; } void selectButton(Button button, Vector3 currentPos) { //check if it is in the image array that is allowed to be moved if (buttonIsAvailableInArray(button)) { //Make the image the current selected image selectedButton = button; dragType = DragType.BUTTONS; moveOffset = selectedButton.transform.position - currentPos; } else { //Clear the selected Button selectedButton = null; dragType = DragType.NONE; } } void selectImage(Image image, Vector3 currentPos) { //check if it is in the image array that is allowed to be moved if (imageIsAvailableInArray(image)) { //Make the image the current selected image selectedUIPanels = image; dragType = DragType.IMAGES; moveOffset = selectedUIPanels.transform.position - currentPos; } else { //Clear the selected Button selectedUIPanels = null; dragType = DragType.NONE; } } public void OnBeginDrag(PointerEventData eventData) { GameObject tempObj = eventData.pointerCurrentRaycast.gameObject; if (tempObj == null) { return; } Button tempButton = tempObj.GetComponent<Button>(); Image tempImage = tempObj.GetComponent<Image>(); Text tempText = tempObj.GetComponent<Text>(); //For Offeset Position Vector2 pos; RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvasOfImageToMove.transform as RectTransform, eventData.position, parentCanvasOfImageToMove.worldCamera, out pos); //Button must contain Text then Image and Button as parant //Check if this is an image if (tempButton == null || tempImage == null) { //Button not detected. Check if Button''s text was detected if (tempText != null) { //Text detected. Now Look for Button and Image in the text''s parent Object tempButton = tempText.GetComponentInParent<Button>(); tempImage = tempText.GetComponentInParent<Image>(); //Since child is text, check if parents are Button and Image if (tempButton != null && tempImage != null) { //This is a Button selectButton(tempButton, parentCanvasOfImageToMove.transform.TransformPoint(pos)); } //Check if there is just an image else if (tempImage != null) { //This is an Image selectImage(tempImage, parentCanvasOfImageToMove.transform.TransformPoint(pos)); } } else { //This is an Image selectImage(tempImage, parentCanvasOfImageToMove.transform.TransformPoint(pos)); } } //Check if there is just an image else if (tempImage != null) { selectImage(tempImage, parentCanvasOfImageToMove.transform.TransformPoint(pos)); } } public void OnDrag(PointerEventData eventData) { Vector2 pos; if (dragType == DragType.BUTTONS) { RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvasOfImageToMove.transform as RectTransform, eventData.position, parentCanvasOfImageToMove.worldCamera, out pos); selectedButton.transform.position = parentCanvasOfImageToMove.transform.TransformPoint(pos) + moveOffset; } else if (dragType == DragType.IMAGES) { RectTransformUtility.ScreenPointToLocalPointInRectangle(parentCanvasOfImageToMove.transform as RectTransform, eventData.position, parentCanvasOfImageToMove.worldCamera, out pos); selectedUIPanels.transform.position = parentCanvasOfImageToMove.transform.TransformPoint(pos) + moveOffset; } } public void OnEndDrag(PointerEventData eventData) { //Buttons if (dragType == DragType.BUTTONS || dragType == DragType.IMAGES) { selectedButton = null; selectedUIPanels = null; dragType = DragType.NONE; } } DragType getCurrentDragType() { return dragType; } private enum DragType { NONE, BUTTONS, IMAGES }; }

En estos días es increíblemente fácil arrastrar elementos de la interfaz de usuario en Unity: crea algunos elementos de la interfaz de usuario. Agregar componente -> Evento -> Activador de eventos . Suelta el guión a continuación. Haga clic para agregar los cuatro desencadenantes obvios. Ya terminaste

Sin embargo.

Estoy totalmente perdido en la relación entre las coordenadas del puntero y las coordenadas de la interfaz de usuario (como se ve en RectTransform, etc.).

En DragIt continuación: ¿cómo diablos mueves un panel de interfaz de usuario correctamente debajo del dedo?

Digamos que tiene un panel grande, con diez UIButton sentado en el panel con Dragster en los botones. ¿Cuál es la relación entre las coordenadas RectTransform y el puntero del mouse ...

en resumen, ¿cómo mueve uno de los botones en DragIt () a continuación?

/* modern Unity drag of UI element */ using UnityEngine; using UnityEngine.UI; using UnityEngine.Events; using UnityEngine.EventSystems; public class Dragster:MonoBehaviour { public int index; // number each of your UI items static bool beingDragged = false; static int dragFrom; public void DragStart() { beingDragged = true; dragFrom = index; } public void DragIt() { ? ? W T F ? ? } public void DragEnd() { beingDragged = false; } public void DroppedBra() { Debig.Log("Drag: from/to " +dragFrom +" --> " +index); } }


Haría que tu script implemente las interfaces de arrastre

public class Dragster:MonoBehaviour,IBeginDragHandler, IEndDragHandler, IDragHandler

Lo que hará que su función DragIt convierta

public void OnDrag(PointerEventData eventData) { transform.position += (Vector3)eventData.delta; }

dándole acceso al delta de ese evento (cuánto se ha movido el mouse) para poder mover su objeto.

Si aún prefiere usar el componente EventTrigger (forma menos preferida), solo necesita cambiar su función DragIt a DragIt(PointerEventData eventData) y usar la opción Dynamic EvenData en el menú desplegable para que el activador reciba el PointerEventData para acceder al delta información

Aquí hay una solución total y completa para arrastrar y soltar elementos ''UnityEngine.UI`, basado en el código de Uri & Colton. Solo copia y pega.

Asombroso copiar y pegar sin complicaciones, arrastrar y soltar perfecto para Unity UI, wtt Colton y Uri:

using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class UNCDraggable:MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler { public Image ghost; // note DON''T try to drag the actual item: it''s not worth the hassle. // a problem arises where you can''t have it on top (as you would want // visually), and still easily get the drops. always use a ghost. // even if you want the "original invisible" while dragging, // simply hide it and use a ghost. everything is tremendously // easier if you do not move the originals. void Awake() { ghost.raycastTarget = false; // (just in case you forgot to do that in the Editor) ghost.enabled = false; } public void OnBeginDrag(PointerEventData eventData) { ghost.transform.position = transform.position; ghost.enabled = true; } public void OnDrag(PointerEventData eventData) { ghost.transform.position += (Vector3)eventData.delta; } public void OnEndDrag(PointerEventData eventData) { ghost.enabled = false; } public void OnDrop(PointerEventData data) { GameObject fromItem = data.pointerDrag; if (data.pointerDrag == null) return; // (will never happen) UNCDraggable d = fromItem.GetComponent<UNCDraggable>(); if (d == null) { // means something unrelated to our system was dragged from. // for example, just an unrelated scrolling area, etc. // simply completely ignore these. return; // note, if very unusually you have more than one "system" // of UNCDraggable items on the same screen, be careful to // distinguish them! Example solution, check parents are same. } Debug.Log ("dropped " + fromItem.name +" onto " +gameObject.name); // your code would look probably like this: YourThings fromThing = fromItem.GetComponent<YourButtons>().info; YourThings untoThing = gameObject.GetComponent<YourButtons>().info; yourBossyObject.dragHappenedFromTo(fromThing, untoThing); } }


Para dragar cosas solo hago esto:

using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public void OnBeginDrag(PointerEventData eventData) { } public void OnDrag(PointerEventData eventData) { //Debug.Log ("OnDrag"); this.transform.position = eventData.position; } public void OnEndDrag(PointerEventData eventData) { Debug.Log ("OnEndDrag"); } }