UGUI:一个渐变特写的滚动框特效
一个滚动框的特写特效。中间的Item为选中的Item,给个尺寸,坐标,Alpha的特写。而两边的则渐淡掉。
思路是把Grid下的每个Item只作为一个容器,再建一个content层级用来放真正的内容。然后监听ScrollRect的onValueChange,遍历Item,根据与中心坐标的距离来调整content的缩放,坐标偏移以及Alpha值。不过需要事先设置好在目标位置上的各项指标值,然后再按照位置进行插值。效果看起来像这样:
配合之前写的CenterOnChild脚本。
工程地址:https://github.com/mutou1994/UGUI_ScrollEffect
public class ScrollRectEffect : MonoBehaviour
{
float left_alpha = 0.6f;
float right_alpha = 0.4f;
float middle_alpha = 1f;
float left_height = 150;
float right_height = 100;
float middle_height = -120;
float left_scale = 0.6f;
float right_scale = 0.3f;
float middle_scale = 1f;
ScrollRect scroll;
List contents;
Vector2 centerPoint;
Vector2 viewPort_size;
void Awake()
{
scroll = transform.GetComponentInParent();
CacheContents();
CalCenterPoint();
scroll.onValueChanged.AddListener(onScroll);
}
void CacheContents()
{
if (contents == null)
contents = new List();
contents.Clear();
for (int i = 0, Imax = transform.childCount; i < Imax; i++)
{
Transform child = transform.GetChild(i).Find("content");
contents.Add(child);
}
}
void CalCenterPoint()
{
viewPort_size = (scroll.transform as RectTransform).rect.size;
Vector3 pickingPoint = Vector3.zero;
//裁剪区域四角坐标
Vector2 halfSize = viewPort_size / 2;
Vector2[] Conners = new Vector2[4];
Conners[0] = new Vector2(-halfSize.x, halfSize.y);
Conners[1] = new Vector2(halfSize.x, halfSize.y);
Conners[2] = new Vector2(halfSize.x, -halfSize.y);
Conners[3] = new Vector2(-halfSize.x, -halfSize.y);
centerPoint = (Conners[0] + Conners[2]) * 0.5f;
}
void onScroll(Vector2 vec)
{
Adjust();
}
void Adjust()
{
CalCenterPoint();
for (int i = 0, Imax = contents.Count; i < Imax; i++)
{
Vector3 pos = scroll.transform.InverseTransformPoint(contents[i].position);
if (!scroll.horizontal) pos.x = centerPoint.x;
if (!scroll.vertical) pos.y = centerPoint.y;
pos.z = 0;
float dis = Vector3.Distance(centerPoint, pos);
int direct = pos.x < centerPoint.x ? -1 : 1;
AdjustAlpha(i, dis, direct < 0 ? left_alpha : right_alpha);
AdjustScale(i, dis, direct < 0 ? left_scale : right_scale);
AdjustPosition(i, dis, direct < 0 ? left_height : right_height);
}
}
void AdjustScale(int index, float dis, float minVal)
{
float rate = 1 - (dis / (viewPort_size.x / 2f));
float scale = Mathf.Lerp(minVal, middle_scale, rate);
Vector3 vec = Vector3.zero;
vec.x = vec.y = vec.z = scale;
contents[index].localScale = vec;
}
void AdjustAlpha(int index, float dis, float minVal)
{
float rate = 1 - (dis / (viewPort_size.x / 2f));
float alpha = Mathf.Lerp(minVal, middle_alpha, rate);
var canvas = contents[index].GetComponent();
canvas.alpha = alpha;
}
void AdjustPosition(int index, float dis, float minVal)
{
float height = Mathf.Lerp(minVal, middle_height, 1 - (dis / (viewPort_size.x / 2f)));
Vector3 pos = contents[index].localPosition;
pos.y = height;
contents[index].localPosition = pos;
}
}
- 上一篇: UGUI:CenterOnChild
- 下一篇: xLua:一个LuaManager
public Action onCenterCallBack;
public Action onCenterFinshed;
if (onCenterCallBack != null)
onCenterCallBack.Invoke(target.gameObject);
if (onCenterFinished != null)
onCenterFinished.Invoke(centeredObject);
你好,我想问一下这段回调的作用是什么?我把这些注释掉之后,感觉没什么变化。
这是回调方法