Unity3D应用案例系列Unity3D中实现《3D照片墙》

Posted 恬静的小魔龙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D应用案例系列Unity3D中实现《3D照片墙》相关的知识,希望对你有一定的参考价值。

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

首先,介绍一波我这个专栏:Unity3D之Unity应用案例

Unity3D不仅仅可以开发游戏,还有非常多的开发方向,秉承着兴趣为先,将可以使用Unity制作的各种应用案例,分享如何进行开发,如何实现,希望大家可以在感兴趣的地方,学习到自己想要学习的东西。

今天就来实现一个3D照片墙的效果。

我对于这个项目的构思就是照片是3D的,可以滑动,然后使用DoTween插件去做动画平滑移动。

OK,那就正式开始。

先看一下效果图:

二、正式开发

新建项目,我使用的版本是Unity3D 2019.4.7f1,模板选用3D:

(1)导入DoTween插件

(2)新建Canvas,设置参数:

设置Canvas的坐标到0,0,0:

(3)在Canvas新建N个Image:

(4)设置Main Camera的属性:

设置完的样子:

反正就是让Image在屏幕中间就可以了。

(5)新建脚本UIRotate.cs,双击打开脚本,编辑代码:

using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;

public class UIRotate : MonoBehaviour

    private int halfSize;
    private GameObject[] gameObjects;
    /// <summary>
    /// 圆半径
    /// </summary>
    private int r = 300;
    /// <summary>
    /// 相间角度
    /// </summary>
    private int angle;

    private void Start()
    
        //初始化数组
        var childCount = transform.childCount;
        //计算出中点
        halfSize = (childCount - 1) / 2;
        //求出圆内角度
        angle = 360 / childCount;
        //初始
        gameObjects = new GameObject[childCount];
        for (var i = 0; i < childCount; i++)
        
            gameObjects[i] = transform.GetChild(i).gameObject;
            SetPosition(i);
            SetDeepin(i);
        
    

    /// <summary>
    /// 设置物体位置
    /// </summary>
    private void SetPosition(int index)
    
        float x = 0;
        float z = 0;
        if (index < halfSize)
        
            int id = halfSize - index;
            x = r * Mathf.Sin(angle * id);
            z = -r * Mathf.Cos(angle * id);
        
        else if (index > halfSize)
        
            int id = index - halfSize;
            x = -r * Mathf.Sin(angle * id);
            z = -r * Mathf.Cos(angle * id);
        
        else
        
            x = 0;
            z = -r;
        
        Tweener tweener = gameObjects[index].GetComponent<RectTransform>().DOLocalMove(new Vector3(x, 0, z), 1);
    

    private void SetDeepin(int index)
    
        //计算图片深度也就是z轴的距离,离摄像机的远近
        int deepin = 0;
        if (index < halfSize)
        
            deepin = index;
        
        else if (index > halfSize)
        
            deepin = gameObjects.Length - (1 + index);
        
        else
        
            deepin = halfSize;
        
        gameObjects[index].GetComponent<RectTransform>().SetSiblingIndex(deepin);
    

(6)将UIRotate.cs脚本附到Canvas对象上,运行程序:

(7)添加左右拖动代码,继续修改UIRotate.cs代码:

using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;

public class UIRotate : MonoBehaviour

    private int halfSize;
    private GameObject[] gameObjects;
    /// <summary>
    /// 圆半径
    /// </summary>
    private int r = 300;
    /// <summary>
    /// 相间角度
    /// </summary>
    private int angle;

    private void Start()
    
        //初始化数组
        var childCount = transform.childCount;
        //计算出中点
        halfSize = (childCount - 1) / 2;
        //求出圆内角度
        angle = 360 / childCount;
        //初始
        gameObjects = new GameObject[childCount];
        for (var i = 0; i < childCount; i++)
        
            gameObjects[i] = transform.GetChild(i).gameObject;
            SetPosition(i);
            SetDeepin(i);
        
    

    /// <summary>
    /// 设置物体位置
    /// </summary>
    private void SetPosition(int index)
    
        float x = 0;
        float z = 0;
        if (index < halfSize)
        
            int id = halfSize - index;
            x = r * Mathf.Sin(angle * id);
            z = -r * Mathf.Cos(angle * id);
        
        else if (index > halfSize)
        
            int id = index - halfSize;
            x = -r * Mathf.Sin(angle * id);
            z = -r * Mathf.Cos(angle * id);
        
        else
        
            x = 0;
            z = -r;
        
        Tweener tweener = gameObjects[index].GetComponent<RectTransform>().DOLocalMove(new Vector3(x, 0, z), 1);
    

    private void SetDeepin(int index)
    
        //计算图片深度也就是z轴的距离,离摄像机的远近
        int deepin = 0;
        if (index < halfSize)
        
            deepin = index;
        
        else if (index > halfSize)
        
            deepin = gameObjects.Length - (1 + index);
        
        else
        
            deepin = halfSize;
        
        gameObjects[index].GetComponent<RectTransform>().SetSiblingIndex(deepin);
    

    /// <summary>
    /// 向左滑动
    /// </summary>
    public void OnLeftDrag()
    
        var length = gameObjects.Length;
        for (var i = 0; i < length; i++)
        
            var temp = gameObjects[i];
            gameObjects[i] = gameObjects[length - 1];
            gameObjects[length - 1] = temp;
        
        for (var i = 0; i < length; i++)
        
            SetPosition(i);
            SetDeepin(i);
        
    

    /// <summary>
    /// 向右滑动
    /// </summary>
    public void OnRightDrag()
    
        var length = gameObjects.Length;
        for (var i = 0; i < length-1; i++)
        
            var temp = gameObjects[i];
            gameObjects[i] = gameObjects[i+1];
            gameObjects[i+1] = temp;
        
        for (var i = 0; i < length; i++)
        
            SetPosition(i);
            SetDeepin(i);
        
    

    private Vector2 touchFirst = Vector2.zero;//手指开始按下的位置
    private Vector2 touchSecond = Vector2.zero;//手指拖动的位置

    void OnGUI()
    
        if (Event.current.type == EventType.MouseDown)
        
            touchFirst = Event.current.mousePosition;//记录开始按下的位置
        
        if (Event.current.type == EventType.MouseUp)
        
            touchSecond = Event.current.mousePosition;//记录拖动的位置
            if (touchSecond.x < touchFirst.x)
            
                OnLeftDrag();//向左滑动
            

            if (touchSecond.x > touchFirst.x)
            
                OnRightDrag();//向右滑动
            
            touchFirst = touchSecond;
        
    

运行程序:

(8)导入照片最后试一下:

三、总结

在Unity3D中实现了3D照片墙,虽然效果出来了,但是想要实现更加美观的效果还需要一些努力。

源代码就放在CSDN吧:
https://download.csdn.net/download/q764424567/84045547

你的点赞就是对博主的支持,有问题记得留言:

博主还有跟多宝藏文章等待你的发掘哦:

专栏方向简介
Unity3D开发小游戏小游戏开发教程分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。
Unity3D从入门到进阶入门从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。
Unity3D之UGUIUGUIUnity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。
Unity3D之读取数据文件读取使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。
Unity3D之数据集合数据集合数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。
Unity3D之VR/AR(虚拟仿真)开发虚拟仿真总结博主工作常见的虚拟仿真需求进行案例讲解。
Unity3D之插件插件主要分享在Unity开发中用到的一些插件使用方法,插件介绍等
Unity3D之日常开发日常记录主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等
Unity3D之日常BUG日常记录记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。

以上是关于Unity3D应用案例系列Unity3D中实现《3D照片墙》的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D小工具Unity3D中实现仿真时钟表盘仿原神时钟

Unity3D应用案例系列答题系统开发

Unity3D应用案例系列答题系统开发

Unity3D应用案例系列专栏文章导读清单

Unity3D应用案例系列专栏文章导读清单

Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)