Блог программиста
Математика Unity (Урок 10). Mathf сравнение и сглаживания.
28.07.2013Математика Unity

Сравнение

В Unity, в связи с неточностью чисел типа float, не рекомендуется использовать точное сравнение. Например:
if(2.0f == 10.0f/5.0f)
	Debug.Log(true);
else
	Debug.Log(false);

Может не всегда выводить «true». Поэтому лучше использовать функцию приблизительного сравнения:
Mathf.Approximately (float a, float b)	//Приблизительное сравнение

Пример будет выглядеть так:
if(Mathf.Approximately(2.0f, 10.0f/5.0f))
	Debug.Log(true);
else
	Debug.Log(false);

В данном случае всегда будет выводить «true».

Сглаживание 1

Первая функция сглаживания в Unity (C#):
Mathf.SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime)		//Сглаживание

Данная функция постепенно приводит значение к значению target.
current Текущее значение
target Целевое значение
currentVelocity Текущая скорость изменения (значение переменной изменяется в функции)
smoothTime Примерное время, для достижения цели
maxSpeed Максимальная скорость изменения (по умолчанию бесконечность)
DeltaTime Время прошедшее с момента последнего вызова функции (по умолчанию Time.deltaTime)

Применение

Изменим пример из предыдущего урока:

using UnityEngine;

public class SmoothPos : MonoBehaviour {
		
	//Цель (пункт Б)
	public Transform target;
	//Текущая скорость
	public float currentVel = 0;
	// Update is called once per frame
	void Update ()
	{
		//Новая позиция по оси Z
		float _z = Mathf.SmoothDamp(transform.position.z, target.position.z, ref currentVel, 1);
		//Устанавливаем новую позицию
		transform.position = new Vector3(transform.position.x, transform.position.y, _z);
	}
}

В данном случае персонаж доберётся из точки А в точку Б за одну секунду. Можно другое время, чтобы персонаж двигался медленнее/быстрее (например 60, тогда он доберётся за одну минуту).

Сглаживание 2

Вторая функция сглаживания в Unity (C#):
Mathf.SmoothDampAngle (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime)	//Сглаживание от -180 до 180

Постепенно приводит значение угла к значению target.

К практике

Изменим пример из предыдущего урока:
using UnityEngine;

public class SmoothRot : MonoBehaviour {
	
    //Угол поворота, к которому стремимся
    public float targetAngle = 90.0f;
    //Текущая скорость
    public float currentVel = 0;
	
    void Update()
    {
	//Получаем новый угол поворота по оси Y
        float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref currentVel, 1);
        //Устанавливаем новый угол
        transform.eulerAngles = new Vector3(transform.rotation.x, angle, transform.rotation.z);
    }
}

Персонаж повернётся за 1 секунду.

Конец.
P.S. Если что-то не понятно, пишите в комментариях.

21031