有积分的可以直接下载上面的资源(竟然要积分头一次知道,还以为自己设置的那,果然垃圾CSDN)
下面是百度网盘资源:
链接:https://pan.baidu.com/s/1yyFgeCVN3gLLUFJXniup5w
提取码:m6wf
场景分辨率设置为:1920*1080
还要很多可以优化的点地方,有兴趣的可以做
比如对象的销毁和生成可以做成对象池,走到最左边后再移动到最右边循环利用
分析过程文件,采用Blender,资源已上传,可以播放动画看效果,下面截个图:
视频效果如下:
anim
Untiy结构如下:
上面的ImageItem是我手动添加展示关系用的,默认就一个Target,PictureWall挂PictureWall脚本,ImageItem(预制体)挂ImageItemController 脚本即可
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using Utility;
public class PictureWall : MonoBehaviour
{
public class PictureInfo
{
public string name;
public Texture2D texture;
}
[SerializeField]
private GameObject prefab;
[SerializeField]
private float width = 1920;
[SerializeField]
private float height = 1080;
[SerializeField, Tooltip("行数")]
private int row = 6;
private int column;
[SerializeField, Tooltip("间隔距离")]
private float intervalDistance = 20;
[SerializeField, Tooltip("奇数行的偏移")]
private float offset = 200;
[SerializeField, Tooltip("圆半径大小")]
private float radius = 300;
private float itemWidth;
private float itemHeight;
public float speed = 10;
[SerializeField]
private RectTransform target;
private string path = "/照片墙/";
private List<string> texturePaths;
private int currentIndex = 0;
private List<PictureInfo> textureList;
void Start()
{
#region 设置Target锚点和位置,觉得麻烦,手动设置请注释这段代码
var rect = transform as RectTransform;
var originalPos = target.anchoredPosition;
target.anchorMin = new Vector2(0, 1);
target.anchorMax = new Vector2(0, 1);
//一般情况新建一个Image或RawImage,锚点是居中的,需要设置到左上,但位置会变化,如有问题请看锚点是否正确
target.anchoredPosition = new Vector2(rect.rect.width / 2 + originalPos.x, originalPos.y - rect.rect.height / 2);
#endregion
textureList = new List<PictureInfo>();
path = Application.streamingAssetsPath + path;
ReadImage();
CalculateRowColumn();
}
private void ReadImage()
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
return;
}
texturePaths = new List<string>();
var jpgs = Directory.GetFiles(path, "*.jpg");
texturePaths.AddRange(jpgs);
foreach (var filePath in texturePaths)
{
UtilityLoadImage.I.LoadImage(filePath, tex =>
{
textureList.Add(new PictureInfo {
name = Path.GetFileNameWithoutExtension(filePath), texture = tex });
addNum++;
if (addNum == texturePaths.Count)
{
Spawn();
}
});
}
}
float addNum = 0;
private void Spawn()
{
float x = 0;
float y = 0;
for (int i = 0; i < row; i++)
{
y = i * (itemHeight + intervalDistance);
for (int j = 0; j < column; j++)
{
x = j * (itemWidth + intervalDistance);
RectTransform rect = Instantiate(prefab, transform).transform as RectTransform;
rect.pivot = new Vector2(0.5f, 0.5f);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, itemWidth);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, itemHeight);
rect.anchoredPosition = new Vector2(x, -y) + new Vector2(rect.rect.width / 2, -rect.rect.height / 2);
var controller = rect.GetComponent<ImageItemController>();
controller.speed = speed;
controller.target = target;
controller.radius = radius;
if (i % 2 != 0)
{
controller.horizontalOffset = offset;
}
SetTexture(rect);
}
}
target.SetAsLastSibling();
}
private void CalculateRowColumn()
{
itemHeight = (height - (row - 1) * intervalDistance) / row;
itemWidth = itemHeight * 16 / 9;
column = (int)(width / (itemWidth + intervalDistance)) + 3;
}
bool isSpawned = false;
private void Update()
{
if (!isSpawned && transform.childCount != 1 && transform.childCount <= (column - 1) * row + 1)
{
isSpawned = true;
SpawnColumn();
}
}
private void SpawnColumn()
{
float x = 0;
float y = 0;
for (int i = 0; i < row; i++)
{
y = i * (itemHeight + intervalDistance);
for (int j = 0; j < 1; j++)
{
x = (column - 1) * (itemWidth + intervalDistance);
RectTransform rect = Instantiate(prefab, transform).transform as RectTransform;
rect.pivot = new Vector2(0.5f, 0.5f);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, itemWidth);
rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, itemHeight);
rect.anchoredPosition = new Vector2(x, -y) + new Vector2(intervalDistance - Time.deltaTime * speed, -rect.rect.height / 2);
//重新计算位置:运行时间长导致误差间隔变大,可能是浮点误差导致的
rect.anchoredPosition = GetPos(rect.anchoredPosition);
var controller = rect.GetComponent<ImageItemController>();
controller.speed = speed;
controller.target = target;
controller.radius = radius;
SetTexture(rect);
}
}
target.SetAsLastSibling();
StartCoroutine(Delay());
}
private Vector2 GetPos(Vector2 originPos)
{
Vector2 nearPos = new Vector2((transform as RectTransform).rect.width, originPos.y);
foreach (RectTransform t in transform)
{
if (t.anchoredPosition.y == originPos.y)
{
if (t.anchoredPosition.x > nearPos.x && t.anchoredPosition.x < originPos.x