mathf abs unity что такое
Mathf abs unity что такое
В этом уроке мы рассмотрим простые, но довольно полезные функции. На этот раз обойдёмся без определений, и перейдём сразу к функциям в Unity3D.
Квадратный корень и его применение
Извлечь квадратный корень из числа в Unity (C#) можно так:
Данная функция возвращает арифметический квадратный корень, то есть неотрицательное значение.
В играх его можно применить, например, для определения расстояния до объекта.
Нам известно расстояние от врага до игрока по оси X и Z (или можем узнать).
По теореме Пифагора мы можем найти квадрат гипотенузы, то есть квадрат расстояния от врага до игрока. После чего извлекаем квадратный корень.
Немного кода:
Модуль или абсолютное значение
Получить абсолютное значение числа в Unity (C#) можно с помощью функции:
Это полезно, когда знак только мешает расчётам.
Например, когда мы считаем скорость. Если объект движется вперед то всё нормально. А если назад? У него выходит отрицательная скорость. Чтобы избавиться от минуса, но не париться с определением направления и знака, можно брать абсолютное значение.
Максимум и минимум.
Не редко бывает, что надо сравнить два числа и использовать из них максимальное или минимальное.
В Unity (C#) для получения наибольшего или наименьшего числа из двух чисел, есть функция:
Использовать можно, например, в случае со здоровьем игрока.
Чтобы оно не превышало максимальное:
И чтобы было не ниже нуля:
Но бывают ситуации, когда выбрать надо более, чем из двух чисел.
К примеру у торговца хорошее настроение и он готов продать игроку любой товар по минимальной цене. Или наоборот, игрок насолил торговцу, и тот продаёт ему всё по максимальной цене.
Реализовать это в Unity (C#) можно с помощью тех же функций, просто в качестве параметра передать массив значений:
Для приведённых ситуаций это будет выглядеть так:
priceList – это массив цен на все товары у продавца.
Unity’s Mathf class provides a collection of common math functions, including trigonometric, logarithmic, and other functions commonly required in games and app development.
This page provides an overview of the Mathf class and its common uses when scripting with it. For an exhaustive reference of every member of the Mathf class, see the Mathf script reference.
Trigonometric
All Unity’s trigonometry functions work in radians.
PI is available as a constant, and you can multiply by the static values Rad2Deg or Deg2Rad to convert between radians and degrees.
Powers and Square Roots
As well as some useful power-of-two related functions. These are useful when working with common binary data sizes, which are often constrained or optimized to power-of-two values (such as texture dimensions):
Interpolation
Unity’s interpolation functions allows you to calculate a value that is some way between two given points. Each of these functions behaves in a different way, suitable for different situations. See the examples in each for more information:
Note that the Vector classes and the Quaternion class all have their own interpolation functions (such as Quaternion.Lerp) which allow you to interpolate positions, directions and rotations in multiple dimensions.
Limiting and repeating values
These simple helper functions are often useful in games or apps and can save you time when you need to limit values to a certain range or repeat them within a certain range.
Logarithmic
The Log function allows you to calculate the logarithm of a specified number, either the natural logarithm or in a specified base. Additionally the Log10 function returns the base–10 logarithm of the specified number.
Other functions
For the full list of functions in the Mathf class, see the Mathf script reference.
Mathf.Abs
Success!
Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.
Submission failed
For some reason your suggested change could not be submitted. Please try again in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.
Description
Description
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
You’ve told us this page needs code samples. If you’d like to help us further, you could provide a code sample, or tell us about what kind of code sample you’d like to see:
You’ve told us there are code samples on this page which don’t work. If you know how to fix it, or have something better we could use instead, please let us know:
You’ve told us there is information missing from this page. Please tell us more about what’s missing:
You’ve told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You’ve told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You’ve told us there is a spelling or grammar error on this page. Please tell us what’s wrong:
You’ve told us this page has a problem. Please tell us more about what’s wrong:
Thanks for helping to make the Unity documentation better!
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.
Copyright © 2020 Unity Technologies. Publication Date: 2021-02-24.
JacksonDunstan.com
Math.Abs vs. Mathf.Abs vs. math.abs vs. Custom
A reader recently asked what the fastest way to take an absolute value was. It occurred to me that there are a lot of ways to do this in Unity! So today we’ll try them all out and see which is best.
Update: A Russian translation of this article is available.
Options
How many ways can we take the absolute value of a float? Let us count:
That’s a lot of ways! The custom options (#3 and #4) are obvious, but let’s dive into the others to see what they’re doing. Here’s a decompiled version of Math.Abs :
This is implemented in native code, so the C# trail ends here. Let’s move on to #2 and look at Mathf.Abs :
This just wraps asint :
asint uses a union to alias the memory without changing the bits. We’ve seen that trick before and know that it even works with Burst. Here’s how Unity implemented it:
This is the same approach as we’ve seen before: the same memory within the struct is used to hold the int and the float so its type can be changed without affecting the bits.
Now let’s look at the return trip and see how the uint is changed back into a float :
Again, this just uses the int overload:
This does the opposite of before using the same union.
Next, let’s write some Burst-compiled jobs to test out each of these approaches by taking the absolute value of one element of a NativeArray :
First, here is the assembly for both Math.Abs and Mathf.Abs :
The key line here is andps which is performing the & 0x7FFFFFFF we saw in math.abs to clear the most-significant bit.
Now let’s look at the Burst output for math.abs :
Here’s the custom version based on if :
Finally, here’s the custom version based on the ternary operator:
Performance
Now let’s put all of these approaches to a performance test to see which is fastest. We’ll do this by taking the absolute value of every element of a NativeArray containing random values:
Here’s the test machine I ran this on:
To find out what’s going on, let’s look at the assembly code in Burst Inspector for these jobs to see if the added loop impacted the output.
The custom version based on the ternary operator, on the other hand, is by far the smallest of the three outputs. It’s a simple loop that performs the mask operation. So why is it so slow? Well, it happens to be the last job to run but moving it to earlier in the test has no impact on the results. Instead, the problem is that this version performs fewer absolute value operations per loop than the others. As a result, it spends more time on the loop and potentially branch mispredictions and less time taking absolute values.
Conclusion
Comments
#1 by sschoener on September 2nd, 2019 · Reply
Thanks for the post 🙂 As for the difference between the Ternary version and the Abs version: It is unlikely that this is due to branch mispredictions. There is only a single branch and this will *always* be taken except for the last iteration of the loop. The branch predictor will catch onto this immediately. The performance difference to me looks more like 8x than 10x — which would be neatly explained by the lack of vectorization.
My main question is why the If version is so much faster than the Ternary version. Looking at the assembly, it is doing 8 floats per iteration but then goes ahead and manually extracts the sign bit for each and every one of them and does some wild jumping that depends on the value of said sign. _That_ should give you branch mispredictions. Just as an experiment to see how bad the mispredictions affect the If-version, you could sort the input array before taking the absolute value.
#2 by sschoener on September 2nd, 2019 · Reply
Potential causes: fewer writes in the If version (in that case their performance should be equivalent if you pass in an array of all negative numbers) or fewer reads (it is reading the 8 floats at once).
#3 by d33ds on September 2nd, 2019 · Reply
JacksonDunstan.com
Math.Abs или Mathf.Abs или math.abs или что-то еще?
(Russian translation from English by Maxim Voloshin)
Ðедавно, читатель ÑпроÑил какой Ñамый быÑтрый ÑпоÑоб получить модуль чиÑла. И Ñ Ð¾Ð±Ð½Ð°Ñ€ÑƒÐ¶Ð¸Ð», что ÑущеÑтвует много ÑпоÑобов Ñделать Ñто в Unity! Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ Ð¼Ñ‹ попробуем их вÑе и узнаем какой Ñамый быÑтрый.
Варианты
Сколько вÑего ÑпоÑобов получить модуль чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой? Давайте поÑчитаем:
Ðто довольно много! Варианты Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ (#3 и #4) очевидны, поÑтому, давайте углубимÑÑ Ð² оÑтальные варианты, чтобы увидеть, что именно они делают. Ðто Ð´ÐµÐºÐ¾Ð¼Ð¿Ð¸Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Math.Abs :
Она реализована в нативном коде, и Ñлед C# кончаетÑÑ. Давайте перейдем к варианту #2 и поÑмотрим на Mathf.Abs :
ПроÑто обертка над asint :
asint иÑпользует объединение(union) чтобы обращатьÑÑ Ðº памÑти через пÑевдонимы(Ð¿Ð¾Ð»Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ) без Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ð¸Ñ‚Ð¾Ð² данных. Мы видели Ñтот прием ранее и даже знаем, что Ñто работает Ñ Burst. Вот как Unity Ñто реализует:
Теперь вернемÑÑ Ð½Ð°Ð·Ð°Ð´ и поÑмотрим как uint преобразуетÑÑ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾ в float :
И Ñнова, Ñто вÑего лишь перегрузка:
ЗдеÑÑŒ проиÑходÑÑ‚ обратные Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¸Ñпользованием того же объединениÑ.
Далее, напишем неÑколько задач Burst компилÑтора, Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ которых мы Ñможем протеÑтировать каждый подход, Ð½Ð°Ñ…Ð¾Ð´Ñ Ð¼Ð¾Ð´ÑƒÐ»ÑŒ чиÑла первого Ñлемента NativeArray :
Теперь поÑмотрим, что Burst Ñкомпилировал Ð´Ð»Ñ math.abs :
ВерÑÐ¸Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ, оÑÐ½Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð½Ð° if :
И, наконец, ручное вычиÑление, оÑнованное на тернарном операторе:
Performance
ТеÑÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð° на которой запуÑкалÑÑ Ñ‚ÐµÑÑ‚:
Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾ чтобы понÑть, повлиÑл ли цикл, добавленный в теÑÑ‚, поÑмотрим аÑÑемблерный код Ð´Ð»Ñ Ñтих задач в Burst инÑпекторе.
ВерÑÐ¸Ñ Ð´Ð»Ñ Ñ‚ÐµÑ€Ð½Ð°Ñ€Ð½Ð¾Ð³Ð¾ оператора, Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ Ñтороны, безуÑловно ÑÐ°Ð¼Ð°Ñ ÐºÐ¾Ñ€Ð¾Ñ‚ÐºÐ°Ñ Ð¸Ð· трех, приведенных выше. Ðто проÑтой цикл, выполнÑющий наложение маÑки. Ðо почему же он такой медленный? Возможно, Ñто проиÑходит потому что задача выполнÑетÑÑ Ð¿Ð¾Ñледней, но Ð¿ÐµÑ€ÐµÐ½Ð¾Ñ ÐµÐµ в начало теÑта не влиÑет на результаты. Как ни Ñтранно, проблема в том, что пропуÑк запиÑи уже положительных значений, дает побочный Ñффект. Больше времени тратитÑÑ Ð½Ð° Ñам цикл и потенциальные промахи в предÑказании команд из-за уÑловного перехода и меньше времени на вычиÑление значений.