Sin函数的实践
一、背景
游戏开发中使用正弦函数这是家常便饭的事情,比如一个河流的移动效果,就可以考虑在Shader中使用正弦函数对顶点进行操作;要想实现的效果好就需要对相关函数的本质效果有一个比较好的了解,所以本文采用Unity来实践一下;
二、效果
上面两幅效果图就是通过Unity实践的运行结果,具体实现都在下文的代码里面
三、源码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ValakiSinDemo : MonoBehaviour
{
[SerializeField]
GameObject target;
bool isTrigger;
public enum DrawType
{
Normal,
ScaleVerticalA, //乘以2
ScaleVerticalB, //乘以-2
ScaleHorizonalA,//乘以2
ScaleHorizonalB,//乘以-2
}
LineRenderer lineRenderer;
[SerializeField] DrawType drawType = DrawType.Normal;
int totalPosCnt = 3500;
// Start is called before the first frame update
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.positionCount = totalPosCnt;
}
/// <summary>
/// 累加时间
/// </summary>
float time;
/// <summary>
/// 绘制索引
/// </summary>
int drawIndex = 0;
/// <summary>
/// 移动索引
/// </summary>
int moveIndex = 0;
/// <summary>
/// 绘制状态
/// </summary>
bool isDrawOver;
/// <summary>
/// 是否移动状态
/// </summary>
bool isStartMove;
bool isRewind;
private void Update()
{
DrawCureLine();
if (isDrawOver && !isStartMove && target != null)
{
MoveTarget();
}
}
void DrawCureLine()
{
if (drawIndex < totalPosCnt)
{
float x = 0;
float y = 0;
time += Time.deltaTime;
x = time;
switch (drawType)
{
case DrawType.Normal:
y = Mathf.Sin(x);
break;
case DrawType.ScaleVerticalA:
y = Mathf.Sin(x) * 2 + 12;
break;
case DrawType.ScaleVerticalB:
y = Mathf.Sin(x) * -2 + 6;
break;
case DrawType.ScaleHorizonalA:
y = Mathf.Sin(x * 2) - 6;
break;
case DrawType.ScaleHorizonalB:
y = Mathf.Sin(x * -2) - 12;
break;
}
lineRenderer.SetPosition(drawIndex, new Vector3(x, y, 0));
drawIndex++;
}
else
{
isDrawOver = true;
}
}
void MoveTarget()
{
if (moveIndex < totalPosCnt && !isRewind)
{
Move();
moveIndex++;
if (moveIndex >= totalPosCnt)
isRewind = true;
}
else
{
moveIndex--;
Move();
if (moveIndex <= 0)
isRewind = false;
}
}
void Move()
{
target.transform.position = Vector3.Lerp(target.transform.position, lineRenderer.GetPosition(moveIndex), 1);
}
}