【Unity】LineRenderer模拟橡皮筋弹跳效果 您所在的位置:网站首页 kettle调用java接口 【Unity】LineRenderer模拟橡皮筋弹跳效果

【Unity】LineRenderer模拟橡皮筋弹跳效果

2024-06-13 02:23| 来源: 网络整理| 查看: 265

LineRenderer模拟橡皮筋弹跳的物理现象,手拖拽橡皮筋然后松开,橡皮筋会来回跳动,并最终静止在原位置,主要思路就是实时计算点的位置,给LineRenderer的点赋值,实现动态弹跳效果 这里写图片描述 代码里主要分了两步:

从松开手的位置,回弹到原来位置然后开始来回跳动,调动幅度越来越小,直到停止不动

该Demo里没有添加手拖拽皮筋的代码,如果有需要可自行实现,仅需要在LineRenderer 点位的起点与终点之间,添加一个中点,然后实时修改中点位置与屏幕鼠标位置一致即可(注意坐标转换~)

还有一个待实现功能,因为实际项目中没有这个需求,原谅楼主太懒没有写出代码··· 目前line从手松开点回弹时,仅用了三个点位,line显示就是两条线段,会有一个明显的夹角,如果要更加自然一点,可以多增加一些点位,利用正弦曲线值乘一个系数,原理与弹跳原理一样

在场景中创建一个空物体,添加LineRenderer 组件,设置合适的参数(材质、宽度等),然后挂载该脚本就OK啦~

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Line : MonoBehaviour { //取样点的数量,数量越多,线条越圆滑 [SerializeField] int pointCount = 20; //回弹速度 [SerializeField, Range(0, 1)] float lineGoBackSpeed = 0.3f; //弹跳衰减参数 [SerializeField, Range(0, 0.2f)] float bounceReduceParame = 0.1f; //线条弹跳频率 [SerializeField, Range(0, 2.0f)] float bounceFrequencyParame = 0.8f; //弹跳高度参数,最大弹跳高度 [SerializeField] float bounceHighParame = 0.05f; //LineRenderer组件 LineRenderer lineRenderer; //line起点终点 Vector2 startPoint, endPoint; //回弹线条取样点,取正弦曲线上半部分,作为线条弯曲最大曲线,在此基础上,乘以动态系数,改变回弹幅度 List pointList; void Start() { //测试 Init(Vector2.zero, Vector2.one * 2); BackToFormerPosition(new Vector2(1, 0)); } void Init(Vector2 startPos, Vector2 endPos) { //获取组件 lineRenderer = GetComponent(); //设置向量起点与终点,保证向量在一二象限,即方向与Y轴正方向夹角不大于90度 if (startPos.y > endPos.y) { startPoint = endPos; endPoint = startPos; } else { startPoint = startPos; endPoint = endPos; } //获取0--π的sin值,即正弦函数上半部分,按指定数量均分,获取取样点,作为弹跳曲线的原型 if (pointList == null) { pointList = new List(); for (float i = 0; i 1) bounceHigh = 1; else if (bounceHigh < -1) bounceHigh = -1; else if (bounceHigh > -0.2f & bounceHigh < 0f) bounceHigh = -0.2f; else if (bounceHigh < 0.2f & bounceHigh >= 0) bounceHigh = 0.2f; // StartCoroutine(SetLineOriginal(nowPoint, bounceHigh)); } //从给定点回弹到原位置 IEnumerator SetLineOriginal(Vector2 middlePoint, float bounceHigh) { //目标点为原位置的中点,中间点从给定位置移动到目标点 Vector2 targetPoint = (startPoint + endPoint) / 2; //设置lineRenderer参数 lineRenderer.positionCount = 3; lineRenderer.SetPosition(0, startPoint); lineRenderer.SetPosition(2, endPoint); lineRenderer.SetPosition(1, middlePoint); float distance = Vector2.Distance(middlePoint, targetPoint); float speed = distance * lineGoBackSpeed; //持续移动lineRenderer中点,直到与很接近原位置 while (distance > 0.05f) { middlePoint = Vector2.MoveTowards(middlePoint, targetPoint, speed); lineRenderer.SetPosition(1, middlePoint); distance = Vector2.Distance(middlePoint, targetPoint); yield return new WaitForSeconds(0.02f); } //恢复直线状态 lineRenderer.positionCount = 2; lineRenderer.SetPosition(0, startPoint); lineRenderer.SetPosition(1, endPoint); //回弹到原位置后,开始线条跳动效果 StartCoroutine(SetLineBounce(bounceHigh)); } //线条跳动效果 IEnumerator SetLineBounce(float bounceHigh) { //起点与终点在X/Y方向的距离 float distanceX = endPoint.x - startPoint.x; float distanceY = endPoint.y - startPoint.y; //向量与水平方向的夹角,单位为弧度 float vectorAngle = Mathf.Acos(Vector2.Dot((endPoint - startPoint).normalized, Vector2.right)); //设置lineRenderer点数量 lineRenderer.positionCount = pointCount; //angle累加,计算其正弦值,得到正弦曲线,0 -> 1 -> 0 -> -1 -> 0 ,依次作为line弹跳幅度系数,正负表示方向 float angle = 0; //衰减数值,影响弹跳幅度,数值越来越小,弹跳幅度越来越小,直到弹跳停止 float reduce = 1; while (reduce >= 0.02f) { //angle累加,bounceFrequencyParame会决定弹跳幅度的变化速度 angle += bounceFrequencyParame; //插值计算reduce值 reduce = Mathf.Lerp(reduce, 0, bounceReduceParame); //设置lineRenderer点位,线条弹起高度 = 幅度系数 * 衰减系数 * 高度系数 SetBounceLine(Mathf.Sin(angle) * reduce * bounceHigh, distanceX, distanceY, vectorAngle); yield return new WaitForSeconds(0.02f); } //恢复直线状态 lineRenderer.positionCount = 2; lineRenderer.SetPosition(0, startPoint); lineRenderer.SetPosition(1, endPoint); } //偏移line的点 void SetBounceLine(float highParam, float distanceX, float distanceY, float vectorAngle) { //计算每个点的坐标位置 //计算公式: //偏移点(x1,y1),向量起点(x0,y0),起点到终点的向量与X轴夹角 a //在一二象限 //x1 = x0 - sin(a), y1 = y0 + cos(a) //在三四象限 //x1 = x0 + sin(a), y1 = y0 + cos(a) //所以在初始化的时候,互换起点与终点,保证向量在一二象限,可以方便计算 float xx, yy; for (int i = 0; i < pointCount; i++) { xx = startPoint.x + distanceX * i / (pointCount - 1) - pointList[i] * highParam * Mathf.Sin(vectorAngle); yy = startPoint.y + distanceY * i / (pointCount - 1) + pointList[i] * highParam * Mathf.Cos(vectorAngle); lineRenderer.SetPosition(i, new Vector2(xx, yy)); } } }

本文来自博客园,作者:萧然CS,转载请注明原文链接:https://www.cnblogs.com/z-c-s/p/15112995.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有