精华内容
下载资源
问答
  • unity Mathf.Lerp做匀速移动

    千次阅读 2019-01-20 13:30:33
    首先,上述“误用”是这样工作的:每帧都重新获取物体当前的位置,计算物体和目标距离的差距,再按照当前帧的持续时间(当做一个百分比)来移动这个比例的位置。因此如果目标位置始终是固定的,那么整体运动是缓动的...

    Lerp函数在Mathf,Vector3, 等类中都有,用法都类似,作用都是按照百分比取得从一个值过度到另外一个值的中间值。下面说的内容针对各中类的Lerp函数都是通用的。

    Lerp的常见“误用”是
    Update()
    {
    Transform.position = Vector3.Lerp(transform.position.x, targetPosition, Time.deltaTime);
    }

    说是“误用”,其实也不完全正确,这种用法是可以工作的,但是常常不是大家的真正需求,很多时候大家使用Lerp都是想达到匀速运动的效果,但如下“误用”却让对象以逐渐降低的速度运动。

    首先,上述“误用”是这样工作的:每帧都重新获取物体当前的位置,计算物体和目标距离的差距,再按照当前帧的持续时间(当做一个百分比)来移动这个比例的位置。因此如果目标位置始终是固定的,那么整体运动是缓动的,先快后慢。这样的效果乍一看还不错,但其实是有一些问题的:因为每秒钟都以固定的比例靠近目标位置,所以运动速度会以固定的比例逐渐降低,只要运算精度够高,运动永远达不到目标,且运算始终在进行。如果确实需要这样做,那么我们需要加上一个阈值,当与目标距离小于这个阈值时,就直接把物体的位置设置为目标位置。这个阈值的大小设置要合适,太大了在后面阶段会感觉到明显的跳跃,太小了会浪费运算时间。

    这里说明一下,如果上述效果就是我们想达到的目标,那么用Time.deltaTime作为第三个参数在这个情况下是有道理的,因为每帧时间不同,为了保证单位时间内运动的百分比是一致的(达到平滑缓动的效果),需要用Time.deltTime介入。

    如果你是误打误撞实现了缓动效果,并且觉得效果不错就没有再深究了,那么建议你继续往下看看。

    用Lerp来实现匀速运动的代码
    先看代码:

    float speed = 2.0f;

    //什么时候开始运动
    float startTime = 2.0f;

    //起始X位置
    float startX = 0.0f;

    //结束X位置
    float endX = 10.0f;

    void Update()
    {
    float lerpValue = Mathf.Lerp(startX,endX,(Time.time-startTime )* speed);
    transform.position = new Vector3(lerpValue,0,0);
    }

    一定要理解清楚Mathf.Lerp(float a, float b, float t)第三个参数t的意义,它是一个百分比,最小值有效值是0,最大有效值是1,如果超出了1,就取1,小于0则取0.

    它表示从a到b之间,按照t这个百分比来取值,例如a是0,b是100,如果t是0.2,则该函数返回的值是20,如果t是1,该函数返回的值为100.

    匀速运动的要点是起始值和结束值都是固定好的,不会随着运动而发生变化。

    Time.time就是系统运行时间,也就是这个程序开始到现在的时长。

    (Time.time - startTime),上面例子中startTime是2.0f,那么这个式子的取值一开始是-2,2秒时变成0,3秒时变成1,先假设没有乘以speed这个值,整个运动过程会在2秒开始,3秒结束。

    物体运动的速度是距离差(在本例中是10.0f)除以1秒。乘以一个speed以后,实际上是在调整整体的运动时间。
    假设speed为0.1f,则运动的时间变为2秒开始12秒结束,运行时间变成了10s,则速度变成原先的1/10,
    同理,假设speed 为10f,则运动时间变为2秒开始2.1秒结束,速度变成原先的10倍。

    展开全文
  • 在使用Unity开发时,有时会使用到物体以指定的速度匀速移动至目标点这个功能,用着的DOTween插件里也没有这个功能,本来想在网上搜索找个现成的来使用来着,但没找着合适的… … 所以自己写了个. 方法 /// <summary&...

    前言

    在使用Unity开发时,有时会使用到物体以指定的速度匀速移动至目标点这个功能,用着的DOTween插件里也没有这个功能,本来想在网上搜索找个现成的来使用来着,但没找着合适的… … 所以自己写了个.

    方法

        /// <summary>
        /// 当前物体以指定的速度匀速移动至目标点
        /// </summary>
        /// <param name="self"></param>
        /// <param name="target"></param>
        /// <param name="speed"></param>
        /// <param name="onComplete"></param>
        /// <param name="onUpdate"></param>
        /// <returns></returns>
        public static IEnumerator IEConstanSpeedMove(this Transform self, Vector3 target, float speed, Action onComplete = null, Action onUpdate = null)
        {
            while (self.position != target)
            {
                self.position = Vector3.MoveTowards(self.position, target, speed * Time.deltaTime);
                onUpdate?.Invoke();
                yield return 0;
            }
            onComplete?.Invoke();
        }
    

    采用携程的方式便于随时控制取消,而且可以添加位置更新和完成时的回调函数;

    测试

    using UnityEngine;
    
    public class NewBehaviourScript : MonoBehaviour
    {
        public Vector3 target = new Vector3(0, 6, 0);
        public float speed = 2;
    
        float t;
    
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                StopAllCoroutines();
                transform.position = Vector3.zero;
                t = 0;
                StartCoroutine(transform.IEConstanSpeedMove(target, speed, () =>
                {
                    print("运动完成,当前位置:" + transform.position + "总用时:" + t);
                }, () =>
                {
                    print("当前位置:" + transform.position);
                    t += Time.deltaTime;
                }));
            }
        }
    }
    

    补充

    当前我这个方法是以物体position操作进行匀速目标点移动的.
    如果想通过以物体的localPosition来操作进行移动的话可以把localPosition的目标点转换为position就可以了.
    例如:如果物体想localPosition移动至new Vector3(8,0,0)的话,采用 target=transform.parent.TransformPoint(new Vector3(8, 0, 0))方法转换为position后再采用那个方法就好了.

    展开全文
  • Unity 使用Lerp实现匀速移动

    千次阅读 2021-01-27 16:40:59
    Unity 使用Lerp实现匀速移动 众所周知,使用Lerp差值进行运算,Lerp中第三个参数其实就是两个值差值的百分比,所以如果直接用一个固定值得话,就导致值得变化速率越来越慢,呈现出来的效果就是一段路程下,越来越慢...

    Unity 使用Lerp实现匀速移动

    使用Lerp差值进行运算,Lerp中第三个参数其实就是两个值差值的百分比,所以如果直接用一个固定值得话,就导致值得变化速率越来越慢,呈现出来的效果就是一段路程下,越来越慢,搜了很多的博客,基本上实现是通过时间改变每次的百分比(如下图),我在用的时候,发现还是会出现速度不均匀的问题,可能是时间没有计算好。
    在这里插入图片描述
    而我想是直接用一个可控的百分比控制,根据Speed*Time.DeltaTime和这一帧物体位置到目的地的距离的比值,得到一个相对原速率的百分比 ,这样可以达到一个匀速的目的,并且会先判断此帧运行的距离是否会大于物体到目的地的距离,如果大于,就设置物体的位置为目的地的位置,如果不大于,就使用差值,代码如下:挂载到移动的物体上,并设置路径点
    在这里插入图片描述

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Move : MonoBehaviour
    {
        public List<Transform> Path;
        int Index = 0;
        public float Speed = 2;
        float framSpeed = 0;//每帧所走的百分比
        void Start()
        {
           
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Index >= Path.Count) return;
            framSpeed = Time.deltaTime * Speed;
            float dis = Vector3.Distance(transform.position, Path[Index].position);
            float pross = 0;
            if (framSpeed > dis)
            {
                transform.position = Path[Index].position;
            }
            else
            {
                pross = framSpeed / dis;
                transform.position = Vector3.Lerp(transform.position, Path[Index].position, pross);
            }
            dis = Vector3.Distance(transform.position, Path[Index].position);
            if (dis <= 0.1f && Index < Path.Count)
            {
                Index++;
            }
        }
    }
    
    
    展开全文
  • Unity的几种移动和旋转方法

    千次阅读 2020-06-12 21:54:34
    C#中提供了非常丰富的移动代码工具,通过这些工具我们可以实现:匀速移动、变速移动、自定义变速移动等移动方式。 基础框架 实现一个Unity中可以挂接的类包含的基本框架是: using System.Collections; using System...

    Unity的移动

    在制作一款游戏的时候,经常需要对物体的位置进行移动,我们希望这个移动是具有多样性的,并且可操作的。

    C#中提供了非常丰富的移动代码工具,通过这些工具我们可以实现:匀速移动、变速移动、自定义变速移动等移动方式。

    基础框架

    实现一个Unity中可以挂接的类包含的基本框架是:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class VecMove : MonoBehaviour
    {
        private void Start()
        {
            //代码初始时调用
        }
    
        private void Update()
        {
            //每帧调用一次
        }
    
        // 本次博文中使用的
        private void OnGUI()
        {
            // 每帧调用一次,用于GUI操作的判断
        }
    
    }
    

    == 为了更加直观的展示移动,本次博文在OnGUI中调用移动方法,通过点击移动按钮查看移动过程 ==

    更一般的情况,可能是在Updat()中调用。
    注意!下面的方法填充在OnGUI()中。

    匀速移动

    if(GUILayout.RepeatButton("匀速移动"))
    {
        this.transform.position = Vector3.MoveTowards(objectPos, targetPos, moveFactor);
    }
    

    点击移动按钮即可实现匀速移动,其中objectPos是当前物体的位置,targetPos是目的物体的位置,moveFactor是每一帧移动的距离。

    变速移动

    if(GUILayout.RepeatButton("变速移动"))
    {
        this.transform.position = Vector3.Lerp(objectPos,targetPos, moveFactor);
    }
    

    从objectPos 移动到 -> targetPos ,每次移动的距离是二者distance*moveFactor的距离。

    当前物体的位置一直在靠近目标位置,因此这个移动距离不断变小,并且永远不可达,只能无限靠近。

    自定义变速运动

    public AnimationCurve curve;        // x轴是移动时间,y轴是移动量
    public float x;
    if(GUILayout.RepeatButton("自定义变速"))
    {
        x += Time.deltaTime / moveDalayTime;
        this.transform.position = Vector3.Lerp(objectPos, targetPos, curve.Evaluate(x));
    }
    if(GUILayout.RepeatButton("自定义变速2"))
    {
        x += Time.deltaTime / moveDalayTime;
        this.transform.position = Vector3.LerpUnclamped(objectPos, targetPos, curve.Evaluate(x));
    }
    

    可以在Unity界面自定义移动曲线

    1. 其中curve设置为public,可以在unity界面进行设置曲线
      在这里插入图片描述
      2.这个曲线如果设置成如下的样子:(超过终点,再回来)
      在这里插入图片描述

    使用Vector3.Lerp会默认到达目的地为最终结果
    使用Vector3.LerpUnclamped会严格按照曲线运动,超过目的地再回来

    最终代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 
    /// </summary>
    public class VecMove : MonoBehaviour
    {
        private Vector3 targetPos = new Vector3(0, 0, 10);
        public float moveFactor = 0.1f;
        public AnimationCurve curve;        // x轴是移动时间,y轴是移动量
        public float moveDalayTime = 1.0f;  // 移动到目的地花费的时间
        private float x;
        private Vector3 objectPos;
        private Vector3 originPos;
        void Start()
        {
            objectPos = this.transform.position;
            originPos = this.transform.position;
        }
    
        void Update()
        {
        }
        void OnGUI()
        {
            if(GUILayout.RepeatButton("复位"))
            {
                objectPos = this.transform.position;
                this.transform.position = originPos;
                x = 0;
            }
            if(GUILayout.RepeatButton("匀速移动"))
            {
                objectPos = this.transform.position;
                this.transform.position = Vector3.MoveTowards(objectPos, targetPos, moveFactor);
            }
            if(GUILayout.RepeatButton("变速移动"))
            {
                this.transform.position = Vector3.Lerp(objectPos,targetPos,moveFactor);
            }
            // 起点固定,终点固定,运动根据曲线来
            if(GUILayout.RepeatButton("自定义变速"))
            {
                x += Time.deltaTime / moveDalayTime;
                this.transform.position = Vector3.Lerp(objectPos, targetPos, curve.Evaluate(x));
            }
            // 上面的是超过终点就算是终点,如果想要超过终点还能回来,就使用下面的方法
            if(GUILayout.RepeatButton("自定义变速2"))
            {
                x += Time.deltaTime / moveDalayTime;
                this.transform.position = Vector3.LerpUnclamped(objectPos, targetPos, curve.Evaluate(x));
            }
        }
    }
    
    

    Unity的几种旋转方法

    接上一节的移动方法,这里列举几种常用的旋转方法
    因为和移动用到的工具原理基本类似,不在赘述,感兴趣的同学可以自己将代码挂接在物体上实验

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 
    /// </summary>
    public class QuternionRotate : MonoBehaviour
    {
        public Transform targetTF;
    
        private void OnGUI()
        {
            if(GUILayout.Button("让摄像机转向目标物体"))
            {
                Vector3 direction = targetTF.position - this.transform.position;
                this.transform.rotation = Quaternion.LookRotation(direction);
            }
            if(GUILayout.RepeatButton("使用Lerp控制旋转速度"))
            {
                Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
                this.transform.rotation = Quaternion.Lerp(this.transform.rotation, dir, 0.01f);
            }
            if(GUILayout.RepeatButton("匀速旋转"))
            {
                Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
                this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation,dir,1f );
            }
            if(GUILayout.RepeatButton("right"))
            {
                this.transform.right = targetTF.position - this.transform.position;
                // Quaternion dir = Quaternion.LookRotation(targetTF.position - this.transform.position);
                // this.transform.rotation = dir;
            }
            if(GUILayout.RepeatButton("right2"))
            {
                Vector3 dir = targetTF.position - this.transform.position;
                this.transform.rotation = Quaternion.FromToRotation(Vector3.right, dir);
            }
        }
    
    
    }
    
    展开全文
  • Unity2D的自学过程中遇到一个问题,对方角色在施展某个具有跟踪效果的技能时,我希望该技能始终指向主角的位置。 查询了不少资料都没有找到比较好用的解决方法,最终决定用正切角的方式求出夹角,然后再让...
  • 挂载到需要移动到物体上 using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move2 : MonoBehaviour { //定义单例,使外部可访问 public static Move2 instance {...
  • Unity3d物体沿着折线匀速移动,移动过程中物体自动改变朝向。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class WayPoints : MonoBehaviour { // put the points ...
  • Vector3.Lerp和itween插件路径算法并不是需要的效果,在目标点转换的时候使用这两个方法并不会匀速,两点间的距离越大速度就越快,我对itween的算法还不太了解,现在我着重解释一下怎么用Vector3.Lerp解决“变速”的...
  • Unity iTween的匀速运动

    千次阅读 2019-02-01 15:08:20
    iTween.MoveTo(gameobject, iTween.Hash("x", 0, "y", 0f, "z", -2000f, "time", 1f, "islocal", true, "...重点是EaseType 的模式 linear 表示线性运动
  • using UnityEngine; using System.Collections; public class CameraFollow : MonoBehaviour {    public Transform target;  private Vector3 wantedPosition;    private flo
  • unity移动的九种方法

    千次阅读 2019-05-10 17:32:20
    第一就是单纯的控制物体移动 从一个位置移动到另一个位置 transform.position += new Vector3(0, 0, 10);...第三种Vector3 .MoveTowards 有目标点的匀速运动,到达目标点的时候一 直运动。 transform.posit...
  • 法一:使用Vector3.MoveTowards()方法 void Update(){ float step = Speed*Time.deltaTime(); gameObject.transform.localPosition = Vector3.MoveTowards(gameObject.transform.localPosition, new Vector3(0, 0,...
  • Unity键盘控制物体移动

    千次阅读 2018-01-11 11:12:49
    using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move : MonoBehaviour { public float speed = 2f; private Rigidbody rigidbody;... // Use this for initi
  • SmoothDamp平滑缓冲移动,多用于摄像机移动 transform.position = Vector3.SmoothDamp(transform.position, endPos, ref velocity, Time.deltaTime); Lerp,每次移动为到目标点的剩余距离的n% transform....
  • 如何在unity中控制物体按照表格中的坐标进行运动? 现在已经在Start中将Excel里的坐标读取到一个二维数组中, 接下来我想的是采用fixedupdate,设定固定时长为0.2秒, 每次更新的时候采用transform.position将...
  • 方法一 private IEnumerator MoveTo(Transform tr, Vector3 pos, float time) { float t = 0; while(true) { t += Time.deltaTime;... float a = t/ time;... tr.position = Vector3.Lerp(tr.position, pos, a.
  • Unity 向目标移动,并朝向目标 var direction = Target.position - transform.position;//目标方向 ...//向目标方向移动,normalized归一实现匀速移动 var angle = Vector3.Angle(transform.forward,
  • Unity 使用DoTween

    千次阅读 2016-10-26 13:53:07
    我看过UGUI的Demo它的实现方式是用Animator来做的,这样每一个需要移动的对象就要挂上一个AmimationController并且还要去编辑动画。。 想想都恐怖,我觉得真没必要那么做。。 我强烈建议新项目使用DoTween。...
  • Unity开发中我们难免要使用代码控制角色的移动,现将已知的几种方法总结如下: 一、transform.Translate() functionTranslate(translation:Vector3,relativeTo:Space=Space.Self) : void 沿着Translation的方向...
  • Unity编辑器场景相机匀速运动
  • unity实现物体移动固定距离

    千次阅读 2019-03-05 11:19:16
    using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player1Control : MonoBehaviour { // private Rigidbody2D playerRig; public float speed;...
  • 可视化调节 曲线运动插件 Untiy C#
  • [Unity2D]在2D游戏里面实现人物的移动 一般的Unity2D游戏中 用WASD控制来移动人物角色的移动 缺陷:与含有碰撞器的强行碰撞时会发生抖动 原因:例如我人物要向左边走,利用脚本获取键盘输入,给人物角色一个向左边的...
  • Unity3D 路径的编辑与跟随路径的移动脚本的编写。
  • Unity中物体移动方法详解

    万次阅读 多人点赞 2019-03-11 14:37:13
    一.Transform 1.transform.Translate不会考虑到碰撞。 transform.Translate(Vector...2.transform.position我认为Transform严谨来说并不能称作移动,而是直接改变物体的坐标。 transform.position(vector3 target...
  • Unity 控制物体移动的一些方法

    千次阅读 2019-07-16 10:40:57
    Unity3D中一些控制物体移动的方法, 匀速移动, 加速移动, 物理运动等
  • Unity3d 控制物体transform移动的几种方法

    万次阅读 多人点赞 2017-03-19 23:36:27
    Unity开发中我们难免要使用代码控制角色的移动,现将已知的几种方法总结如下: 一、transform.Translate() function Translate (translation : Vector3, relativeTo : Space = Space.Self) : void ...
  • unity移动摄像机时物体闪烁模糊

    千次阅读 2014-08-08 14:29:46
    第一视角在场景中漫游时,前方的贴图总是闪烁,
  • unity里对象的移动

    2019-05-09 19:23:34
    position +=一个三维向量 位置 改变x y z 移动、 ... Vector3 .MoveTowards 有目标点的匀速运动,到达目标点的时候一直运动 Vector3.Lerp线型差值移动,初始点到最总点的差值 差值:10 5 2.5 1.2...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 616
精华内容 246
关键字:

unity匀速移动