chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View File

@@ -0,0 +1,247 @@
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// TeamIndicator - Creates an overhead team marker above characters to differentiate teammates from enemies.
/// Attach to character prefabs or add dynamically via TeamIndicatorManager.
/// </summary>
public class TeamIndicator : MonoBehaviour
{
[Header("Indicator Settings")]
[SerializeField] private float heightOffset = 2.5f;
[SerializeField] private float indicatorSize = 0.3f;
[Header("Team Colors")]
[SerializeField] private Color allyColor = new Color(0.2f, 0.8f, 0.2f, 1f); // Green
[SerializeField] private Color enemyColor = new Color(0.9f, 0.2f, 0.2f, 1f); // Red
[SerializeField] private Color controlledColor = new Color(0.2f, 0.6f, 1f, 1f); // Blue for currently controlled
[Header("Visual Options")]
[SerializeField] private bool showOnAllies = true;
[SerializeField] private bool showOnEnemies = true;
[SerializeField] private bool hideWhenControlled = true;
[SerializeField] private float fadeDistance = 50f; // Fade out at this distance
private GameObject indicatorObject;
private SpriteRenderer spriteRenderer;
private Camera mainCamera;
private TeamMember teamMember;
private string myTeamTag;
private bool isCurrentlyControlled = false;
// Static reference to find the current player for team comparison
private static Transform currentPlayerTransform;
private static string currentPlayerTeamTag = "Player";
private void Start()
{
// Only activate in Cash System mode
if (SelectionOptions.Instance == null || !SelectionOptions.Instance.isCashSystemSelected)
{
enabled = false;
return;
}
mainCamera = Camera.main;
teamMember = GetComponent<TeamMember>();
myTeamTag = gameObject.tag;
CreateIndicator();
UpdateIndicatorColor();
}
private void LateUpdate()
{
if (indicatorObject == null || mainCamera == null) return;
// Update position to stay above character
indicatorObject.transform.position = transform.position + Vector3.up * heightOffset;
// Billboard effect - always face camera
indicatorObject.transform.rotation = Quaternion.LookRotation(
indicatorObject.transform.position - mainCamera.transform.position
);
// Check if this character is currently controlled
bool wasControlled = isCurrentlyControlled;
isCurrentlyControlled = teamMember != null && teamMember.IsPlayerControlled;
// Update static reference if we're the controlled character
if (isCurrentlyControlled)
{
currentPlayerTransform = transform;
currentPlayerTeamTag = myTeamTag;
}
// Update color if control status changed
if (wasControlled != isCurrentlyControlled)
{
UpdateIndicatorColor();
}
// Handle visibility based on settings
UpdateVisibility();
// Fade based on distance from camera
UpdateFade();
}
private void CreateIndicator()
{
// Create indicator game object
indicatorObject = new GameObject($"{gameObject.name}_TeamIndicator");
indicatorObject.transform.position = transform.position + Vector3.up * heightOffset;
// Add sprite renderer for the indicator
spriteRenderer = indicatorObject.AddComponent<SpriteRenderer>();
spriteRenderer.sprite = CreateCircleSprite();
spriteRenderer.sortingOrder = 100; // Ensure it renders on top
// Set initial size
indicatorObject.transform.localScale = Vector3.one * indicatorSize;
}
private Sprite CreateCircleSprite()
{
// Create a simple diamond/arrow shaped indicator texture
int size = 64;
Texture2D texture = new Texture2D(size, size);
Color transparent = new Color(0, 0, 0, 0);
// Fill with transparent
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
texture.SetPixel(x, y, transparent);
}
}
// Draw a downward pointing triangle/arrow
int centerX = size / 2;
int topY = size - 8;
int bottomY = 8;
for (int y = bottomY; y <= topY; y++)
{
float progress = (float)(y - bottomY) / (topY - bottomY);
int halfWidth = (int)(progress * (size / 2 - 4));
for (int x = centerX - halfWidth; x <= centerX + halfWidth; x++)
{
// Create a border effect
bool isBorder = Mathf.Abs(x - (centerX - halfWidth)) < 3 ||
Mathf.Abs(x - (centerX + halfWidth)) < 3 ||
y == bottomY || y >= topY - 2;
Color col = isBorder ? Color.white : Color.white;
col.a = isBorder ? 1f : 0.8f;
texture.SetPixel(x, y, col);
}
}
texture.Apply();
texture.filterMode = FilterMode.Bilinear;
return Sprite.Create(texture, new Rect(0, 0, size, size), new Vector2(0.5f, 0f), size);
}
private void UpdateIndicatorColor()
{
if (spriteRenderer == null) return;
// Currently controlled character
if (isCurrentlyControlled)
{
spriteRenderer.color = controlledColor;
return;
}
// Determine if ally or enemy relative to player
bool isAlly = (myTeamTag == currentPlayerTeamTag);
if (isAlly)
{
spriteRenderer.color = allyColor;
}
else
{
spriteRenderer.color = enemyColor;
}
}
private void UpdateVisibility()
{
if (spriteRenderer == null) return;
bool shouldShow = true;
// Hide if this is the controlled character and setting is enabled
if (hideWhenControlled && isCurrentlyControlled)
{
shouldShow = false;
}
// Check ally/enemy visibility settings
bool isAlly = (myTeamTag == currentPlayerTeamTag);
if (isAlly && !showOnAllies) shouldShow = false;
if (!isAlly && !showOnEnemies) shouldShow = false;
indicatorObject.SetActive(shouldShow);
}
private void UpdateFade()
{
if (spriteRenderer == null || mainCamera == null) return;
float distance = Vector3.Distance(mainCamera.transform.position, transform.position);
// Calculate alpha based on distance
float alpha = Mathf.Clamp01(1f - (distance / fadeDistance));
alpha = Mathf.Max(alpha, 0.3f); // Minimum alpha
Color currentColor = spriteRenderer.color;
currentColor.a = alpha;
spriteRenderer.color = currentColor;
}
private void OnDestroy()
{
if (indicatorObject != null)
{
Destroy(indicatorObject);
}
}
/// <summary>
/// Force update the indicator color (call after team changes)
/// </summary>
public void RefreshIndicator()
{
myTeamTag = gameObject.tag;
UpdateIndicatorColor();
UpdateVisibility();
}
/// <summary>
/// Set indicator visibility
/// </summary>
public void SetVisible(bool visible)
{
if (indicatorObject != null)
{
indicatorObject.SetActive(visible);
}
}
/// <summary>
/// Static method to update all indicators when player changes
/// </summary>
public static void RefreshAllIndicators()
{
foreach (var indicator in FindObjectsOfType<TeamIndicator>())
{
indicator.RefreshIndicator();
}
}
}