一、效果图

1.效果1

2.效果2

二、贝塞尔曲线

关于贝塞尔曲线的学习大家可以看这个文章进行学习https://blog.csdn.net/qq_39162826/article/details/119806754?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165313175716782395391583%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165313175716782395391583&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-119806754-null-null.142^v10^pc_search_result_control_group,157^v4^control&utm_term=unity+%E8%B4%9D%E5%A1%9E%E5%B0%94%E6%9B%B2%E7%BA%BF&spm=1018.2226.3001.4187

看了上面的贝塞尔曲线的公式,大家应该能想到unity中的一个函数Lerp吧,我们根据上一个文章来看:

1. 一阶贝塞尔曲线公式是这样的

   List<Vector3> pointsList=new List<Vector3>() {Vector3.zero,Vector3.one }; //一阶贝塞尔public Vector3 FirstOrderBezier(float t){Vector3 a = pointsList[0];Vector3 b = pointsList[1];return a + (b - a) * t;}

如果我们使用Lerp来写的话是这样:

    List<Vector3> pointsList=new List<Vector3>() {Vector3.zero,Vector3.one };//一阶贝塞尔public Vector3 FirstOrderBezierLerp(float t) {Vector3 a = pointsList[0];Vector3 b = pointsList[1];return Vector3.Lerp(a,b,t);}

2. 二阶贝塞尔曲线

    List<Vector3> pointsList=new List<Vector3>() {Vector3.zero,Vector3.one, new Vector3(2,2,2)};//二阶贝塞尔public Vector3 SecondOrderBezierLerp(float t){Vector3 a = pointsList[0];Vector3 b = pointsList[1];Vector3 c = pointsList[2];Vector3 aa = a + (b - a) * t;Vector3 bb = b + (c - b) * t;return aa + (bb - aa) * t;}

Lerp

    //二阶贝塞尔public Vector3 SecondOrderBezierLerp(float t){Vector3 a = pointsList[0];Vector3 b = pointsList[1];Vector3 c = pointsList[2];Vector3 aa = Vector3.Lerp(a, b, t);Vector3 bb = Vector3.Lerp(b, c, t);return Vector3.Lerp(aa, bb, t);}

好的根据这个规律我们写一个n阶贝塞尔曲线

  #region N阶贝塞尔曲线public List<Vector3> bezierPointList;//存储计算的贝塞尔曲线结果List<Vector3> calculateBezierPointList=new List<Vector3>(); public Vector3 NOrderBezierLerp(float t) {//点为空或为0if (bezierPointList==null|| bezierPointList.Count<=0)return Vector3.zero;//点为1if (bezierPointList.Count == 1)return bezierPointList[0];Vector3 result = Vector3.zero; //返回的结果//列表赋值calculateBezierPointList = bezierPointList;//当列表的值大于等于2时执行while (calculateBezierPointList.Count>=2){List<Vector3> pointList = new List<Vector3>();for (int i = 0; i < calculateBezierPointList.Count-1; i++){Vector3 posA = calculateBezierPointList[i];Vector3 posB = calculateBezierPointList[i+1];pointList.Add(Vector3.Lerp(posA, posB,t));}//将计算好的贝塞尔曲线列表赋值给calculateBezierPointListcalculateBezierPointList = pointList;}//最终计算后列表中只有1个点result = calculateBezierPointList[0]; return result;}#endregion

然后我们用LineRenderer组件来测试这个N阶贝塞尔曲线是否管用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// N阶贝塞尔曲线测试
/// </summary>
public class N_OrderBezierLerpTest : MonoBehaviour
{LineRenderer line;void Start(){line = GetComponent<LineRenderer>();line.positionCount = 100;}void Update(){//实时创建贝塞尔曲线点for (int i = 1; i < line.positionCount + 1; i++){Vector3 Bezierposition = N_OrderBezierLerp(i * 0.01f);line.SetPosition(i - 1, Bezierposition);}}#region N阶贝塞尔曲线public List<Vector3> bezierPointList;//存储计算的贝塞尔曲线结果List<Vector3> calculateBezierPointList=new List<Vector3>(); public Vector3 N_OrderBezierLerp(float t) {//点为空或为0if (bezierPointList==null|| bezierPointList.Count<=0)return Vector3.zero;//点为1if (bezierPointList.Count == 1)return bezierPointList[0];Vector3 result = Vector3.zero; //返回的结果//列表赋值calculateBezierPointList = bezierPointList;//当列表的值大于等于2时执行while (calculateBezierPointList.Count>=2){List<Vector3> pointList = new List<Vector3>();for (int i = 0; i < calculateBezierPointList.Count-1; i++){Vector3 posA = calculateBezierPointList[i];Vector3 posB = calculateBezierPointList[i+1];pointList.Add(Vector3.Lerp(posA, posB,t));}//将计算好的贝塞尔曲线列表赋值给calculateBezierPointListcalculateBezierPointList = pointList;}//最终计算后列表中只有1个点result = calculateBezierPointList[0]; return result;}#endregion}

场景布局:

 运行程序来看看效果:

看这样我们就可以随心所欲的创建多种曲线效果了。

三、使用贝塞尔曲线制作图片轮播

1.Bezier.cs

贝塞尔曲线脚本,里面记录了N阶贝塞尔曲线公式

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 贝塞尔曲线工具脚本
/// </summary>
public class Bezier
{//存储计算的贝塞尔曲线结果static List<Vector3> calculateBezierPointList = new List<Vector3>();/// <summary>/// N阶贝塞尔曲线/// </summary>/// <param name="bezierPointList">贝塞尔曲线列表</param>/// <param name="t">t值</param>/// <returns></returns>public static Vector3 N_OrderBezierLerp(List<Vector3> bezierPointList, float t){//点为空或为0if (bezierPointList == null || bezierPointList.Count <= 0)return Vector3.zero;//点为1if (bezierPointList.Count == 1)return bezierPointList[0];Vector3 result = Vector3.zero; //返回的结果//列表赋值calculateBezierPointList = bezierPointList;//当列表的值大于等于2时执行while (calculateBezierPointList.Count >= 2){List<Vector3> pointList = new List<Vector3>();for (int i = 0; i < calculateBezierPointList.Count - 1; i++){Vector3 posA = calculateBezierPointList[i];Vector3 posB = calculateBezierPointList[i + 1];pointList.Add(Vector3.Lerp(posA, posB, t));}//将计算好的贝塞尔曲线列表赋值给calculateBezierPointListcalculateBezierPointList = pointList;}//最终计算后列表中只有1个点result = calculateBezierPointList[0];return result;}
}

2. item.cs

此脚本是要挂载在图片上,用于记录当前在曲线的位置

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;/// <summary>
/// 图片ietm
/// </summary>
public class Item : MonoBehaviour
{float bezierT;SpriteRenderer m_Img;//封装public float BezierT { get => bezierT; set => bezierT = value; }/// <summary>/// 修改图片精灵/// </summary>/// <param name="sprite"></param>public void SetImageSprite(Sprite sprite){//image为空时初始化if (m_Img == null)m_Img = transform.GetChild(0).GetComponent<SpriteRenderer>();m_Img.sprite = sprite;}}

3.BezierController.cs

此脚本控制物体在曲线的排列,以及鼠标控制拖动等功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;//贝塞尔曲线控制
public class BezierController : MonoBehaviour
{//起始和结束点最好有预留,否则拖动时可能会出现左右闪烁问题[Header("首尾消失距离")][Range(0f, 0.5f)][SerializeField] float leftDis = 0.05f; [Range(0.5f, 1f)][SerializeField] float rightDis = 0.95f;[Header("控制鼠标拖动物体速度")][SerializeField] float speed = 1;[Header("物体容器")]public Transform content;//容器LineRenderer line;[Header("图片精灵列表,贝塞尔曲线点位")]public List<Sprite> spriteList;public List<Vector3> bezierPointList;void Start(){line = GetComponent<LineRenderer>();line.positionCount = 100;//初始化图片布局InitItem();}Vector2 oldPos;void Update(){//生成贝塞尔曲线点 LineRenderBezier_Creat();//按下I按键初始化item布局 if (Input.GetKey(KeyCode.I))InitItem(); //初始化#region 鼠标拖动控制左右移动if (Input.GetMouseButtonDown(0)){oldPos = Input.mousePosition;}if (Input.GetMouseButton(0)){Vector2 pos = new Vector2(Input.mousePosition.x - oldPos.x, Input.mousePosition.y - oldPos.y);for (int i = 0; i < content.childCount; i++){Item obj = content.GetChild(i).GetComponent<Item>();objMove(pos, obj);}oldPos = Input.mousePosition;}#endregion}#region 初始化item平均布局public void InitItem(){//Debug.Log("初始化");//计算物体在曲线中的t值(间距)float space = Mathf.Abs(rightDis - leftDis) / content.childCount;//循环初始化 for (int i = 0; i < content.childCount; i++){Item obj = content.GetChild(i).GetComponent<Item>();obj.BezierT = leftDis + (i * space);Vector3 _pos = Bezier.N_OrderBezierLerp(bezierPointList, obj.BezierT);obj.transform.position = _pos;SetImageSprite(1, obj); //修改图片}}#endregion#region 物体移动void objMove(Vector2 pos, Item obj){//计算物体BezierT的值float value = (pos.x * speed * Time.deltaTime) / Screen.width;obj.BezierT += value;//物体BezierT的值大于等于1 (到达最右边)if (obj.BezierT >= 1){//BezierT值等于 除1的余数obj.BezierT = obj.BezierT % 1;SetImageSprite(1, obj);//切换下一张图片}//物体BezierT的值小于等于0 (到达最左边边)if (obj.BezierT <= 0){//取除1的余数float newBezierT = obj.BezierT % 1;  //我们的贝塞尔T取值范围为0~1,不会出现负数 所以“取余的值”要为正,这里进行绝对值计算obj.BezierT = rightDis- Mathf.Abs(newBezierT);SetImageSprite(-1, obj);//切换上一张图片}//计算在贝塞尔曲线的位置并赋值Vector3 _pos = Bezier.N_OrderBezierLerp(bezierPointList, obj.BezierT);obj.transform.position = _pos; }#endregion#region 图片替换int currentIndex = -1;/// <summary>/// 图片替换/// </summary>/// <param name="dir">移动方向</param>/// <param name="item">要替换的图片物体</param>void SetImageSprite(int dir, Item item){if (dir > 0){currentIndex++;//超出图片列表最大值 等于0if (currentIndex > spriteList.Count - 1)currentIndex = 0;}if (dir < 0){currentIndex--;//超出图片列表最小值 等于列表最后一个if (currentIndex < 0)currentIndex = spriteList.Count - 1;}//修改item图片item.SetImageSprite(spriteList[currentIndex]);}#endregion#region 生成贝塞尔曲线/// <summary>/// 生成贝塞尔曲线Line/// </summary>private void Bezier_Creat(){for (int i = 1; i < line.positionCount + 1; i++){Vector3 Bezierposition = Bezier.N_OrderBezierLerp(bezierPointList, i*0.01f);line.SetPosition(i - 1, Bezierposition);}}#endregion}

脚本中我都加了很详细的注释,如果有问题或者不懂的可以在评论交流指正。

三、原程序包

版本:2019.4.32f1

链接:https://pan.baidu.com/s/1IB_6opHR6idcrCoGMl6XVg?pwd=syq1 
提取码:syq1

Unity之使用贝塞尔曲线制作图片轮播相关推荐

  1. 会声会影如何制作图片轮播的视频效果

    当需要进行图片展示时,常常使用图片轮播的形式进行展示,这种效果很常见并且展示效果好,该怎么制作呢?接下来,小编就教大家用视频编辑软件会声会影2020制作图片轮播的视频效果. 一. 制作单张图片滚动效果 ...

  2. php制作图片轮播_图片轮播效果实现方法

    图片轮播效果如何实现呢本文主要介绍了JQuery实现图片轮播效果的制作原理以及实现代码,文章末尾附上源码下载,具有很好的参考价值.下面跟着小编一起来看下吧,希望能帮助到大家. 用JQuery操作DOM ...

  3. vue 实现无限轮播_使用Vue制作图片轮播组件思路详解

    之前一直都没有认真的写过一个组件.以前在写业务代码的过程中,都是用的别人封装好的组件,这次尝试着写了一个图片轮播组件,虽然比不上知名的轮播组件,但它的功能基本完整,而且在写这个组件的过程中,学的东西也 ...

  4. php制作图片轮播_JavaScript_jQuery制作简洁的图片轮播效果,演示图:核心代码:$ - phpStudy...

    jQuery制作简洁的图片轮播效果 演示图: 核心代码: $(document).ready(function(){ var $iBox = $('.imgBox'), $iNum = $('.img ...

  5. 网页制作使用CSS样式制作轮播教程,静态网页设计与开发 1.案例——CSS3制作图片轮播图 (4)使用纯CSS3代码实现简单的图片轮播——分步骤实现.docx...

    使用纯CSS3代码实现简单的图片轮播 设计思路: 以5张图片为例: 1.基本布局: 通过设置每张图片的尺寸和父容器的尺寸,从而将5张图片横向并排放入一个div容器(#photos)内.所有图片设置统一 ...

  6. 纯js制作图片轮播效果

    好久没有发博客了,最近都在复习,为了找工作做准备. 前段时间逛了下鼠绘漫画网追海贼王最新漫画,发现他们家的图片轮播效果跟其他网页的图片轮播效果效果不同,看起来更加有趣,于是我尝试了用js复写它. 前提 ...

  7. php制作图片轮播_轮播图怎么做

    效果图 思路分析: 1.开启一个定时器 方法名:window.setInterval(code,MilliSec),每隔指定的时间就执行code,无限次执行. 2.定时器函数主要是用来执行图片轮播的效 ...

  8. SharePoint Online 部件InjectionScriptWebpart制作图片轮播

    前言 我们经常需要在SharePoint Online中开发门户站点,而新闻就是门户里最常用的一种类型. 下面,我们就为大家演示一下,如何使用注入脚本部件,完成一个新闻列表的功能. 正文 1.我们首先 ...

  9. unity实现图片轮播效果_Unity 制作图片轮播功能

    功能:自动播放移动 首尾相接  鼠标移到图片上 时 移动停止并 该图片变大  鼠标离开图片恢复原形 轮播效果继续 效果如下 界面布局 大体是这个样子 scrollView就是一个底板带Image组件 ...

最新文章

  1. Struts2--ActionContext及CleanUP Filter
  2. python 使用win32com 操作excel
  3. Regtech半月观察(9月上)
  4. Linux/CentOS下安装Apache/SVN/Subversion图文详解教程
  5. 《游戏编程入门 4th》笔记(2 / 14):监听Windows消息
  6. python 自动登录网站_python自动登录网页脚本
  7. 流氓百度乱发短信的经历
  8. GitHub:为什么我们最终选择放弃了 jQuery
  9. Android loopback(三)
  10. koa学习笔记(一)环境安装及文件目录
  11. gdisk 创建和维护磁盘分区命令(GPT分区方案)
  12. 地图经纬度转换(百度,高德,谷歌,Leaflet)
  13. R语言列联表的统计分析及假设检验
  14. 【2018ECCV】Zero-Shot Deep Domain Adaptation 零样本深度域适应
  15. C#窗体调用地图(高德地图)-实现公交线路查询
  16. 明天就会有阳光...
  17. 火影T7C笔记本Win11重装Win10系统方法分享
  18. 解决AttributeError: module ‘win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9‘ has no attribu
  19. Substrate之旅1:Polkadot是什么
  20. OpenGL编程指南(第八版)第一个渲染三角形案例代码在win8双显卡电脑VS2015中运行方法总结

热门文章

  1. c语言数据类型的心得体会,C语言学习与感悟——《C语言学习基本框架》
  2. 计算机远程桌面软件,手把手教你远程控制电脑软件推荐
  3. 平台经济中国案例研究——网易云平台
  4. logit模型应用实例_最大似然估计(上)——离散选择模型之十
  5. gate simulation
  6. miRNA数据库篇——miRDB:软件预测的哺乳动物miRNA靶基因数据库(假阳性较高)
  7. Egret:一个简单的打砖块游戏
  8. 5 爬虫 异步协程 梨视频
  9. Vue使用微信录音并上传服务端
  10. 首发 华为Mate7青春版拆机换电池