Hi.
First i would like to apologies for any mistake i could make as I’m not fluent in english.
I’m recently (over a month by now) starting a new project of remaking an older game.
For this I choose to discover Unity system, so I’m pretty new to this.
What I want :
I need for my game to use a what i call “slide” panel.
I’m not sure of the words here.
It is something like the notification panel on Android : you put your finger on the top edge of the screen and swipe toward bottom to make the notification panel deploy.
I want something like that (but in a horizontal way, from left to right). This is something usual on several Androïd Apps and often serve as a configuration screen to can slide from left or right edge of the screen.
On this panel i then want to have several clickable icon.
As i said I’m new to unity universe. I’m just overreading some UI stuff and maybe I should look into using some kind of ScrollRect but with the effect it’s “scroll”/“slide” itself automatically toward right ?
Then add some childrens UI:Button with a texture if it is possible ?
As i suspect this is something already done and I don’t want to reinvent the same thing again I ask you if you have any info on this (like a tutorial of implementing such slide panel) ?
Thank you for any help you can provide.
Ok so using this tutorial on panel I managed to get my panel “dragable” along X axis only and only within screen position (to be exact up to 0.90*canvas width toward left so a 10% off my panel is still “available” on screen to drag it toward right) :
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class SpellsPanel : MonoBehaviour, IPointerDownHandler, IDragHandler
{
private Vector2 pointerOffset;
private RectTransform canvasRectTransform;
private RectTransform panelRectTransform;
void Awake()
{
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null)
{
canvasRectTransform = canvas.transform as RectTransform;
panelRectTransform = transform as RectTransform;
}
}
public void OnPointerDown(PointerEventData data)
{
panelRectTransform.SetAsLastSibling();
RectTransformUtility.ScreenPointToLocalPointInRectangle(panelRectTransform, data.position, data.pressEventCamera, out pointerOffset);
}
public void OnDrag(PointerEventData data)
{
if (panelRectTransform == null)
return;
//Vector2 pointerPostion = ClampToWindow(data);
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRectTransform, data.position, data.pressEventCamera, out localPointerPosition
))
{
Vector3 newPos = new Vector3(localPointerPosition.x - pointerOffset.x, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
//panelRectTransform.localPosition = localPointerPosition - pointerOffset;
if (newPos.x >= 0)
panelRectTransform.localPosition = new Vector3(0.0f, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
else if (newPos.x <= (-0.90f * canvasRectTransform.rect.width))
panelRectTransform.localPosition = new Vector3(-0.90f * canvasRectTransform.rect.width, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
else
panelRectTransform.localPosition = newPos;
}
}
Do you think I could go this way ? Because up to now this work only if we drag the panel with the mouse.
Is it possible to make my panel slide automatically if i reach a given threshold of dragging my panel ?
My issue here is how to make my panel move by itself, because above i was exploiting the IDragHandler system to handle drag with the mouse.
For example if I drag my panel for a distance more than 10% of canvas width to the left and then release my mouse I want my panel to folds along the X axis until it reach my given (0.90 * canvas width) fold up state.
Same on the other hand : If I drag for more than 10% of canvas width to the right from fold up state my panel deploy itself until it cover the screen.
Pointer events are passed to the object the pointer is over, so you would need to have a panel “over the top” of every other UI element to allow the slide to happen from any where on the screen with the script attached to it.
So i managed to do it manually … But i feel i reinvent something already done and don’t like my code.
Here is my code if someone want to look at it and tell me some improvement (I especially don’t like my imbricated if statement of onPointerUp() method) :
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class SpellsPanel : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
private Vector2 pointerOffset;
private Vector2 pointerDownPosition;
private float threshold, panelSpeed;
private RectTransform canvasRectTransform;
private RectTransform panelRectTransform;
private bool onDeploy, onFold = false;
public bool isDeployed = false;
public bool isFolded = true;
void Awake()
{
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null)
{
canvasRectTransform = canvas.transform as RectTransform;
panelRectTransform = transform as RectTransform;
}
}
void Start()
{
panelSpeed = canvasRectTransform.rect.width * 0.025f;
threshold = canvasRectTransform.rect.width * 0.10f;
panelRectTransform.localPosition = new Vector3(-0.90f * canvasRectTransform.rect.width, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
}
void Update()
{
if (onDeploy)
{
//ON DEPLOIE !
if (panelRectTransform.localPosition.x < 0)
panelRectTransform.localPosition += (panelSpeed * new Vector3(1, 0, 0));
else
{
panelRectTransform.localPosition = new Vector3(0.0f, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
isDeployed = true;
isFolded = !isDeployed;
onDeploy = false;
onFold = false;
}
}
if (onFold)
{
//ON REPLIE !
if (panelRectTransform.localPosition.x > (-0.90f * canvasRectTransform.rect.width))
panelRectTransform.localPosition += (panelSpeed * new Vector3(-1, 0, 0));
else
{
panelRectTransform.localPosition = new Vector3(-0.90f * canvasRectTransform.rect.width, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
isFolded = true;
isDeployed = !isFolded;
onDeploy = false;
onFold = false;
}
}
}
public void OnPointerDown(PointerEventData data)
{
panelRectTransform.SetAsLastSibling();
pointerDownPosition = data.position;
RectTransformUtility.ScreenPointToLocalPointInRectangle(panelRectTransform, data.position, data.pressEventCamera, out pointerOffset);
}
public void OnPointerUp(PointerEventData data)
{
Vector2 pointerDelta = data.position - pointerDownPosition;
// si le "swipe" a parcouru une distance suffisante
if (Mathf.Abs(pointerDelta.x) > threshold)
{
// swipe vers la droite
if (pointerDelta.x > 0)
{
// on deploie le paneau si il n'est pas déjà déployé
if (!isDeployed)
{
onDeploy = true;
onFold = !onDeploy;
}
}
//swipe vers la gauche
else
{
// on replie le panneau si il n'est pas déjà replié.
if (!isFolded)
{
onFold = true;
onDeploy = !onFold;
}
}
}
else
{
// petit swipe vers la droite
if (pointerDelta.x > 0)
{
// on replie le paneau si il n'est pas déjà déployé ou si il n'était pas déjà en déploiement
if (!isDeployed)
{
onFold = !onDeploy;
onDeploy = !onFold;
}
}
//petit swipe vers la gauche
else
{
// on déploie le panneau si il n'est pas déjà replié ou si il n'était pas déjà en repli.
if (!isFolded)
{
onDeploy = !onFold;
onFold = !onDeploy;
}
}
}
}
public void OnDrag(PointerEventData data)
{
if (panelRectTransform == null)
return;
//Vector2 pointerPostion = ClampToWindow(data);
isDeployed = false;
isFolded = false;
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRectTransform, data.position, data.pressEventCamera, out localPointerPosition
))
{
Vector3 newPos = new Vector3(localPointerPosition.x - pointerOffset.x, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
//panelRectTransform.localPosition = localPointerPosition - pointerOffset;
if (newPos.x >= 0)
{
panelRectTransform.localPosition = new Vector3(0.0f, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
isDeployed = true;
//isFolded = !isDeployed;
onDeploy = false;
onFold = false;
}
else if (newPos.x <= (-0.90f * canvasRectTransform.rect.width))
{
panelRectTransform.localPosition = new Vector3(-0.90f * canvasRectTransform.rect.width, panelRectTransform.localPosition.y, panelRectTransform.localPosition.z);
isFolded = true;
//isDeployed = !isFolded;
onDeploy = false;
onFold = false;
}
else
panelRectTransform.localPosition = newPos;
}
}
}