Files
MagnetismHeroes/Assets/MagnetismHeroes/UnityRuntime/Presentation/BoardPresenter.cs
T

72 lines
3.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using MagnetismHeroes.Core;
using UnityEngine;
namespace MagnetismHeroes.UnityRuntime.Presentation
{
public sealed class BoardPresenter : MonoBehaviour
{
[SerializeField] private BallView _ballPrefab;
[SerializeField] private GroupBadge _badgePrefab;
[SerializeField] private Camera _camera;
private readonly Dictionary<string, BallView> _balls = new Dictionary<string, BallView>();
private readonly List<GroupBadge> _badges = new List<GroupBadge>();
private BoardRules _board;
public Camera Camera => _camera;
public IReadOnlyDictionary<string, BallView> Balls => _balls;
public void Render(BoardRules board)
{
_board = board;
foreach (var view in _balls.Values) { view.gameObject.SetActive(false); Destroy(view.gameObject); }
foreach (var badge in _badges) { badge.gameObject.SetActive(false); Destroy(badge.gameObject); }
_balls.Clear(); _badges.Clear();
if (board == null) return;
foreach (var group in board.Groups)
{
foreach (var ballId in group.ballIds)
{
var state = board.Balls.First(ball => ball.id == ballId);
var ball = Instantiate(_ballPrefab, ToVector(state.position), Quaternion.identity, transform);
ball.Bind(ballId, group.id, board.CountedBallIds.Contains(ballId)); _balls.Add(ballId, ball);
}
_badges.Add(Instantiate(_badgePrefab, transform));
}
PositionBadges();
}
public void PreviewGroup(string groupId, Vector3 delta)
{
foreach (var state in _board.Balls)
_balls[state.id].transform.position = ToVector(state.position) + (_balls[state.id].GroupId == groupId ? delta : Vector3.zero);
PositionBadges();
}
public void CancelPreview()
{
if (_board == null) return;
foreach (var state in _board.Balls) _balls[state.id].transform.position = ToVector(state.position);
PositionBadges();
}
private void PositionBadges()
{
if (_board == null) return;
var groups = _board.Groups;
for (int index = 0; index < groups.Length; index++)
{
var group = groups[index];
var center = group.ballIds.Select(id => _balls[id].transform.position).Aggregate(Vector3.zero, (sum, value) => sum + value) / group.ballIds.Length;
var representative = _balls[group.ballIds[0]].transform.position;
_badges[index].Bind(group.ballIds.Length, center + Vector3.up * 0.95f,
representative - _camera.transform.forward * 0.49f);
_badges[index].FaceCamera(_camera);
}
}
private void LateUpdate() => PositionBadges();
public static Vector3 ToVector(Position3 position) => new Vector3(position.x, position.y, position.z);
public static Position3 ToPosition(Vector3 vector) => new Position3(vector.x, vector.y, vector.z);
}
}