ArkanoidTG/Assets/Scripts/Brick.cs

188 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}