Unity照片墙简易圆形交互效果总结

有积分的可以直接下载上面的资源(竟然要积分头一次知道,还以为自己设置的那,果然垃圾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
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值