云朵左右移动上下漂浮

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

这个函数比较常用, 在处理角色移动时,常常需要去限制他们。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值