一、pingpong效果
灯光渐变(呼吸灯),位置往复移动,尺寸重复变化…
二、pingpong的原理和用途
PingPong(呼吸)效果脚本:计算出一个值,这个由插值算法生成,值的变化形式为由小到大,再由大到小,循环往复,pingpong的函数,经过抽象包装,插值的代码在update里一行解决,简单易懂。
- 【算法实现】:关键语句:【Mathf.PingPong(Time.time, time)】,放置在update里面
方式一:插值范围比较大
var lerp = Mathf.PingPong(Time.time, time)
如果time = 2,那么2秒之内,插值系列从0运行到2,然后从2运行到0,Time.time只作为一个时间轴,呼吸的动画在时间轴的切片内循环进行
方式二:插值的范围为[0,1]呼吸时间为time指定的值
var lerp2 = Mathf.PingPong(Time.time, time) / time
如果time = 2,那么2秒之内,插值系列从【0 / 2 = 0】运行到【2 / 2 = 1】,然后从【2 / 2 = 1】 运行到【0 / 2 = 0 】
- 【使用场景】:
1、物体(3D物体,2D物体)由大到小变化
2、颜色渐变
3、灯光强弱
4、其它:用该呼吸系数值进行各种操作,比如一个弹簧的拉长和缩短等等
二、脚本配置
三、脚本代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// PingPong(呼吸)效果脚本:计算出一个值,这个由插值算法生成,值的变化形式为由小到大,再由大到小,循环往复
/// 【算法实现】:关键语句:【Mathf.PingPong(Time.time, time)】,放置在update里面
///
/// 方式一:插值范围比较大
/// var lerp = Mathf.PingPong(Time.time, time)
/// 如果time = 2,那么2秒之内,插值系列从0运行到2,然后从2运行到0,Time.time只作为一个时间轴,呼吸的动画在时间轴的切片内循环进行
///
/// 方式二:插值的范围为[0,1]呼吸时间为time指定的值
/// var lerp2 = Mathf.PingPong(Time.time, time) / time
/// 如果time = 2,那么2秒之内,插值系列从【0 / 2 = 0】运行到【2 / 2 = 1】,然后从【2 / 2 = 1】 运行到【0 / 2 = 0 】
///
/// 【使用场景】:
/// 1、物体(3D物体,2D物体)由大到小变化
/// 2、颜色渐变
/// 3、灯光强弱
/// 4、其它:用该呼吸系数值进行各种操作,比如一个弹簧的拉长和缩短等等
/// </summary>
public class pingPong : MonoBehaviour
{
/// <summary>
/// 呼吸开关
/// </summary>
[Header("呼吸开关")]
[SerializeField]
public bool OnOff;
/// <summary>
/// 单次渐变的时间【一个完整的周期为一呼一吸,包含两次渐变(小 -> 大,大 -> 小,...)】
/// </summary>
[Header("单次渐变的时间,单位秒")]
[SerializeField]
public float time;
/// <summary>
/// 呼吸动画的的物体
/// </summary>
[Header("缩放的物体")]
[SerializeField]
public GameObject go;
[Header("插值的观察窗口")]
public float testValue;
/// <summary>
/// 原始的scale值
/// </summary>
private Vector3 startScale;
// Start is called before the first frame update
void Start()
{
startScale = go.transform.localScale;
}
// Update is called once per frame
void Update()
{
if(OnOff == true)
{
/*
var lerp = Mathf.PingPong(Time.time, time)
如果time = 2,那么2秒之内,插值系列从0运行到2,或者从2运行到0,Time.time只作为一个时间轴,呼吸的动画在时间轴的【等分段,用变量time来等分】内循环进行
var lerp2 = Mathf.PingPong(Time.time, time) / time
如果time = 2,那么2秒之内,插值系列从【0 / 2 = 0】运行到【2 / 2 = 1】,然后从【2 / 2 = 1】 运行到【0 / 2 = 0 】
*/
//测试代码
testValue = Mathf.PingPong(Time.time, time) / time;
ChangeScale(go, startScale, testValue);
ChangeColor(GoToChangeColor, startColor,endColor,testValue);
ChangePosition(GoToChangePos, startPos.transform.position,endPos.transform.position,testValue);
}
else
{
// do nothing
}
}
/*======================以下是测试脚本========================*/
/// <summary>
/// scale渐变动画
/// </summary>
/// <param name="go"></param>
/// <param name="originScale"></param>
/// <param name="lerpValue"></param>
void ChangeScale(GameObject go,Vector3 originScale,float lerpValue)
{
go.transform.localScale = originScale * lerpValue;
}
[Header("改颜色的物体")]
public GameObject GoToChangeColor;
[Header("初始颜色")]
public Color startColor;
[Header("终止颜色")]
public Color endColor;
/// <summary>
/// 颜色插值渐变动画
/// </summary>
/// <param name="go">改颜色的物体</param>
/// <param name="startColor">初始颜色</param>
/// <param name="endColor">终止颜色</param>
/// <param name="lerpValue">渐变进度</param>
void ChangeColor(GameObject go,Color startColor,Color endColor,float lerpValue)
{
go.GetComponent<Renderer>().materials[0].color = Color.Lerp(startColor, endColor, lerpValue);
}
[Header("改位置的物体")]
public GameObject GoToChangePos;
[Header("初始位置")]
public GameObject startPos;
[Header("结束位置")]
public GameObject endPos;
/// <summary>
/// Vector3向量插值渐变动画
/// </summary>
/// <param name="go">改位置的物体</param>
/// <param name="startPos">初始位置</param>
/// <param name="endPos">结束位置</param>
/// <param name="lerpValue">位置变换进度</param>
void ChangePosition(GameObject go ,Vector3 startPos,Vector3 endPos,float lerpValue)
{
go.transform.position = Vector3.Lerp(startPos, endPos, lerpValue);
}
}