- Home /
Is there a way to scroll GUI text WITHOUT scrollbars?
Hi, guys:
I need a way to scroll text without a scroll bar for my android app, simply dragging the text with a finger on it.
The problem of scrollview is scrollbars are really thin and hard to press with a finger, that's why nobody uses them on mobile platforms. So i need a simple way to make scrollbar disappear or another GUI control that can work for this. Any workaround could fit my needs, because my app is crap if users must try 5 times to press the scrollbar in order to read the whole text.
Any help is appreciated.
There's a complete working answer here, very simple. It's only a few lines of code: http://answers.unity3d.com/questions/17347/any-examples-of-an-iphone-like-scrollview-using-un.html the selected answer by fudingyu
Answer by Bunny83 · Feb 12, 2014 at 04:29 AM
Sure, but you would have to implement the scrolling yourself. Some time ago i've posted a scrollview where you can explicitly hide the scrollbars if you need this. The scrolling is done with two nested GUI groups.
For the scolling you need to utilise the Touch input. Something like this:
//C#
int scrollFinger = -1;
Vector2 scrollPos = Vector2.zero;
Vector2 TouchScrollView(Rect aScreenRect, Vector2 aScrollPos, Rect aContentRect, ref int aFingerID)
{
aScrollPos = GUI.BeginScrollView(aScreenRect, aScrollPos, aContentRect);
foreach(Touch T in Input.touches)
{
if (T.phase == TouchPhase.Began)
{
Vector2 pos = T.GetGUIPosition();
if (aScreenRect.Contains(pos))
{
aFingerID = T.fingerId;
}
}
else if (afingerID == T.fingerId)
{
Vector2 delta = T.FixedTouchDelta();
aScrollPos.y += delta.y;
aScrollPos.x -= delta.x;
if(T.phase == TouchPhase.Ended || T.phase == TouchPhase.Canceled)
afingerID = -1;
}
}
return aScrollPos;
}
void OnGUI()
{
scrollPos = TouchScrollView(new Rect(10,10,100,100), scrollPos, new Rect(0,0,100,500), ref scrollFinger);
GUI.Label(new Rect(0,0,100,500), "Some long text to scroll");
GUI.EndScrollView();
}
For this you need those two Touch extension methods which can also be found on the wiki:
public static class GUIHelpers
{
public static Vector2 GetGUIPosition(this Touch aTouch)
{
var tmp = aTouch.position;
tmp.y = Screen.height - tmp.y;
return tmp;
}
// returns the true touch delta in pixels
public static Vector2 FixedTouchDelta(this Touch aTouch)
{
float dt = Time.deltaTime / aTouch.deltaTime;
if (dt == 0 || float.IsNaN(dt) || float.IsInfinity(dt))
dt = 1.0f;
return aTouch.deltaPosition * dt;
}
}
ps: I wrote this from scratch and should only be an example. Haven't tried this exact implementation in Unity but used a similar one quite a lot. If you want to try this one, please report back if anything doesn't work.
Thank you very much, man. I'm watching your code in you are god I have already implemented a drag function in my code for dragging and zoo$$anonymous$$g all GUI controls on my app, so when i remove the scrollbar and GUI styles of your code i think i'll be ready to go. Thank you very much again, i'll give you a thumb cause i cant give you 1000.
After a few tries on your code, using only this:
public class GUIX {
public static Vector2 BeginScrollView(Rect position, Vector2 scrollPosition, Rect contentRect) {
Rect viewArea = position;
GUI.BeginGroup(viewArea);
contentRect.x = -scrollPosition.x;
contentRect.y = -scrollPosition.y;
GUI.BeginGroup(contentRect);
return scrollPosition;
}
public static void EndScrollView() {
GUI.EndGroup();
GUI.EndGroup();
}
}
as the GUIX, because i dont need scrollbars nor styles at all, and implementing drag function based on mouseup and mousedown; i've come to delete all.
Now i'm working on your code as it is, and it works good, only had to change 2 afingerID for aFingerID. But when i change the line 7:
aScrollPos = GUI.BeginScrollView(aScreenRect, aScrollPos, aContentRect);
for the GUIX correspondent:
aScrollPos = GUIX.BeginScrollView(aScreenRect, aScrollPos, aContentRect, false, false);
the other GUI controls on my program are called in Begingroup rects, and i can´t find the problem, as both endgroups are called after the exection in every frame for OnGUI.
Again just click here for an extremely simple version of Bunn's solution, works perfectly http://answers.unity3d.com/questions/17347/any-examples-of-an-iphone-like-scrollview-using-un.html#answer-736286
Answer by Baalhug · Feb 15, 2014 at 08:58 PM
After long searches and debugging i finally found a perfect solution.
The next code will create a scrolling text without scrollbars which users can scroll by simply dragging the text, with mouse drag or touch drag. It automatically calculates the height of contenttext, so it will end dragging when end of text is reached. NOTE it is only defined the vertical drag, but the horizontal can be made easily by adding the correspondent .x functions.
Code for your GUI or window function:
public Vector2 scrollPos=Vector2.zero;
void OnGUI(){
string text1 = "A long text which will be dragged inside a smaller 'screen rect'...";
GUIcontent labeltext = new GUIContent (text1);
float textheight = GUIStyle4Label.CalcHeight(labeltext, 340f); //340f is the width of this example content label, use your own values here and in the other rects.
scrollPos = CustomScrollView(new Rect(20, 30, 340, 400), scrollPos, new Rect(0, 0, 340, textheight+20));
GUI.Label (new Rect (0, 0, 340, textheight+20), labelText, GUIStyle4Label);
GUIX.EndScrollView();
}
Function to scroll (inside your class):
Vector2 ClickScrollView(Rect aScreenRect, Vector2 aScrollPos, Rect aContentRect)
{
float difHeightRects=aContentRect.height-aScreenRect.height;
if (Event.current.type==EventType.MouseDrag){
if (aScreenRect.Contains(Event.current.mousePosition)){
if (aScrollPos.y<=difHeightRects && aScrollPos.y>=0) aScrollPos.y -= Event.current.delta.y;
if (aScrollPos.y>difHeightRects) aScrollPos.y=difHeightRects;
if (aScrollPos.y<0) aScrollPos.y=0;
}
}
aScrollPos = GUIX.BeginScrollView(aScreenRect, aScrollPos, aContentRect);
return aScrollPos;
}
Class GUIX (outside your class, but inside your script)
public class GUIX {
public static Vector2 BeginScrollView(Rect viewArea, Vector2 scrollPosition, Rect contentRect) {
GUI.BeginGroup(viewArea);
contentRect.y = -scrollPosition.y;
GUI.BeginGroup(contentRect);
return scrollPosition;
}
public static void EndScrollView() {
GUI.EndGroup();
GUI.EndGroup();
}
}
@Baalhug - I must be having a derp moment. :) I cannot get your code to work. Taking the code you provided, creating a blank Android project with an empty game object, and attaching your script to it (show below in totality), produces this: link text Which is not scrollable in any way. Additionally, when I attempt to add more labels, it shrinks the font down to a microscopic size. Can you please point me in the right direction? Thanks!
using UnityEngine;
using System.Collections;
public class ScrollingListView : $$anonymous$$onoBehaviour
{
public GUIStyle GUIStyle4Label;
public Vector2 scrollPos = Vector2.zero;
void OnGUI()
{
string text1 = "A long text which will be dragged inside a smaller 'screen rect'...";
GUIContent labelText = new GUIContent(text1);
float textheight = GUIStyle4Label.CalcHeight(labelText, 340f); //340f is the width of this example content label, use your own values here and in the other rects.
scrollPos = ClickScrollView(new Rect(20, 30, 340, 400), scrollPos, new Rect(0, 0, 340, textheight + 20));
GUI.Label(new Rect(0, 0, 340, textheight + 20), labelText, GUIStyle4Label);
GUIX.EndScrollView();
}
Vector2 ClickScrollView(Rect aScreenRect, Vector2 aScrollPos, Rect aContentRect)
{
float difHeightRects = aContentRect.height - aScreenRect.height;
if (Event.current.type == EventType.$$anonymous$$ouseDrag)
{
if (aScreenRect.Contains(Event.current.mousePosition))
{
if (aScrollPos.y <= difHeightRects && aScrollPos.y >= 0) aScrollPos.y -= Event.current.delta.y;
if (aScrollPos.y > difHeightRects) aScrollPos.y = difHeightRects;
if (aScrollPos.y < 0) aScrollPos.y = 0;
}
}
aScrollPos = GUIX.BeginScrollView(aScreenRect, aScrollPos, aContentRect);
return aScrollPos;
}
}
public class GUIX
{
public static Vector2 BeginScrollView(Rect viewArea, Vector2 scrollPosition, Rect contentRect)
{
GUI.BeginGroup(viewArea);
contentRect.y = -scrollPosition.y;
GUI.BeginGroup(contentRect);
return scrollPosition;
}
public static void EndScrollView()
{
GUI.EndGroup();
GUI.EndGroup();
}
}
Your answer
Follow this Question
Related Questions
Vertical Scrollbar GUI.Label 1 Answer
Scrollview button very small? 0 Answers
Problem with modifying scrollPosition on android 1 Answer
How to disable ScrollView dragging 4 Answers
Need help creating a scrollable text area for displaying EULA. 1 Answer