Unity C#脚本实现场景中物体的左右往返移动同时上下浮动
Unity小白第一次写博客,里面的代码参考了一些文章,链接如下:
Unity中实现游戏物体来回移动的方法 https://blog.csdn.net/qq_39347046/article/details/88074897
Unity —— Vector3https://blog.csdn.net/qq_19428987/article/details/91445273
unity笔记3 - Mathf.Repeat and Mathf.PingPong https://blog.csdn.net/qq_15505341/article/details/79251558
最终代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cloudMove : MonoBehaviour
{
// Start is called before the first frame update
/// 弧度
public float radian;
/// 上下变化幅度
public float moveAmplitude = 5f;
/// 初始位置
private Vector3 oldPos;
//随时间变化的PingPong左端的值,使物体移动
float i = 0;
void Start()
{
//获取物体原位置
oldPos = transform.position;
}
// Update is called once per frame
void Update()
{
//通过Time.deltaTime每帧改变弧度的值
radian += Time.deltaTime;
//每帧增加相应的i值
i += 0.1f;
//newY值是通过cos函数实现的y轴上下浮动的值
float newY = Mathf.Cos(radian) * moveAmplitude;
//l值是通过PingPong方法实现的x轴水平移动的值
float l = Mathf.PingPong(i,150);
//通过Vetor3与l值和newY值相乘得到的坐标变化量加上原坐标可以得到新的位置
transform.position = oldPos + Vector3.up * newY + Vector3.left * l;
}
}
其中左右移动的部分主要使用了PingPong的方法,上下的浮动使用三角函数。
一、unity中物体往返移动的方法
1.判断边界值改变方向
public class UpDown3 : MonoBehaviour
{
public float speed = 3;
void Update()
{
transform.position += Vector3.up * speed * Time.deltaTime;
//超出范围
if (transform.position.y>=10 || transform.position.y <= -10)
{
//反向
speed = -speed;
}
}
}
2.设定两个临界点,插值移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UpDown2 : MonoBehaviour
{
/// 插值比例
public float t;
/// 是否向上移动
public bool isUP = true;
/// 临界点1
public Vector3 startPos = new Vector3(0, -3, 0);
/// 临界点2
public Vector3 endPos = new Vector3(0, 3, 0);
/// 移动速度
private float speed = 3;
void Update()
{
t += Time.deltaTime;
if (isUP)
{
transform.position = Vector3.Lerp(transform.position, endPos, t * speed);
if (transform.position.y >= endPos.y)
{
isUP = false;
t = 0;
}
}
else
{
transform.position = Vector3.Lerp(transform.position, startPos, t * speed);
if (transform.position.y <= startPos.y)
{
isUP = true;
t = 0;
}
}
}
}
3.PingPong方法
Vector3 start;
float i = 0;
void Start () {
start = transform.position;
}
void Update () {
i += 0.1f;
float l = Mathf.PingPong(i,5);
transform.position = start + Vector3.left * l;
}
PingPong方法左端的数字需要自己实现增加或减少,如可以使用Time.time和Time.unscaledTime。右侧为length,个人理解为临界值。
PingPong方法的数学原理参考:unity数学函数mathf.PinPong的实现原理
4.三角函数实现浮动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UpDown : MonoBehaviour
{
/// 弧度
public float radian;
/// 上下变化幅度
public float moveAmplitude = 5f;
/// 初始位置
private Vector3 oldPos;
void Start()
{
oldPos = transform.position;
}
void Update()
{
radian += Time.deltaTime;
float newY = Mathf.Cos(radian) * moveAmplitude;
transform.position = oldPos + Vector3.up * newY;
}
}
二、Vector3向量
Vector3向量,在三维坐标系中带有方向和大小的数据
经常在程序中使用Vector3向量,但是一直没有详细了解,就对于它的方向和值都很不清楚,所以这次简单总结了一下,方便以后查询使用。
Vector3中一些常量:(经常用来移动物体坐标)
Vector3.back=(0,0,-1)
Vector3.forward=(0,0,1)
Vector3.left=(-1,0,0)
Vector3.right=(1,0,0)
Vector3.down=(0,-1,0)
Vector3.up=(0,1,0)
Vector3.zero=(0,0,0)
Vector3.one=(1,1,1)
其他:
Vector3.Angle() :向量之间的夹角,返回两个向量之间较小的角度(在旋转计算中常常用到)
Vector3.Cross() :叉积,返回垂直于a,b,两个向量所在平面的另一个向量,长度|c|=|a||b|sin<a,b>
Vector3.Dot():点积,a·b=|a|·|b|cos<a,b>(是一个标量,只有大小,没有方向)
Vector3.Distance():求两点之间的距离,(范围判断中使用)
Vector3.Lerp() :插值运算,一般用于平滑处理,比如摄像机的缓慢移动、导弹的追踪等
Vector3.MoveTowards():沿着目标移动,
Vector3.Normalize():向量单位化,方向一致,大小为单位1
Vector3.Project():向量投影,求一个向量在另一个向量方向上的投影
Vector3.Slerp():球形插值
三、Mathf.Repeat & Mathf.PingPong & Mathf.Clamps
1.Mathf.Repeat
主要效果是重复,(类似于循环动画)
例:输出为012012012012012012012
//输入 012345678
//输出 012012012
for (int i = 0; i < 9; i++)
{
Debug.Log(Mathf.Repeat(i,3));
}
例:用Repeat控制Cube在场景中运动
Vector3 start;
float i = 0;
void Start () {
start = transform.position;
}
void Update () {
i += 0.1f;
//变量l的值只会在0-4.9之间循环循环循环,所以方块就一直循环循环的动了
float l = Mathf.Repeat(i,5);
transform.position = start + Vector3.left * l;
}
2.Mathf.PingPong
主要效果是往复运动
例:输出为0123210123210123210123
//输入012345678
//输出012321012
for (int i = 0; i < 9; i++)
{
Debug.Log(Mathf.PingPong(i,3));
}
例:用PingPong方法控制物体在场景中往复连贯运动
Vector3 start;
float i = 0;
void Start () {
start = transform.position;
}
void Update () {
i += 0.1f;
//变量l的值只会在0-4.9之间来回来回
float l = Mathf.PingPong(i,5);
transform.position = start + Vector3.left * l;
}
3.Mathf.Clamps
限制value的值在min和max之间, 如果value小于min,返回min。 如果value大于max,返回max,否则返回value
这个函数比较常用, 在处理角色移动时,常常需要去限制他们。