Vector2 ToString and vector components show totally different values
I'm making scripts for vehicle control with virtual joysticks. Everything seemed to be working fine until I found a very strange bug which I just can't explain. So, I have a normalized Vector2 which is controlled by a joystick and is used to set direction of the vehicles, nothing special. But when this vector is pointing left a very weird thing happens, Vector2.ToString shows (1.0, 0.0) but Vector2.y shows 8.742278E-08 or -8.742278E-08 like this:
void Update() {
print("JOYSTICK INPUT" + inputVector + " INPUT Y " + inputVector.y);
}
And the output is
JOYSTICK INPUT(-1.0, 0.0) INPUT Y 8.742278E-08 UnityEngine.MonoBehaviour:print(Object) Joystick:Update() (at Assets/Virtual Joystick Pack/Scripts/Base/Joystick.cs:35)
I could explain it by changing value somewhere else if I would be getting it asynchronously but I just have no explanation of how can they be so different in synchronous output
I'm not a newbie in programming, I have many years of experience with it, but this bug really made me come here and ask for help
p.s. Here's the complete code of my custom Joystick and its base class (base asset can be found here https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631). The base joystick has the same problem
using UnityEngine;
using UnityEngine.EventSystems;
public class Joystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
[Header("Options")]
[Range(0f, 2f)] public float handleLimit = 1f;
[HideInInspector]
public Vector2 inputVector = Vector2.zero;
[Header("Components")]
public RectTransform background;
public RectTransform handle;
public virtual float Horizontal { get { return inputVector.x; } }
public virtual float Vertical { get { return inputVector.y; } }
public virtual void OnDrag(PointerEventData eventData)
{
}
public virtual void OnPointerDown(PointerEventData eventData)
{
}
public virtual void OnPointerUp(PointerEventData eventData)
{
}
void Update() {
print("JOYSTICK IN PUT" + inputVector + " INPUT Y " + inputVector.y);
}
}
And my joystick
using UnityEngine;
using UnityEngine.EventSystems;
public class SnapableFixedJoystick : Joystick
{
[Header("Snappable Fixed Joystick")]
Vector2 joystickPosition = Vector2.zero;
private Camera cam = new Camera();
private const int _snapAngle = 45;
private float _halfSnapAngle = 0.0f;
void Start()
{
_halfSnapAngle = _snapAngle / 2;
joystickPosition = RectTransformUtility.WorldToScreenPoint(cam, background.position);
}
public override void OnDrag(PointerEventData eventData)
{
Vector2 direction = eventData.position - joystickPosition;
float degAngle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (_snapAngle > 0) {
degAngle += _halfSnapAngle;
if (degAngle >= 0) {
degAngle -= (degAngle % _snapAngle);
} else {
degAngle -= (_snapAngle + (degAngle % _snapAngle));
}
// used to snap joystick handle to a specific angle
SetVectorAngle(ref direction, degAngle * Mathf.Deg2Rad);
}
inputVector = (direction.magnitude > background.sizeDelta.x / 2f) ? direction.normalized : direction / (background.sizeDelta.x / 2f);
handle.anchoredPosition = (inputVector * background.sizeDelta.x / 2f) * handleLimit;
}
private void SetVectorAngle(ref Vector2 vector, float angle) {
var len = vector.magnitude;
vector.x = Mathf.Cos(angle) * len;
vector.y = Mathf.Sin(angle) * len;
}
public override void OnPointerDown(PointerEventData eventData)
{
OnDrag(eventData);
}
public override void OnPointerUp(PointerEventData eventData)
{
inputVector = Vector2.zero;
handle.anchoredPosition = Vector2.zero;
}
}
Answer by Bunny83 · Feb 18, 2018 at 05:43 AM
They are not totally different values. You should learn to read scientific notation. By default ToString of Unity's vector structs will round each component to 1 digit behind the decimal point. When you print the components manually you basically call ToString on a float value which be default shows much more digits and uses the default scientific notation.
The value 8.742278E-08
is just 8.742278 * 10^-08
. So the actual value in decimal notation is 0.00000008742278
which gets of course rounded to just "0.0" when you round to only one decimal place.
You may also want to watch the Numberphile video on floating point numbers
Damn! You're totally right! I should have postponed this until morning :) Thank you so much!
Your answer
Follow this Question
Related Questions
My movement script is not moving my 2D object 2 Answers
Turn a vector3 relative to a look direction 1 Answer
Vector2 intersection 0 Answers
[noob] vector2 cuestions 0 Answers
Character move speed not working 1 Answer