147 lines
5.3 KiB
C#
147 lines
5.3 KiB
C#
using UnityEngine;
|
||
|
||
namespace Vanguard.Board3D
|
||
{
|
||
/// <summary>Колода, дроп или душа: стопка карт с подписью и коллайдером.</summary>
|
||
public sealed class Pile3D : MonoBehaviour
|
||
{
|
||
private PlaymatLayoutConfig _config;
|
||
private readonly GameObject[] _layers = new GameObject[3];
|
||
private MeshRenderer _top;
|
||
private MaterialPropertyBlock _block;
|
||
private TextMesh _label;
|
||
private int _count;
|
||
|
||
public BoardZone Zone { get; private set; }
|
||
public int Player { get; private set; }
|
||
public BoardCardRef Ref => BoardCardRef.Pile(Zone, Player, _count);
|
||
|
||
public void SetPlayer(int player)
|
||
{
|
||
Player = player;
|
||
}
|
||
|
||
public static Pile3D Create(
|
||
Transform parent,
|
||
PlaymatLayoutConfig config,
|
||
BoardZone zone,
|
||
int player,
|
||
Vector3 position,
|
||
string title,
|
||
Color accent)
|
||
{
|
||
var go = new GameObject("Pile " + zone);
|
||
go.transform.SetParent(parent, false);
|
||
go.transform.localPosition = position;
|
||
|
||
var pile = go.AddComponent<Pile3D>();
|
||
pile.Zone = zone;
|
||
pile.Player = player;
|
||
pile._config = config;
|
||
pile._block = new MaterialPropertyBlock();
|
||
pile.Build(title, accent, config);
|
||
return pile;
|
||
}
|
||
|
||
private void Build(string title, Color accent, PlaymatLayoutConfig config)
|
||
{
|
||
var width = config.cardWidth;
|
||
var height = config.cardHeight;
|
||
var thickness = Mathf.Max(0.006f, config.cardThickness * 1.2f);
|
||
|
||
for (var i = 0; i < _layers.Length; i++)
|
||
{
|
||
var layer = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||
layer.name = "Layer " + i;
|
||
RemoveCollider(layer);
|
||
layer.transform.SetParent(transform, false);
|
||
layer.transform.localPosition = new Vector3(0f, i * thickness, 0f);
|
||
layer.transform.localScale = new Vector3(width, thickness, height);
|
||
var renderer = layer.GetComponent<MeshRenderer>();
|
||
renderer.sharedMaterial = Zone == BoardZone.Soul
|
||
? BoardMaterials.CreateUnlit(null, accent)
|
||
: BoardMaterials.Back;
|
||
BoardMaterials.SetShadows(renderer, true);
|
||
_layers[i] = layer;
|
||
}
|
||
|
||
var topGo = new GameObject("Top");
|
||
topGo.transform.SetParent(transform, false);
|
||
var topFilter = topGo.AddComponent<MeshFilter>();
|
||
topFilter.sharedMesh = BoardMeshLibrary.CardFace(width, height, front: true);
|
||
_top = topGo.AddComponent<MeshRenderer>();
|
||
_top.sharedMaterial = BoardMaterials.White;
|
||
BoardMaterials.SetShadows(_top, false);
|
||
|
||
_label = BoardText.Create(
|
||
transform,
|
||
title,
|
||
0.115f,
|
||
new Color(0.86f, 0.90f, 1f),
|
||
new Vector3(0f, 0.02f, -(height * 0.78f)));
|
||
|
||
var collider = gameObject.AddComponent<BoxCollider>();
|
||
collider.size = new Vector3(width * 1.06f, 0.16f, height * 1.06f);
|
||
collider.center = new Vector3(0f, 0.08f, 0f);
|
||
}
|
||
|
||
public void SetCount(int count, Texture2D topTexture, string title, Color accent)
|
||
{
|
||
_count = count;
|
||
var safe = Mathf.Max(0, count);
|
||
var layers = safe <= 0 ? 1 : safe < 5 ? 1 : safe < 20 ? 2 : 3;
|
||
if (Zone == BoardZone.Soul)
|
||
layers = safe < 10 ? 1 : 2;
|
||
var thickness = Mathf.Max(0.006f, _config.cardThickness * 1.2f);
|
||
|
||
for (var i = 0; i < _layers.Length; i++)
|
||
_layers[i].SetActive(i < layers);
|
||
|
||
_top.transform.localPosition = new Vector3(
|
||
0f,
|
||
(layers - 1) * thickness + 0.0015f,
|
||
0f);
|
||
|
||
if (topTexture != null)
|
||
{
|
||
_top.GetPropertyBlock(_block);
|
||
_block.Clear();
|
||
BoardMaterials.SetTexture(_block, _top.sharedMaterial, topTexture);
|
||
BoardMaterials.SetColor(_block, _top.sharedMaterial, Color.white);
|
||
_top.SetPropertyBlock(_block);
|
||
}
|
||
else
|
||
{
|
||
_top.GetPropertyBlock(_block);
|
||
_block.Clear();
|
||
if (Zone == BoardZone.Soul)
|
||
{
|
||
BoardMaterials.SetTexture(_block, _top.sharedMaterial, BoardTextures.White);
|
||
BoardMaterials.SetColor(_block, _top.sharedMaterial, accent);
|
||
}
|
||
else
|
||
{
|
||
BoardMaterials.SetTexture(_block, _top.sharedMaterial, BoardTextures.Back);
|
||
BoardMaterials.SetColor(_block, _top.sharedMaterial, Color.white);
|
||
}
|
||
|
||
_top.SetPropertyBlock(_block);
|
||
}
|
||
|
||
BoardText.SetText(_label, title + " " + safe);
|
||
}
|
||
|
||
private static void RemoveCollider(GameObject target)
|
||
{
|
||
var collider = target.GetComponent<Collider>();
|
||
if (collider == null)
|
||
return;
|
||
|
||
if (Application.isPlaying)
|
||
Destroy(collider);
|
||
else
|
||
DestroyImmediate(collider);
|
||
}
|
||
}
|
||
}
|