都在代码和代码注释里了
发表在这里我还是有私心想要问问题的:
是因为自己在使用时发现,Unity会调用两次通过继承来的PictureScrollView的Start函数两次,
我并不能想明白是怎么回事,还请有了解的指点一下:)先谢谢能给我指点的各位了;)
而且我写的这个代码当用户按住鼠标不松开一直向某个方向拖动的话就不会循环显示图片了,交换一次只会运行,即只交换一张对应图片
我自己所摆放的预制体样式
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9MmaOJTUE5ENJpXTmZEWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zNxMTOwIDMxETMyATM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
///
/// 继承自UnityEngine.UI的ScrollRect
///
public class PictureScrollView : ScrollRect
{
Vector3 v_OldContenPos = Vector3.zero;
float size = 0;
float contentDeltaPos = 0;
float moveDirection = 0;
int count = 0;
bool isDrag = true;
bool isStillMove = false;
///
/// 存储content下的子物体
///
Button[] buttonElements = null;
public delegate void Func(bool b);
///
/// 不在拖动和拖动后持续移动的状态下,要进行的操作
///
public Func DisMove;
void StopAction()
{
DisMove(false);
}
protected override void Start()
{
base.Start();
buttonElements = content.GetComponentsInChildren ();
int length = buttonElements.Length;
for (int i = 0; i < length; i++)
{
buttonElements[i].onClick.AddListener(StopAction);
}
//在这里设置了一下content的锚点
content.GetComponent
().anchorMin = new Vector2(0,0.5f) ;
content.GetComponent
().anchorMax = new Vector2(0, 0.5f);
//保存元素容器的初始坐标
v_OldContenPos = content.localPosition;
//获取子物体的数量
count = content.childCount;
//Debug.Log(count);
//该方法会被调用两次,不进行判断第一次会有content子对象数量为零
//不知道为什么会被调用两次,而且在停止播放程序后还会再调用两次
if (count > 0)
{
//获得子物体的宽度
size = content.GetChild(0).GetComponent
().sizeDelta.x;
}
}
private void Update()
{
if (!isDrag && isStillMove)
{
//继续滑动
StillScroll();
}
}
public override void OnBeginDrag(PointerEventData eventData)
{
base.OnBeginDrag(eventData);
}
public override void OnDrag(PointerEventData eventData)
{
base.OnDrag(eventData);
//循环滑动
Scroll();
DisMove(false);
}
public override void OnEndDrag(PointerEventData eventData)
{
base.OnEndDrag(eventData);
isDrag = false;
isStillMove = true;
}
///
/// 循环滑动 ///
void Scroll()
{
//容器改变了的位置
contentDeltaPos = content.position.x;
//移动方向
moveDirection = velocity.x;
//检测是否达到交换位置的点
//当使用按照预制体摆放物体时,向左移-,超过两倍的单元宽度的位移时
//将最后一个交换至第一个
if (contentDeltaPos < -2 * size && isDrag)
{
//在有ContentSizeFitter类的管理下,SetAsLastSibling()函数会对子物体排序
content.GetChild(0).SetAsLastSibling();
content.localPosition = v_OldContenPos;
}
if (contentDeltaPos < -2 * size)
{
isDrag = false;
}
//当使用按照预制体摆放物体时,向右移+,超过一定长度的位移时
//将第一个交换至最后一个
if (contentDeltaPos > 0 && isDrag)
{
content.localPosition = v_OldContenPos;
content.GetChild(count - 1).SetAsFirstSibling();
}
if (contentDeltaPos > 1)
{
isDrag = false;
}
}
///
/// 在拖动(OnDrag())结束后的持续滑动 ///
void StillScroll()
{
//容器改变了的位置
contentDeltaPos = content.position.x;
//移动方向
moveDirection = velocity.x;
//检测是否达到交换位置的点
//当使用按照预制体摆放物体时,向左移-,超过两倍的单元宽度的位移时
//将最后一个交换至第一个
if (contentDeltaPos < -2 * size && velocity.x <= -0.1)
{
//在有ContentSizeFitter类的管理下,SetAsLastSibling()函数会对子物体排序
content.GetChild(0).SetAsLastSibling();
content.localPosition = v_OldContenPos;
}
//当使用按照预制体摆放物体时,向右移+,超过一定长度的位移时
//将第一个交换至最后一个
if (contentDeltaPos > 0 && velocity.x >= 0.1)
{
content.localPosition = v_OldContenPos;
content.GetChild(count - 1).SetAsFirstSibling();
}
if (Mathf.Abs(velocity.x) <= 0.1)
{
isStillMove = false;
}
//在这里改变状态,主要用于和外部类通讯
if (DisMove != null)
{
DisMove(true);
}
}
}