ArkanoidTG/Assets/Scripts/Brick.cs

188 lines
7.8 KiB
C#
Raw Permalink Normal View History

2024-11-25 23:14:57 +03:00
using UnityEngine;
using TMPro;
public class Brick : MonoBehaviour
{
public int points = 100;
[Header("Particle Effects")]
public Color hitParticleColor = Color.white;
public Color destroyParticleColor = Color.white;
public float hitParticleLifetime = 0.3f;
public float destroyParticleLifetime = 0.5f;
public int hitParticleCount = 10;
public int destroyParticleCount = 20;
protected SpriteRenderer spriteRenderer;
protected ParticleSystem hitParticles;
protected ParticleSystem destroyParticles;
protected Material particleMaterial;
protected virtual void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
// Создаем материал для частиц
CreateParticleMaterial();
// Создаем системы частиц
CreateParticleSystems();
}
protected virtual void CreateParticleMaterial()
{
// Используем более простой шейдер, который гарантированно работает в WebGL
particleMaterial = new Material(Shader.Find("Sprites/Default"));
particleMaterial.SetFloat("_BlendOp", (float)UnityEngine.Rendering.BlendOp.Add);
particleMaterial.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
particleMaterial.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.One);
particleMaterial.enableInstancing = true; // Включаем инстансинг для лучшей производительности
}
protected virtual void CreateParticleSystems()
{
// Создаем систему частиц для эффекта удара
GameObject hitParticlesObj = new GameObject("HitParticles");
hitParticlesObj.transform.SetParent(transform);
hitParticlesObj.transform.localPosition = Vector3.zero;
hitParticles = hitParticlesObj.AddComponent<ParticleSystem>();
// Создаем систему частиц для эффекта уничтожения
GameObject destroyParticlesObj = new GameObject("DestroyParticles");
destroyParticlesObj.transform.SetParent(transform);
destroyParticlesObj.transform.localPosition = Vector3.zero;
destroyParticles = destroyParticlesObj.AddComponent<ParticleSystem>();
// Останавливаем системы перед настройкой
hitParticles.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
destroyParticles.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
// Настраиваем систему частиц для удара
var hitMain = hitParticles.main;
hitMain.duration = 0.2f;
hitMain.loop = false;
hitMain.startLifetime = hitParticleLifetime;
hitMain.startSpeed = 5f; // Увеличили скорость с 3f до 5f
hitMain.startSize = 0.08f; // Уменьшили размер с 0.1f до 0.08f
hitMain.maxParticles = hitParticleCount;
hitMain.simulationSpace = ParticleSystemSimulationSpace.World;
hitMain.cullingMode = ParticleSystemCullingMode.AlwaysSimulate;
hitMain.gravityModifier = 1.5f; // Добавили гравитацию
var hitEmission = hitParticles.emission;
hitEmission.rateOverTime = 0;
hitEmission.SetBursts(new ParticleSystem.Burst[] {
new ParticleSystem.Burst(0f, hitParticleCount)
});
var hitShape = hitParticles.shape;
hitShape.shapeType = ParticleSystemShapeType.Circle;
hitShape.radius = 0.2f;
// Добавляем физику для частиц удара
var hitPhysics = hitParticles.externalForces;
hitPhysics.multiplier = 1f;
// Настраиваем систему частиц для уничтожения
var destroyMain = destroyParticles.main;
destroyMain.duration = 0.2f;
destroyMain.loop = false;
destroyMain.startLifetime = destroyParticleLifetime;
destroyMain.startSpeed = 8f; // Увеличили скорость с 5f до 8f
destroyMain.startSize = 0.12f; // Уменьшили размер с 0.15f до 0.12f
destroyMain.maxParticles = destroyParticleCount;
destroyMain.simulationSpace = ParticleSystemSimulationSpace.World;
destroyMain.cullingMode = ParticleSystemCullingMode.AlwaysSimulate;
destroyMain.gravityModifier = 2f; // Добавили гравитацию
var destroyEmission = destroyParticles.emission;
destroyEmission.rateOverTime = 0;
destroyEmission.SetBursts(new ParticleSystem.Burst[] {
new ParticleSystem.Burst(0f, destroyParticleCount)
});
var destroyShape = destroyParticles.shape;
destroyShape.shapeType = ParticleSystemShapeType.Circle;
destroyShape.radius = 0.3f;
// Добавляем физику для частиц уничтожения
var destroyPhysics = destroyParticles.externalForces;
destroyPhysics.multiplier = 1f;
// Устанавливаем сортировку частиц поверх блока и назначаем материал
var hitRenderer = hitParticles.GetComponent<ParticleSystemRenderer>();
var destroyRenderer = destroyParticles.GetComponent<ParticleSystemRenderer>();
hitRenderer.material = particleMaterial;
destroyRenderer.material = particleMaterial;
hitRenderer.sortingOrder = spriteRenderer.sortingOrder + 2;
destroyRenderer.sortingOrder = spriteRenderer.sortingOrder + 2;
}
protected virtual void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Ball"))
{
OnCollisionEffect(collision);
TakeHit();
}
}
protected virtual void OnCollisionEffect(Collision2D collision)
{
// Базовая реализация пустая
}
protected virtual void TakeHit()
{
// Базовая реализация - просто уничтожаем блок
PlayDestroyEffect();
GameManager.Instance.AddScore(points);
GameManager.Instance.BrickDestroyed();
GameManager.Instance.CheckWinCondition();
Destroy(gameObject);
}
protected void PlayHitEffect()
{
if (hitParticles != null)
{
var hitMain = hitParticles.main;
hitMain.startColor = spriteRenderer.color;
hitParticles.Play();
}
}
protected void PlayDestroyEffect()
{
if (destroyParticles != null)
{
// Создаем копию материала для финального взрыва
Material destroyMaterial = new Material(particleMaterial);
var destroyRenderer = destroyParticles.GetComponent<ParticleSystemRenderer>();
destroyRenderer.material = destroyMaterial;
// Запускаем эффект уничтожения
var destroyMain = destroyParticles.main;
destroyMain.startColor = spriteRenderer.color;
// Отсоединяем систему частиц и запускаем её
destroyParticles.transform.SetParent(null);
destroyParticles.Play();
// Уничтожаем систему частиц и её материал после проигрывания
Destroy(destroyMaterial, destroyParticleLifetime);
Destroy(destroyParticles.gameObject, destroyParticleLifetime);
}
}
protected virtual void OnDestroy()
{
if (particleMaterial != null)
{
Destroy(particleMaterial);
}
}
}