Skip to content

Instantly share code, notes, and snippets.

@MattRix
Created August 11, 2013 20:32
Show Gist options
  • Save MattRix/6206733 to your computer and use it in GitHub Desktop.
Save MattRix/6206733 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using UnityEngine;
public class Scroller
{
public float maxDragSpeed = 20.0f; //maximum drag speed
public float edgeSquish = 60.0f; //how far to go past the end
public float edgeBounce = 0.19f; //how much force to use to bounce back
public float strongFriction = 0.75f; //used to bring it to a stop quicker
public float weakFriction = 0.87f; //used when throwing at high speed
public float slowSpeed = 3.0f; //below this speed it will be brought to a stop quickly
private bool _isDragging = false;
public Scroller()
{
}
public void StartDrag()
{
if(_isDragging) return;
_isDragging = true;
}
public void EndDrag()
{
if(!_isDragging) return;
_isDragging = false;
}
public bool CalculateScrollUpdate(ref float pos, ref float speed, float boundsMin, float boundsMax)
{
float diff = 0;
if(pos < boundsMin)
{
diff = boundsMin - pos;
}
else if(pos > boundsMax)
{
diff = boundsMax - pos;
}
if(_isDragging) //restrict the speed based on how far it's out of bounds
{
float diffEased = Mathf.Abs(diff) / edgeSquish;
speed *= Mathf.Max(0.0f,1.0f - Mathf.Sqrt(diffEased));
speed = Mathf.Clamp(speed,-maxDragSpeed,maxDragSpeed);
}
else //bring it back in from the edge with squish speed
{
if(Mathf.Abs(speed) > 0.01f || Mathf.Abs(diff) > 1.0f)
{
if(Mathf.Abs(diff) > 0.0f || Mathf.Abs(speed) < slowSpeed) //slow it down if it's out of bounds OR close to stopping
{
speed *= strongFriction;
}
else
{
speed *= weakFriction;
}
}
else //it's done moving, stahp!
{
speed = 0.0f;
//put it at the exact edge
if(pos < boundsMin)
{
pos = boundsMin;
}
else if(pos > boundsMax)
{
pos = boundsMax;
}
return false; //it's not moving anymore!
}
pos += speed + diff * edgeBounce;
}
return true; //it's still moving
}
public void CalculateScrollDrag(ref float pos, ref float speed, float boundsMin, float boundsMax)
{
float diff = 0;
if(pos < boundsMin)
{
diff = boundsMin - pos;
}
else if(pos > boundsMax)
{
diff = boundsMax - pos;
}
if(diff == 0) //it's in bounds, move normally
{
pos += speed;
}
else //out of bounds the movement gets spongey!
{
float diffEased = Mathf.Abs(diff) / edgeSquish;
pos += speed * Mathf.Max(0.0f,1.0f - Mathf.Sqrt(diffEased)); //note how we don't modify speed itself
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment