Stwórz prosty licznik kroków (pedometr) w Unity C#
W tym tutorialu dowiesz się, jak zbudować licznik kroków, który:
- Wykrywa kroki za pomocą akcelerometru urządzenia.
- Oblicza przebyty dystans na podstawie średniej długości kroku.
- Zapisuje liczbę kroków na dany dzień przy użyciu mechanizmu
PlayerPrefsw Unity. - Umożliwia łatwą konfigurację ustawień dzięki wykorzystaniu ScriptableObject.
Prerekwizyty
Upewnij się, że:
- Masz podstawową znajomość Unity oraz języka C#.
- Posiadasz zainstalowaną najnowszą wersję Unity (każda niedawna wersja będzie odpowiednia).
Krok 1: Utworzenie ScriptableObject do konfiguracji
Na początek stworzymy ScriptableObject, który przechowuje ustawienia konfiguracyjne naszego licznika kroków. Dzięki temu będziesz mógł łatwo zmieniać wartości (np. długość kroku czy próg wykrywania) bez modyfikacji kodu.
Utwórz nowy skrypt C# o nazwie StepCounterConfig.cs i wklej poniższy kod:
using UnityEngine;
[CreateAssetMenu(fileName = "StepCounterConfig", menuName = "StepCounter/Config", order = 1)]
public class StepCounterConfig : ScriptableObject
{
[Header("Ustawienia Licznika Kroków")]
[Tooltip("Średnia długość kroku w metrach.")]
public float stepLength = 0.75f;
[Header("Ustawienia Wykrywania")]
[Tooltip("Próg przyspieszenia do wykrywania kroków.")]
public float threshold = 1f;
}
Krok 2: Implementacja logiki licznika kroków
W tym kroku utworzymy główny skrypt odpowiedzialny za wykrywanie kroków i obliczanie przebytego dystansu. Użyjemy wzorca Singleton, aby mieć pewność, że zawsze operujemy na jednym egzemplarzu licznika.
Utwórz nowy skrypt C# o nazwie StepCounter.cs i wklej poniższy kod:
using UnityEngine;
public class StepCounter : MonoBehaviour
{
// Implementacja Singletona
private static StepCounter _instance;
public static StepCounter Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType();
if (_instance == null)
{
GameObject container = new GameObject("StepCounter");
_instance = container.AddComponent();
}
}
return _instance;
}
}
[Header("Konfiguracja")]
public StepCounterConfig config;
[Header("Zmienne w trakcie działania")]
[SerializeField] private float distanceWalked = 0f;
[SerializeField] private int stepCount = 0;
private Vector3 acceleration;
private Vector3 prevAcceleration;
private void Start()
{
if (config == null)
{
Debug.LogError("Uwaga! Brakuje StepCounterConfig!");
return;
}
// Ustawienie początkowej wartości przyspieszenia
prevAcceleration = Input.acceleration;
// Sprawdzenie, czy nadszedł nowy dzień (odświeżenie danych)
StepDataHandler.Instance.CheckForNewDay();
}
private void Update()
{
if (config == null) return;
// Wykrywanie kroków
DetectSteps();
// Obliczanie dystansu
CalculateDistance();
// Zapisywanie liczby kroków
StepDataHandler.Instance.SaveDailySteps(stepCount);
}
// Metoda do wykrywania kroków
private void DetectSteps()
{
acceleration = Input.acceleration;
float delta = (acceleration - prevAcceleration).magnitude;
if (delta > config.threshold)
{
stepCount++;
Debug.Log($"Wykryto krok! Liczba kroków: {stepCount}");
}
prevAcceleration = acceleration;
}
// Obliczanie przebytych metrów
private void CalculateDistance()
{
distanceWalked = stepCount * config.stepLength;
}
// Metoda do kalibracji długości kroku
public void CalibrateStepLength(float newStepLength)
{
if (newStepLength > 0)
{
config.stepLength = newStepLength;
Debug.Log($"Kalibracja: nowa długość kroku to {config.stepLength} metra.");
}
else
{
Debug.LogWarning("Nieprawidłowa wartość długości kroku!");
}
}
// Metody pomocnicze: pobieranie i resetowanie danych
public float GetDistanceWalked() => distanceWalked;
public int GetStepCount() => stepCount;
public void ResetStepData()
{
stepCount = 0;
distanceWalked = 0f;
}
public void LoadStepData(int loadedStepCount)
{
stepCount = loadedStepCount;
CalculateDistance();
}
}
Krok 3: Zapisywanie i odczytywanie danych (Data Persistence)
Aby liczba kroków była zapisywana pomiędzy kolejnymi sesjami aplikacji oraz resetowana przy zmianie dnia, utworzymy osobny skrypt do obsługi danych.
Utwórz nowy skrypt C# o nazwie StepDataHandler.cs i wklej poniższy kod:
using UnityEngine;
public class StepDataHandler : MonoBehaviour
{
// Implementacja Singletona (podobnie jak w StepCounter)
private static StepDataHandler _instance;
public static StepDataHandler Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType();
if (_instance == null)
{
GameObject container = new GameObject("StepDataHandler");
_instance = container.AddComponent();
}
}
return _instance;
}
}
private const string lastRecordedDateKey = "LastRecordedDate";
private const string dailyStepsKey = "DailySteps";
// Zapisuje liczbę kroków do PlayerPrefs
public void SaveDailySteps(int stepCount)
{
PlayerPrefs.SetInt(dailyStepsKey, stepCount);
}
// Sprawdza, czy nadszedł nowy dzień
public void CheckForNewDay()
{
string currentDateString = System.DateTime.Now.ToString("yyyyMMdd");
string lastRecordedDate = PlayerPrefs.GetString(lastRecordedDateKey, currentDateString);
if (currentDateString != lastRecordedDate)
{
ResetDailySteps();
PlayerPrefs.SetString(lastRecordedDateKey, currentDateString);
}
else
{
LoadDailySteps();
}
}
// Resetuje licznik kroków na nowy dzień
private void ResetDailySteps()
{
PlayerPrefs.SetInt(dailyStepsKey, 0);
StepCounter.Instance.ResetStepData();
Debug.Log("Nowy dzień – licznik kroków został zresetowany.");
}
// Wczytuje zapisane dane o krokach
private void LoadDailySteps()
{
int stepCount = PlayerPrefs.GetInt(dailyStepsKey, 0);
StepCounter.Instance.LoadStepData(stepCount);
Debug.Log("Wczytano zapisane kroki.");
}
}
Krok 4: Konfiguracja w Unity
Po zaimportowaniu kodu czas na konfigurację sceny w Unity:
- Utworzenie assetu konfiguracyjnego:
- W edytorze Unity przejdź do Assets → Create → StepCounter → Config.
- Powstanie nowy asset typu StepCounterConfig – nazwij go np. „DefaultStepCounterConfig”.
- Dostosuj wartości
stepLength(długość kroku) orazthreshold(próg wykrywania) według swoich potrzeb.
- Dodanie komponentów do sceny:
- Dodaj komponent
StepCounterdo dowolnego GameObject w scenie. - W inspektorze przypisz stworzony asset „DefaultStepCounterConfig” do pola
configw komponencieStepCounter. - Upewnij się, że w scenie znajduje się również obiekt (lub zostanie automatycznie utworzony) z komponentem
StepDataHandler.
- Dodaj komponent
Podsumowanie
W tym tutorialu nauczyłeś się, jak stworzyć podstawowy licznik kroków w Unity używając C#. Oto główne punkty:
- ScriptableObject: Umożliwia łatwą konfigurację ustawień, takich jak długość kroku czy próg wykrywania.
- Singleton: Gwarantuje, że korzystamy z jednego egzemplarza zarówno licznika kroków, jak i handlera danych.
- Wykrywanie kroków: Oparte na zmianach przyspieszenia, które są rejestrowane i przeliczane na liczbę kroków oraz dystans.
- Data Persistence: Zapisuje liczbę kroków i resetuje dane przy zmianie dnia za pomocą mechanizmu
PlayerPrefs.
Dodatkowo możesz rozszerzyć projekt o: