今天用UGUI做多个图片自动滚动展示的功能,具体如下
1.从特定文件夹中读取所有图片
2.排列展示所有图片,如果超出屏幕范围了,就循环滚动
3.点击其中的图片,暂停滚动,该图片放大展示在屏幕中间。再点击就缩小回去,并继续滚动。
首先,要遍历文件夹,读取所有的图片
// 在特定路径中获取所有图片
Dictionary<string, Texture2D> GetAllImgInPath( string fullPath)
{
Dictionary<string, Texture2D> retDict = new Dictionary<string, Texture2D>();
// 先判断是不是存在该路径
if( Directory.Exists( fullPath) == false)
{
return retDict;
}
// 遍历路径中所有的文件
string [] filePathArr = Directory.GetFiles( fullPath);
string ext = string.Empty;
string []imgExtArr = new string[]{".jpg", ".png", ".bmp"};
foreach( string fullName in filePathArr)
{
// 根据后缀判断是不是图片
ext = Path.GetExtension( fullName);
if( ((IList)imgExtArr).Contains(ext))
{
// 读取图像
byte[] imgBytes = File.ReadAllBytes( fullName);
Texture2D t2d = new Texture2D(1,1);
t2d.LoadImage( imgBytes);
retDict.Add( Path.GetFileName( fullName), t2d);
}
}
return retDict;
}
然后针对每个图像创建一个RawImage对象。我在ugui中没有找到直接创建ugui控件的函数,只能做了一个RawImage的预置物,然后使用预置物Instantiate出来新的。
// 初始化所有图像
void InitAllImg( Dictionary<string, Texture2D> texDict)
{
if( m_imgCellPerfab == null || m_imgCellParent == null)
{
Debug.LogError( "InitAllImg ERR!! 预置物或者父节点是空值!");
return;
}
m_allImgs.Clear();
foreach( KeyValuePair<string, Texture2D> pair in texDict)
{
// 新建rawImage
Texture2D t2d = pair.Value;
RawImage imgCell = Instantiate( m_imgCellPerfab);
imgCell.texture = t2d;
imgCell.GetComponent<Transform>().SetParent( m_imgCellParent, false);
// 给图片添加点击事件
EventTriggerListener.Get(imgCell.gameObject).onDown += OnClickImg;
m_allImgs.Add( imgCell);
}
InitImgPos();
}
现在这些图片都可以显示了,现在该处理这些图片的位置了。设定一个间距距离,然后根据图像的宽度就可以算出下个图像的初始位置
// 初始化位置
void InitImgPos()
{
// 先算出总的宽度
float totalW = m_spacing;
foreach( RawImage img in m_allImgs)
{
// 图片的宽度+间隔
RectTransform rectTran = img.GetComponent<RectTransform>();
totalW = totalW + rectTran.rect.width + m_spacing;
}
// 如果总宽度比父节点宽度小,居中。如果总宽度比父节点的宽度大,从最左边起
Vector2 parentSize = m_imgCellParent.GetComponent<RectTransform>().sizeDelta;
float startX = 0;
if( totalW < parentSize.x)
{
// 居中
startX = -totalW/2;
}
else
{
// 从最左边起
startX = -parentSize.x/2;
}
float x = startX + m_spacing;
// 初始化每个图片的位置
foreach( RawImage img in m_allImgs)
{
// 图片的宽度+间隔
RectTransform rectTran = img.GetComponent<RectTransform>();
// 因为是中心对齐,所以偏移宽度的一半
x = x + rectTran.sizeDelta.x/2;
rectTran.localPosition = new Vector3( x, 0, 0);
// 下个图片的位置
x = x + rectTran.sizeDelta.x/2 + m_spacing;
}
}
之后就是处理移动了,就是每帧根据速度算出来移动的距离,然后每个图片都移动这个距离就好了。如果移动超出父节点的范围了的话,就把这个位置重新设置在队列的最后面(也就是当前的位置加上总的宽度)
// 处理移动 useTime:使用的时间
void DealMove( float useTime)
{
float dis = useTime * m_moveSp;
float x = 0;
Vector2 parentSize = m_imgCellParent.GetComponent<RectTransform>().sizeDelta;
// 遍历完所有的图片计算新位置
foreach( RawImage img in m_allImgs)
{
RectTransform rectTran = img.GetComponent<RectTransform>();
x = rectTran.localPosition.x - dis;
// 跑出范围了,就把它加到后面去
if( x < -(parentSize.x/2 + rectTran.sizeDelta.x/2 + m_spacing))
{
x = x + m_totalWidth;
}
rectTran.localPosition = new Vector3( x, 0, 0);
}
}
到目前为止,循环滚动的跑马灯效果已经完成了。
下面要处理点击图片后放大/缩小,滚动的开始/停止。
要实现放大/缩小效果,需要另外创建一个图片专门用于放大缩小。因为如果直接用原图来放大的话,如果它的层级不是最高的,那么放大后层级比它高的图片会盖在它上面。图片缩放的时候需要用到dotween插件。
// 开始弹出
public void StartPop( RawImage srcImg, PopCB popCB)
{
m_srcImg = srcImg;
m_popCB = popCB;
//
m_popPlane.SetActive( true);
// 根据源图片初始化要缩放的图片的大小,位置
RectTransform rectTran = m_scaleImg.GetComponent<RectTransform>();
RectTransform srcImgTran = srcImg.GetComponent<RectTransform>();
rectTran.sizeDelta = srcImgTran.sizeDelta;
rectTran.localPosition = srcImgTran.localPosition;
m_scaleImg.texture = srcImg.texture;
// 计算出需要缩放的倍数
float scaleX = m_maxSize.x/srcImgTran.sizeDelta.x;
float scaleY = m_maxSize.y/srcImgTran.sizeDelta.y;
float scale = Mathf.Min( scaleX, scaleY);
m_bWaiting = true;
Sequence quence = DOTween.Sequence();
quence.Append( rectTran.DOScale( new Vector3(scale, scale, 1), m_animTime));
quence.Join( rectTran.DOLocalMove( new Vector3(0,0,0), m_animTime));
quence.AppendCallback( ()=>{
// 动画完成
m_bWaiting = false;
});
}
给图片添加点击事件的时候用到了
EventTriggerListener.Get(imgCell.gameObject).onDown += OnClickImg;
EventTriggerListener这个类是自己封装的事件的监听类,具体的代码可以看项目源文件。
unity版本:unity 2020.3
源码路径:
autoRollImg.unitypackage-网络游戏文档类资源-CSDN下载