136 lines
3.9 KiB
C#
136 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Mapbox.CheapRulerCs;
|
|
using Mapbox.Unity.Map;
|
|
using UnityEngine;
|
|
|
|
public class CollectableDuckManager : MonoBehaviour
|
|
{
|
|
public List<CollectableDuckData> collectableDucks;
|
|
|
|
private readonly HashSet<CollectableDuckData> _collectedDucks = new HashSet<CollectableDuckData>();
|
|
|
|
private readonly Dictionary<CollectableDuckData, CollectableDuck> _spawnedDucks = new Dictionary<CollectableDuckData, CollectableDuck>();
|
|
|
|
public AbstractMap map;
|
|
public Transform player;
|
|
public Transform collectableDuckParent;
|
|
|
|
public event EventHandler<CollectableDuckData> DuckClicked;
|
|
|
|
/// <summary>
|
|
/// Spawn distance in meters (i.e. how close should the player be to a duck before it spawns on the map
|
|
/// </summary>
|
|
public float spawnDistance = 50;
|
|
|
|
public CollectableDuck duckSpawnPrefab;
|
|
|
|
private static CollectableDuckManager _instance;
|
|
|
|
public static CollectableDuckManager Instance
|
|
{
|
|
get { return _instance; }
|
|
private set { _instance = value; }
|
|
}
|
|
|
|
public CollectableDuckManager()
|
|
{
|
|
Instance = this;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
CheckCollectableDuckIds();
|
|
_collectedDucks.Clear();
|
|
foreach (var duck in collectableDucks.Where(duck => PlayerPrefs.GetInt("duck." + duck.Id) > 0))
|
|
{
|
|
_collectedDucks.Add(duck);
|
|
}
|
|
}
|
|
|
|
private void CheckCollectableDuckIds()
|
|
{
|
|
var duckIds = new HashSet<string>();
|
|
foreach (var duck in collectableDucks)
|
|
{
|
|
if (duckIds.Contains(duck.Id))
|
|
{
|
|
Debug.LogError("Duplicate duck ID: '" + duck.Id + "' for duck '" + duck.name + "'");
|
|
}
|
|
|
|
duckIds.Add(duck.Id);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var ruler = new CheapRuler(map.CenterLatitudeLongitude.x, CheapRulerUnits.Meters);
|
|
var playerPosition = map.WorldToGeoPosition(player.position).ToArray();
|
|
for (int i = 0; i < collectableDucks.Count; i++)
|
|
{
|
|
var duck = collectableDucks[i];
|
|
var duckCoord = duck.LatitudeLongitude;
|
|
var dist = ruler.Distance(duckCoord.ToArray(), playerPosition);
|
|
// Debug.Log("Distance to " + duck.name + ": " + dist);
|
|
if (dist < spawnDistance && !_collectedDucks.Contains(duck))
|
|
{
|
|
SpawnDuck(duck);
|
|
}
|
|
else
|
|
{
|
|
RemoveDuck(duck);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SpawnDuck(CollectableDuckData duck)
|
|
{
|
|
if (!_spawnedDucks.ContainsKey(duck))
|
|
{
|
|
// Spawn the duck
|
|
var duckSpawn = Instantiate(duckSpawnPrefab, map.GeoToWorldPosition(duck.LatitudeLongitude),
|
|
Quaternion.identity, collectableDuckParent);
|
|
duckSpawn.CollectableDuckData = duck;
|
|
var duckModel = Instantiate(duck.ModelPrefab, duckSpawn.transform);
|
|
duckModel.transform.localPosition = Vector3.zero;
|
|
|
|
_spawnedDucks[duck] = duckSpawn;
|
|
}
|
|
else
|
|
{
|
|
if (!_spawnedDucks[duck].gameObject.activeSelf)
|
|
{
|
|
_spawnedDucks[duck].gameObject.SetActive(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RemoveDuck(CollectableDuckData duck)
|
|
{
|
|
if (_spawnedDucks.ContainsKey(duck))
|
|
{
|
|
if (_spawnedDucks[duck].gameObject.activeSelf)
|
|
{
|
|
_spawnedDucks[duck].gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OnDuckClicked(CollectableDuckData duck)
|
|
{
|
|
if (DuckClicked != null)
|
|
{
|
|
DuckClicked.Invoke(this, duck);
|
|
}
|
|
|
|
}
|
|
|
|
public void OnDuckCollected(CollectableDuckData duck)
|
|
{
|
|
_collectedDucks.Add(duck);
|
|
PlayerPrefs.SetInt("duck." + duck.Id, 1);
|
|
|
|
RemoveDuck(duck);
|
|
}
|
|
} |