- Home /
Any examples of an iphone-like scrollview using unity GUI?
Note - this is now trivial with New Unity UI.
http://docs.unity3d.com/Manual/script-ScrollRect.html
panel the size of the "hole" you want to scroll through, add scrollRect, add mask. make a longer panel with your content. drag the content panel on to "Content" slot on the scrollRect. if the "hole" is the fullscreen, no need for the mask.
Historic question only:
The Unity way of doing scrollviews involves a thumb and a slider on the edges of the screen. Does anybody have a working implementation inside of Unity GUI of something similar to how the iPhone scroll views work?
I.e. I want to be able to drag inside the scroll view itself to drag the contents. Ideally with some kind of vertical/horizontal detection so the movement is constrained to one axis if the user is mostly scrolling along one axis.
Answer by fudingyu · Jun 27, 2014 at 02:54 PM
Note this also works perfectly for GUILayout.BeginScrollView, if you are using automatic layout.
public class scrollView:MonoBehaviour
{
Vector2 scrollPos;
void OnGUI() // simply an example of a long ScrollView
{
scrollPos = GUI.BeginScrollView(
new Rect(110,50,130,150),scrollPos,
new Rect(110,50,130,560),
GUIStyle.none,GUIStyle.none);
// HOORAY THOSE TWO ARGUMENTS ELIMINATE
// THE STUPID RIDICULOUS UNITY SCROLL BARS
for(int i = 0;i < 20; i++)
GUI.Box(new Rect(110,50+i*28,100,25),"xxxx_"+i);
GUI.EndScrollView ();
}
void Update() // so, make it scroll with the user's finger
{
if(Input.touchCount == 0) return;
Touch touch = Input.touches[0];
if (touch.phase == TouchPhase.Moved)
{
// simplistically, scrollPos.y += touch.deltaPosition.y;
// but that doesn't actually work
// don't forget you need the actual delta "on the glass"
// fortunately it's easy to do this...
float dt = Time.deltaTime / touch.deltaTime;
if (dt == 0 || float.IsNaN(dt) || float.IsInfinity(dt))
dt = 1.0f;
Vector2 glassDelta = touch.deltaPosition * dt;
scrollPos.y += glassDelta.y;
}
}
}
NOTE indeed you almost certainly want to eliminate the ridiculous scroll bars Unity adds to the scroll view. Fortunately that is taken care of by the two "GUIStyle.none" arguments as shown.
ALSO NOTE depending on the "feel" you want on the scroll, for me this is the most ideal approach:
private Vector2 beginFinger; // finger
private float deltaFingerY; // finger
private Vector2 beginPanel; // scrollpanel
private Vector2 latestPanel; // scrollpanel
void Update()
{
if ( Input.touchCount != 1 ) return;
touch = Input.touches[0];
if ( touch.phase == TouchPhase.Began )
{
beginFinger = touch.position;
beginPanel = scrollPos;
}
if ( touch.phase == TouchPhase.Moved )
{
Vector2 newFingerScreenPos = touch.position;
deltaFingerY = newFingerScreenPos.y - beginFinger.y;
float newY = beginPanel.y + deltaFingerY;
latestPanel = beginPanel;
latestPanel.y = newY;
scrollPos = latestPanel;
}
}
AND FINALLY NOTE you will certainly want to avoid scrolling when the user touches a (eg.) slider. Solution for that issue: http://answers.unity3d.com/questions/30842/how-to-detect-mouse-over-gui-and-guilayout-element.html (selected answer)
NOTE, I added the code to correctly make the scaling factor as per the glass. Works perfectly.
Since this has made the front page again its worth noting that the 4.6 UI makes this very easy, using a ScrollRect.
And indeed Bored, critically in 4.6 I guess Unity have brainstormed up the amazing idea you may want to know when touching a control. Imagine! http://forum.unity3d.com/threads/4-6-how-to-detect-if-any-gui-element-has-been-clicked-on.263473/ Pretty soon, you'll be able to use Unity with those new things, what are people calling them ... "touch screen devices" is it?
I translated it into unityscript if someone needs it
function OnGUI()
{
GUILayout.BeginArea(Rect(Screen.width*0.3, Screen.height*0.2, Screen.width*0.6, 500f));
scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(Screen.width*0.42), GUILayout.Height(350f));
for (var juj=0;juj<5;juj++)
{
if(GUILayout.Button(""+names[juj]+" "+lastNames[juj],dafont))
{
}
}
GUILayout.EndScrollView();
GUILayout.EndArea();
}
if(Input.touchCount == 0)return;
var touch : Touch = Input.touches[0];
if (touch.phase == TouchPhase.$$anonymous$$oved)
{
// simplistically, scrollPos.y += touch.deltaPosition.y;
// but that doesn't actually work
// don't forget you need the actual delta "on the glass"
// fortunately it's easy to do this...
var dt : float = Time.deltaTime / touch.deltaTime;
if (dt == 0 || float.IsNaN(dt) || float.IsInfinity(dt))
dt = 1.0f;
var glassDelta : Vector2 = touch.deltaPosition * dt;
scrollPosition.y += glassDelta.y;
}
Answer by echo17 · Mar 15, 2017 at 03:56 PM
For anyone reading this thread and still looking for a pre-made solution, check out EnhancedScroller on the Unity Asset Store: http://u3d.as/fXk
Your answer
Follow this Question
Related Questions
Recreating iPhone Home Screen in Unity 1 Answer
How to drag a scrollView with TouchPhase.Moved? 0 Answers
scrollview on iphone acts weird 3 Answers
iAd in Unity 1.7 1 Answer
How to detect Game Object is touched in Unity iPhone? 1 Answer