188 lines
7.8 KiB
C#
188 lines
7.8 KiB
C#
|
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);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|