Shaking is unstable values from the sensor.
Why do you think Google Maps handles a change in value even by 1 degree?
Can you confirm this, or is it just your thoughts?
There are several ways to remove shaking:
1. The threshold for changing the value.
2. Lerp or tween values.
3. Collect the last few values (4, 8, 10, 12, etc.), and based on them find the average value.
There are many algorithms for calculating the average value, for example: sum / quantity.
Online Maps Location Service uses options 1 and 2.
The value 0.02 was selected by the test way.
How to improve this - try to combine all three ways.
Something like:
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class LerpMarker2 : MonoBehaviour
{
public float headingThreshold = 0.5f;
public int maxValues = 4;
public float lerpValue = 0.08f;
private float targetHeading;
private OnlineMapsMarker marker;
private List<float> headings;
private bool compassInitialized = false;
private void Start()
{
marker = OnlineMapsMarkerManager.CreateItem(OnlineMaps.instance.position);
marker.align = OnlineMapsAlign.Center;
headings = new List<float>();
OnlineMapsLocationService.instance.OnCompassChanged += OnCompassChanged;
}
private void OnCompassChanged(float value)
{
compassInitialized = true;
OnlineMapsLocationService.instance.OnCompassChanged -= OnCompassChanged;
targetHeading = value * 360;
marker.rotation = value;
headings.Add(targetHeading);
}
private void Update()
{
if (!compassInitialized) return;
if (headings.Count == maxValues) headings.RemoveAt(0);
float heading = OnlineMapsLocationService.instance.trueHeading;
float prevHeading = headings[headings.Count - 1];
if (prevHeading - heading > 180) heading += 360;
if (prevHeading - heading < -180) heading -= 360;
headings.Add(heading);
heading = headings.Average();
if (Mathf.Abs(heading - targetHeading) > headingThreshold) targetHeading = heading;
float targetRotation = targetHeading / 360;
float rotationOffset = Mathf.Abs(marker.rotation - targetRotation);
if (rotationOffset < float.Epsilon) return;
if (rotationOffset < 0.0028) // 1 deg / 360
{
marker.rotation = targetRotation;
}
else marker.rotation = Mathf.Lerp(marker.rotation, targetRotation, lerpValue);
OnlineMaps.instance.Redraw();
}
}
Kind Regards,
Infinity Code Team.
Boost your productivity a lot and immediately using
Ultimate Editor Enhancer.
Trial and non-commerce versions available.