跳转至

[Unity学习随笔3.15]quard的trigger属性,SmoothDamp函数

BUG记录:

NullReferenceException: Object reference not set to an instance of an object

可能是脚本中的对象未绑定(或者对象改名后忘记重新绑定)


img

Quard中的该属性: 用来虚化/实化空间及判断空间是否被入侵, 可拓写相应的触发函数

private void OntriggerEnter( ){ } 进入该空间
private void OntriggerStay( ){ } 在该区域停留
private void OntriggerExit( ){ } 离开该区域

img


getaxis的horizal和vertical只适用于键盘,对多设备输入的支持不灵活

GetAixs对设备的支持可以在edit -> projectsetting -> inputmanager设定

SmoothDamp可以使按键变动的信号过渡更加平缓自然

public class PlayerInput : MonoBehaviour
{
    public string keyUp = "w";
    public string keyDown = "s";
    public string keyLeft = "a";
    public string keyRight = "d";

    public float Dup;
    public float Dright;

    public bool inputEnabled = true;

    private float targetDup;
    private float targetDright;
    private float velocityDup;
    private float velocityDright;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        targetDup = (Input.GetKey(keyUp) ? 1.0f : 0) - (Input.GetKey(keyDown) ? 1.0f : 0);
        targetDright = (Input.GetKey(keyRight) ? 1.0f : 0) - (Input.GetKey(keyLeft) ? 1.0f : 0);

        if (inputEnabled == false)
        {
            targetDup = 0;
            targetDright = 0;
        }

        Dup = Mathf.SmoothDamp(Dup, targetDup, ref velocityDup, 0.1f);
        Dright = Mathf.SmoothDamp(Dright, targetDright, ref velocityDright, 0.1f);

    }
}

Unity中Lerp与SmoothDamp函数使用误区浅析

[专栏作家]Unity中Lerp与SmoothDamp函数使用误区浅析 (sohu.com)

Unity的Lerp和SmoothDamp这两个函数我们在处理物体移动、一些渐进变化或者摄像机的跟随等场景会较常用到,虽然Mathf、Vector2、Vector3等都有这两个函数,但用法上是基本一样的,用起来也比较简单。不过在实际的运用中,往往一不小心却会掉进坑里,下面我们一起来分析一下。

1

Lerp函数

Lerp函数使用的最常见的误区是把线性移动用成了弹性移动(关键是自己还不知道,还奇怪,咦,不是说好的线性移动吗?怎么有点弹性的赶脚……),如下图所示:

img

这样子的代码一般是这么写的:

img

这个错误主要是没有理解好Lerp的第三个参数t的作用,这里我们为了便于理解,我们拿Mathf.Lerp函数来分析,思路是一样的。我们先来看一下Mathf.Lerp函数的具体实现:

img

img

估计大家一看函数的实现就明白了关键点,想要线性移动,应该只控制t的变化,t的值在0-1,它就类似一个百分比的值,代表着a点到b点之间的位置,比如想要到a和b之间的3/10的位置,t就应该是0.3,想要一步到位t的值就应该为1。在上述错误的用法中,实际的效果就是第一次到达1/10位置,第二次到达1/10+9/10*1/10的位置……理论上讲永远到不了b点,每一次都是a与b点之间的1/10的位置,所以移动的幅度越来越小,有一种弹性感觉。正确的使用方法如下:

img

效果如下:

img

2

SmoothDamp函数

SmoothDamp函数在使用过程中比较容易出现的一个问题就是容易在代码较复杂的情形下将currentVelocity这个参数需要的变量定义为局部变量,如下:

img

使用局部变量的效果如下图所示,越来越慢,定义的平滑时间明明是0.3f,怎么用了10几秒的时间都还在缓慢移动?

img

为了便于理解,我们来看一下Mathf.SmoothDamp的具体实现:

img

通过具体的实现我们就可以很清楚的发现,currentVelocity这个变量是先使用,然后再赋值,通过ref传递就是为了获取到上一次计算得到的速度值,如果我们使用局部变量,每一次速度都是零,相当于刚开始进行平滑移动,平滑的距离(transform.position到target)不断在缩短,然而平滑时间却没有变化,为了保证大约在平滑的时间内完成平滑移动,这个起步速度肯定是越来越慢的,所以就导致了上图中的问题。

我们把currentVelocity改为全局变量,就可以看到正常效果了

img

效果如下:

img

评论