My goal is to detect the acceleration the user is giving to the device by walking, and make my in-game capsule walk just like the user.
I used Input.gyro.userAcceleration
to do it, as Input.acceleration
is about how tilted the device is.
It seems to catch the accelerations fine, and using them i can more or less determine where the device was heading.
Despite that, when the user stops walking, he gives a negative acceleration to the device, theoretically stopping it as well.
This did not happen, the capsule often came back to its starting position and i suspected that it was because of the drag force, so i removed it.
Even then the accelerometer was not precise enough, and the capsule was left with some speed even when i stopped the device, resulting in it moving in some random direction at low speed.
This is why i tried making some algorithms to detect those small movements and cancel them, but that too was unsuccessful.
here is a link to a video of what happens
in the video you can see that 2 of these 3 movements were decently accurate, while in the second movement the capsule got pulled back to its starting position as i was pulling my phone away from it.
Here is my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//it's named look around because i forgot to change the name, it's used to move around
public class PlayerLookAround : MonoBehaviour
{
public Rigidbody rb; //rigidbody of the capsule
private Gyroscope gyro; //phone gyroscope
public float speedMultiplier = 1f;
public float accLvlBeforeSmoothing = 0.002f; //used to remove small movements that were not meant by the user
void Start()
{
rb = GetComponent<Rigidbody>(); //rigidbody of the capsule
gyro = Input.gyro; //phone gyroscope
gyro.enabled = true; //turning on the gyroscope
Debug.Log(gyro.updateInterval.ToString());
//gyro.updateInterval = 0.001f;
rb.velocity *= 0f;
}
void FixedUpdate()
{
Vector3 acc = Input.acceleration; //create a vector3 equal to the acceleration that the user is giving to the device
acc.x = (float)System.Math.Round(acc.x, 4);
acc.y = (float)System.Math.Round(acc.y, 4); //rounding to the fourth decimal on every axis
acc.z = (float)System.Math.Round(acc.z, 4);
acc.x = -acc.x; //adjusting the axis since it was flipped
acc.y = -acc.y * 0; //blocking the y axis to preventing the user from being able to make the capsule fly
Debug.Log(acc.magnitude);
//smooth noise on all axis, this should cancel the small movements in a single axis when needed,
//leaving the others to move (for example when the user is moving the phone right to left,
//this should cancel the small movements up/down and backwards/forward)
if (acc.x > -accLvlBeforeSmoothing && acc.x < accLvlBeforeSmoothing)
{
acc.x = 0;
}
if (acc.y > -accLvlBeforeSmoothing && acc.y < accLvlBeforeSmoothing)
{
acc.y = 0; //this axis is locked but i keep this line in case i unlock it
}
if (acc.z > -accLvlBeforeSmoothing && acc.z < accLvlBeforeSmoothing)
{
acc.z = 0;
}
//if the phone is barely moving or the velocity is really low make it zero,
//this should smooth out the movement and not leave the capsule walking even if the user isnt
if (acc.magnitude <= 0.005f || rb.velocity.magnitude > -0.1 && rb.velocity.magnitude < 0.1 && rb.velocity.magnitude != 0)
{
rb.velocity *= 0;
return;
}
//add a force to the capsule that goes in the same direction as the acceleration
rb.AddForce(acc * rb.mass * speedMultiplier, ForceMode.Impulse); // F = ma --> a = F/m a = v/t v = x/t v/t = F/m
}
}
I am pretty new to programming, i tried to explain my issue in the best way i could, thank you for your time!