using System.Collections;
using System.Collections.Generic;
using DG.Tweening; //DOTween插件
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class RotationChart : MonoBehaviour,IDragHandler,IEndDragHandler
{
public Image[] prefab; //可旋转的图片预制体数组
public int num; //图片数量
public float spacing; //图片间隔
float c; //园的周长
float r; //园的半径
float ang; //两个图片间的夹角
float dis = 0; //图片滑动距离
float max = 1; //最大缩放比例
float min = 0.5f; //最小缩放比例
float cutSpeed =300; //切换速度
List<GameObject>list = new List<GameObject>(); //可旋转的图片列表
List<Transform>sorts = new List<Transform>(); //可旋转的图片的transform组
// Start is called before the first frame update
void Start()
{
//计算园的周长、半径和两个图片间的夹角
c = (prefab[1].rectTransform.rect.width + spacing) * num;
r = c / (2 * Mathf.PI);
ang = (2 * Mathf.PI) / num;
Move(); //移动图片
}
//移动图片
public void Move()
{
float moveang = dis / r; //图片移动的弧度值
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(i * ang + moveang) * r; //计算图片位置的x坐标
float z = Mathf.Cos(i * ang + moveang) * r; //计算图片位置的y坐标
float p = (z + r) / (2* r); //根据y坐标计算图片的比例系数
p = 1 - p;
float scale = (max - min)* p + min; //计算图片的缩放比例
if (list.Count<=i)
{
GameObject image = Instantiate(prefab[i].gameObject, transform); //创建图片
image.name = i.ToString();
list.Add(image);
sorts.Add(image.transform);
}
list[i].transform.localPosition = Vector3.right*x; //设置图片的位置
list[i].transform.localScale = Vector3.one *scale; //设置图片的缩放比例
}
sorts.Sort((a, b) => //按照缩放比例排序
{
if (a.localScale.x < b.localScale.x)
{
return -1;
}
else if (a.localScale.x == b.localScale.x)
{
return 0;
}
else
{
return 1;
}
});
for (int i = 0; i < sorts.Count; i++)
{
sorts[i].SetSiblingIndex(i); //重新设置图片的顺序
}
}
//拖拽行为
public void OnDrag(PointerEventData eventData)
{
dis += eventData.delta.x; //计算拖拽距离
Move();
}
//拖拽结束
public void OnEndDrag(PointerEventData eventData)
{
float startspeed = eventData.delta.x; //拖拽结束时的速度
float endspeed = 0;
float time = Mathf.Abs(startspeed) / cutSpeed; //计算切换所需的时间
DOTween.To((float a) =>
{
dis -= a; //计算滑动距离
Move();
}, startspeed, endspeed, time).OnComplete(() =>
{
Align(list.IndexOf(sorts[num-1].gameObject)); //对齐图片的位置
});
}
/// <summary>
/// 轮转图对齐
/// </summary>
/// <param name="n"></param>
public void Align(int n)
{
//当前的下标
int i = list.IndexOf(sorts[num - 1].gameObject);
int s = i-n; //计算需要旋转的图片数量
int s2 = num - Mathf.Abs(s);
s2 = s >0 ? -s2 : s2;
int s3 = Mathf.Abs(s) >Mathf.Abs(s2) ? s : s2; //选择需要旋转的方向
float moveAng = Mathf.Asin(sorts[num - 1].localPosition.x/r)+s*ang; //计算需要旋转的弧度值
float moveDis = moveAng * r; //计算需要旋转的距离
float time = Mathf.Abs(moveDis) / cutSpeed; //计算旋转所需的时间
DOTween.To((float a) =>
{
dis = a; //计算总滑动距离
Move();
}, dis, dis + moveDis, time).OnComplete(() =>
{
//sorts[num - 1].GetComponent<xx>().xxx(); //在动画完成后执行某些操作
});
}
}
【Unity技巧分享】如何实现简单的图片轮转效果
在游戏或软件中,很多时候需要实现一个能让用户浏览多张图片的效果,而轮转效果便是其中之一。但是在Unity中实现这个功能并不容易,本文将介绍如何使用DOTween插件来实现一个简单的图片轮转效果。
首先,需要准备好多张可以用于轮转的图片,并将其制作成预制体。在代码中通过定义预制体数组来管理这些图片。
接着,需要计算出轮转的圆心、半径和图片之间的夹角。将所有图片按照圆弧排列,同时通过计算每个图片的位置和比例实现轮转效果。通过列表管理每个图片,并按照缩放比例排序。
接下来,监听拖拽行为,计算拖拽的距离并移动图片。拖拽结束后,通过动画的方式实现轮转到指定位置的效果。可以通过计算需要旋转的图片数量,选择旋转的方向并计算出旋转的距离和时间,最终以动画的方式完成轮转效果。
在实现这个功能过程中,使用DOTween插件可以大大简化动画效果的处理,提高了开发效率。同时,通过简单的数学计算,实现了轮转效果,让用户可以更加方便地浏览多张图片。
综上所述,使用DOTween插件和简单的数学计算,可以快速实现一个简单的图片轮转效果。希望本文对大家有所帮助,也欢迎大家留言交流。