TO SQUASH: Nuke ball explosion.
This commit is contained in:
@@ -7,7 +7,7 @@ AnimationClip:
|
|||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: BallExplosionDecal
|
m_Name: BallExplosionDecal
|
||||||
serializedVersion: 7
|
serializedVersion: 8
|
||||||
m_Legacy: 0
|
m_Legacy: 0
|
||||||
m_Compressed: 0
|
m_Compressed: 0
|
||||||
m_UseHighQualityCurve: 1
|
m_UseHighQualityCurve: 1
|
||||||
@@ -22,23 +22,23 @@ AnimationClip:
|
|||||||
curve:
|
curve:
|
||||||
- time: 0
|
- time: 0
|
||||||
value: {fileID: 7210558746331385846, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: 7210558746331385846, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 0.1
|
- time: 0.16666667
|
||||||
value: {fileID: -5432075094247615553, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: -5432075094247615553, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 0.21666667
|
- time: 0.35
|
||||||
value: {fileID: -6233756757657699445, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: -6233756757657699445, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 0.31666666
|
- time: 0.5
|
||||||
value: {fileID: -9134259580595608040, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: -9134259580595608040, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 0.43333334
|
|
||||||
value: {fileID: -6261058792273593043, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
|
||||||
- time: 0.56666666
|
|
||||||
value: {fileID: 7983266495651452045, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
|
||||||
- time: 0.68333334
|
- time: 0.68333334
|
||||||
value: {fileID: 7271509617224618838, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: -6261058792273593043, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 0.78333336
|
|
||||||
value: {fileID: -9122391734515957254, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
|
||||||
- time: 0.9
|
- time: 0.9
|
||||||
|
value: {fileID: 7983266495651452045, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
|
- time: 1.0833334
|
||||||
|
value: {fileID: 7271509617224618838, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
|
- time: 1.25
|
||||||
|
value: {fileID: -9122391734515957254, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
|
- time: 1.4166666
|
||||||
value: {fileID: -6539983120607256907, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: -6539983120607256907, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- time: 1
|
- time: 1.5833334
|
||||||
value: {fileID: 1192567241846995084, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
value: {fileID: 1192567241846995084, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
attribute: m_Sprite
|
attribute: m_Sprite
|
||||||
path:
|
path:
|
||||||
@@ -61,6 +61,7 @@ AnimationClip:
|
|||||||
isPPtrCurve: 1
|
isPPtrCurve: 1
|
||||||
isIntCurve: 0
|
isIntCurve: 0
|
||||||
isSerializeReferenceCurve: 0
|
isSerializeReferenceCurve: 0
|
||||||
|
metaData: 0
|
||||||
pptrCurveMapping:
|
pptrCurveMapping:
|
||||||
- {fileID: 7210558746331385846, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
- {fileID: 7210558746331385846, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
- {fileID: -5432075094247615553, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
- {fileID: -5432075094247615553, guid: 7982a3f8e588f159dbb4a39dda4520a4, type: 3}
|
||||||
@@ -77,7 +78,7 @@ AnimationClip:
|
|||||||
m_AdditiveReferencePoseClip: {fileID: 0}
|
m_AdditiveReferencePoseClip: {fileID: 0}
|
||||||
m_AdditiveReferencePoseTime: 0
|
m_AdditiveReferencePoseTime: 0
|
||||||
m_StartTime: 0
|
m_StartTime: 0
|
||||||
m_StopTime: 1.0166667
|
m_StopTime: 1.6
|
||||||
m_OrientationOffsetY: 0
|
m_OrientationOffsetY: 0
|
||||||
m_Level: 0
|
m_Level: 0
|
||||||
m_CycleOffset: 0
|
m_CycleOffset: 0
|
||||||
@@ -96,4 +97,11 @@ AnimationClip:
|
|||||||
m_EulerEditorCurves: []
|
m_EulerEditorCurves: []
|
||||||
m_HasGenericRootTransform: 0
|
m_HasGenericRootTransform: 0
|
||||||
m_HasMotionFloatCurves: 0
|
m_HasMotionFloatCurves: 0
|
||||||
m_Events: []
|
m_Events:
|
||||||
|
- time: 1.5833334
|
||||||
|
functionName: DestroySpark
|
||||||
|
data:
|
||||||
|
objectReferenceParameter: {fileID: 0}
|
||||||
|
floatParameter: 0
|
||||||
|
intParameter: 0
|
||||||
|
messageOptions: 0
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ GameObject:
|
|||||||
- component: {fileID: 1846621201000746085}
|
- component: {fileID: 1846621201000746085}
|
||||||
- component: {fileID: 7402419950365427160}
|
- component: {fileID: 7402419950365427160}
|
||||||
- component: {fileID: 4492134503030492876}
|
- component: {fileID: 4492134503030492876}
|
||||||
|
- component: {fileID: 7068514341266521413}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Ball Explosion
|
m_Name: Ball Explosion
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -115,3 +116,15 @@ Animator:
|
|||||||
m_AllowConstantClipSamplingOptimization: 1
|
m_AllowConstantClipSamplingOptimization: 1
|
||||||
m_KeepAnimatorStateOnDisable: 0
|
m_KeepAnimatorStateOnDisable: 0
|
||||||
m_WriteDefaultValuesOnDisable: 0
|
m_WriteDefaultValuesOnDisable: 0
|
||||||
|
--- !u!114 &7068514341266521413
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6718664185715355894}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: bc6262e498fa2d2eba7d1e3d1b58f1cb, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier: Assembly-CSharp::SharkSpark
|
||||||
|
|||||||
@@ -306,3 +306,6 @@ MonoBehaviour:
|
|||||||
hitSound: {fileID: 8300000, guid: a36177a84709d5c51ae647a599008d1d, type: 3}
|
hitSound: {fileID: 8300000, guid: a36177a84709d5c51ae647a599008d1d, type: 3}
|
||||||
criticalSound: {fileID: 8300000, guid: 756fb91b052f83560a8f10a21d610eb1, type: 3}
|
criticalSound: {fileID: 8300000, guid: 756fb91b052f83560a8f10a21d610eb1, type: 3}
|
||||||
explosionSound: {fileID: 8300000, guid: 4b277a57224afa7df868a42f9005709e, type: 3}
|
explosionSound: {fileID: 8300000, guid: 4b277a57224afa7df868a42f9005709e, type: 3}
|
||||||
|
destroySound: {fileID: 8300000, guid: f4dab77a6338f5d0ca6038bad0c87d87, type: 3}
|
||||||
|
explosionEffectPrefab: {fileID: 6718664185715355894, guid: 0fa4013691ac1bf6eae3a2ac6c7c35ff, type: 3}
|
||||||
|
worldFiller: {fileID: 0}
|
||||||
|
|||||||
@@ -6287,6 +6287,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 2071167547}
|
- component: {fileID: 2071167547}
|
||||||
- component: {fileID: 2071167548}
|
- component: {fileID: 2071167548}
|
||||||
|
- component: {fileID: 2071167549}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: WorldFiller
|
m_Name: WorldFiller
|
||||||
m_TagString: WorldFiller
|
m_TagString: WorldFiller
|
||||||
@@ -6324,9 +6325,108 @@ MonoBehaviour:
|
|||||||
player: {fileID: 1002905792}
|
player: {fileID: 1002905792}
|
||||||
gameBoardSpriteRenderer: {fileID: 297740151}
|
gameBoardSpriteRenderer: {fileID: 297740151}
|
||||||
wallPrefab: {fileID: 2746972694419659216, guid: 3fbc857440f3c649b9d49d40955db450, type: 3}
|
wallPrefab: {fileID: 2746972694419659216, guid: 3fbc857440f3c649b9d49d40955db450, type: 3}
|
||||||
|
ballSpawner: {fileID: 240489636}
|
||||||
|
areaDestroyed: {fileID: 8300000, guid: f4dab77a6338f5d0ca6038bad0c87d87, type: 3}
|
||||||
fallbackBarThicknessWorldUnits: 0.08
|
fallbackBarThicknessWorldUnits: 0.08
|
||||||
geometryEpsilon: 0.0001
|
geometryEpsilon: 0.0001
|
||||||
wallPaddingPixelsPerSide: 2
|
wallPaddingPixelsPerSide: 2
|
||||||
|
--- !u!82 &2071167549
|
||||||
|
AudioSource:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2071167546}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 4
|
||||||
|
OutputAudioMixerGroup: {fileID: 0}
|
||||||
|
m_audioClip: {fileID: 0}
|
||||||
|
m_Resource: {fileID: 0}
|
||||||
|
m_PlayOnAwake: 1
|
||||||
|
m_Volume: 1
|
||||||
|
m_Pitch: 1
|
||||||
|
Loop: 0
|
||||||
|
Mute: 0
|
||||||
|
Spatialize: 0
|
||||||
|
SpatializePostEffects: 0
|
||||||
|
Priority: 128
|
||||||
|
DopplerLevel: 1
|
||||||
|
MinDistance: 1
|
||||||
|
MaxDistance: 500
|
||||||
|
Pan2D: 0
|
||||||
|
rolloffMode: 0
|
||||||
|
BypassEffects: 0
|
||||||
|
BypassListenerEffects: 0
|
||||||
|
BypassReverbZones: 0
|
||||||
|
rolloffCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 1
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
panLevelCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
spreadCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 0
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
|
reverbZoneMixCustomCurve:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Curve:
|
||||||
|
- serializedVersion: 3
|
||||||
|
time: 0
|
||||||
|
value: 1
|
||||||
|
inSlope: 0
|
||||||
|
outSlope: 0
|
||||||
|
tangentMode: 0
|
||||||
|
weightedMode: 0
|
||||||
|
inWeight: 0.33333334
|
||||||
|
outWeight: 0.33333334
|
||||||
|
m_PreInfinity: 2
|
||||||
|
m_PostInfinity: 2
|
||||||
|
m_RotationOrder: 4
|
||||||
--- !u!1 &2071745858
|
--- !u!1 &2071745858
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -199,4 +199,9 @@ public class BallBase : MonoBehaviour
|
|||||||
bounds = default;
|
bounds = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StopBall()
|
||||||
|
{
|
||||||
|
speed = new Vector2(0.0f, 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class NukeBall : BallBase
|
public class NukeBall : BallBase
|
||||||
{
|
{
|
||||||
@@ -6,6 +8,8 @@ public class NukeBall : BallBase
|
|||||||
|
|
||||||
public AudioClip explosionSound;
|
public AudioClip explosionSound;
|
||||||
|
|
||||||
|
public GameObject explosionEffectPrefab;
|
||||||
|
|
||||||
public WorldFiller worldFiller;
|
public WorldFiller worldFiller;
|
||||||
|
|
||||||
// Tracks escalating danger/critical phases for audio cues.
|
// Tracks escalating danger/critical phases for audio cues.
|
||||||
@@ -30,6 +34,8 @@ public class NukeBall : BallBase
|
|||||||
|
|
||||||
private float bounceDuration = 1.00f;
|
private float bounceDuration = 1.00f;
|
||||||
|
|
||||||
|
private bool exploding = false;
|
||||||
|
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
@@ -55,6 +61,11 @@ public class NukeBall : BallBase
|
|||||||
// Update is called once per frame
|
// Update is called once per frame
|
||||||
void FixedUpdate()
|
void FixedUpdate()
|
||||||
{
|
{
|
||||||
|
if (exploding)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
||||||
|
|
||||||
if (stateInfo.IsName("NuclearBallBounce")) {
|
if (stateInfo.IsName("NuclearBallBounce")) {
|
||||||
@@ -100,14 +111,20 @@ public class NukeBall : BallBase
|
|||||||
{
|
{
|
||||||
// Set critical state.
|
// Set critical state.
|
||||||
var area = worldFiller != null ? worldFiller.GetAreaPercentOfFreeRegion(transform.position) : -1.0f;
|
var area = worldFiller != null ? worldFiller.GetAreaPercentOfFreeRegion(transform.position) : -1.0f;
|
||||||
criticalState = (area < 0.2f) ? 2 : (area < 0.4f) ? 1 : 0;
|
|
||||||
|
if (area == -1.0f || exploding)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
criticalState = (area < 0.12f) ? 3 : (area < 0.2f) ? 2 : (area < 0.4f) ? 1 : 0;
|
||||||
|
|
||||||
// State 1 beeps every 0.5s, state 2 beeps every 0.25s.
|
// State 1 beeps every 0.5s, state 2 beeps every 0.25s.
|
||||||
criticalTime = (criticalState == 2) ? 0.5f : 1.0f;
|
criticalTime = (criticalState == 2) ? 0.5f : 1.0f;
|
||||||
|
|
||||||
// If in a critical state, increment the critical timer and play the
|
// If in a critical state, increment the critical timer and play the
|
||||||
// critical sound if the timer exceeds the critical time.
|
// critical sound if the timer exceeds the critical time.
|
||||||
if (criticalState >= 1)
|
if (criticalState == 1 || criticalState == 2)
|
||||||
{
|
{
|
||||||
criticalTimer += Time.deltaTime;
|
criticalTimer += Time.deltaTime;
|
||||||
|
|
||||||
@@ -119,6 +136,28 @@ public class NukeBall : BallBase
|
|||||||
criticalTimer -= criticalTime;
|
criticalTimer -= criticalTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (criticalState == 3)
|
||||||
|
{
|
||||||
|
audioSource.PlayOneShot(explosionSound);
|
||||||
|
|
||||||
|
var balls = worldFiller != null ?
|
||||||
|
worldFiller.GetBallsInSameFreeRegion(transform.position) :
|
||||||
|
new Queue<GameObject>();
|
||||||
|
|
||||||
|
foreach (var ball in balls)
|
||||||
|
{
|
||||||
|
ball.GetComponent<BallBase>()?.StopBall();
|
||||||
|
|
||||||
|
if (explosionEffectPrefab != null)
|
||||||
|
{
|
||||||
|
Instantiate(explosionEffectPrefab, ball.transform.position, Quaternion.identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exploding = true;
|
||||||
|
|
||||||
|
StartCoroutine(DestroyAndFillRegion(balls));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
criticalTimer = 0.0f;
|
criticalTimer = 0.0f;
|
||||||
@@ -198,4 +237,25 @@ public class NukeBall : BallBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerator DestroyAndFillRegion(Queue<GameObject> balls)
|
||||||
|
{
|
||||||
|
yield return new WaitForSeconds(1.4f);
|
||||||
|
|
||||||
|
foreach (var ball in balls)
|
||||||
|
{
|
||||||
|
Destroy(ball);
|
||||||
|
}
|
||||||
|
|
||||||
|
var freeRegion = worldFiller != null ?
|
||||||
|
worldFiller.GetFreeRegionOfPosition(transform.position) :
|
||||||
|
null;
|
||||||
|
|
||||||
|
if (freeRegion != null)
|
||||||
|
{
|
||||||
|
worldFiller.FillFreeRegion(freeRegion.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Destroy(gameObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ public class WorldFiller : MonoBehaviour
|
|||||||
|
|
||||||
public GameObject wallPrefab;
|
public GameObject wallPrefab;
|
||||||
|
|
||||||
|
public BallSpawner ballSpawner;
|
||||||
|
|
||||||
|
public AudioClip areaDestroyed;
|
||||||
|
|
||||||
|
private AudioSource audioSource;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float fallbackBarThicknessWorldUnits = 0.08f;
|
private float fallbackBarThicknessWorldUnits = 0.08f;
|
||||||
|
|
||||||
@@ -33,6 +39,7 @@ public class WorldFiller : MonoBehaviour
|
|||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
|
audioSource = GetComponent<AudioSource>();
|
||||||
gameBoardBounds = gameBoardSpriteRenderer.bounds;
|
gameBoardBounds = gameBoardSpriteRenderer.bounds;
|
||||||
InitializeFreeAreas();
|
InitializeFreeAreas();
|
||||||
ClearWalls();
|
ClearWalls();
|
||||||
@@ -317,6 +324,75 @@ public float GetAreaPercentOfFreeRegion(Vector2 position)
|
|||||||
return -1.0f;
|
return -1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Rect? GetFreeRegionOfPosition(Vector2 position)
|
||||||
|
{
|
||||||
|
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
||||||
|
{
|
||||||
|
InitializeFreeAreas();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < freeAreas.Count; i++)
|
||||||
|
{
|
||||||
|
if (RectContainsWithTolerance(freeAreas[i], position))
|
||||||
|
{
|
||||||
|
return freeAreas[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FillFreeRegion(Rect freeRegion)
|
||||||
|
{
|
||||||
|
if ((freeAreas.Count == 0 || boardArea <= geometryEpsilon) && gameBoardSpriteRenderer != null)
|
||||||
|
{
|
||||||
|
InitializeFreeAreas();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryGetMatchingFreeArea(freeRegion, out Rect regionToFill))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Requested region is not currently a free area.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TrySpawnWallInRect(regionToFill))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
audioSource.PlayOneShot(areaDestroyed);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Queue<GameObject> GetBallsInSameFreeRegion(Vector2 position)
|
||||||
|
{
|
||||||
|
Queue<GameObject> ballsInSameRegion = new Queue<GameObject>();
|
||||||
|
|
||||||
|
if (ballSpawner == null)
|
||||||
|
{
|
||||||
|
return ballsInSameRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetRegion = GetFreeRegionOfPosition(position);
|
||||||
|
|
||||||
|
if (targetRegion == null)
|
||||||
|
{
|
||||||
|
return ballsInSameRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ball in ballSpawner.GetBalls())
|
||||||
|
{
|
||||||
|
var ballRegion = GetFreeRegionOfPosition(ball.transform.position);
|
||||||
|
if (ballRegion != null && ballRegion.Value == targetRegion.Value)
|
||||||
|
{
|
||||||
|
ballsInSameRegion.Enqueue(ball);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ballsInSameRegion;
|
||||||
|
}
|
||||||
|
|
||||||
public Vector2 GetRandomPositionInFreeAreas(Bounds? clearingArea = null)
|
public Vector2 GetRandomPositionInFreeAreas(Bounds? clearingArea = null)
|
||||||
{
|
{
|
||||||
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
if (freeAreas.Count == 0 && gameBoardSpriteRenderer != null)
|
||||||
@@ -531,6 +607,180 @@ public float GetAreaPercentOfFreeRegion(Vector2 position)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TryGetMatchingFreeArea(Rect requestedRegion, out Rect matchedRegion)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < freeAreas.Count; i++)
|
||||||
|
{
|
||||||
|
if (RectsApproximatelyEqual(freeAreas[i], requestedRegion))
|
||||||
|
{
|
||||||
|
matchedRegion = freeAreas[i];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matchedRegion = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool RectsApproximatelyEqual(Rect a, Rect b)
|
||||||
|
{
|
||||||
|
return Mathf.Abs(a.xMin - b.xMin) <= geometryEpsilon
|
||||||
|
&& Mathf.Abs(a.yMin - b.yMin) <= geometryEpsilon
|
||||||
|
&& Mathf.Abs(a.xMax - b.xMax) <= geometryEpsilon
|
||||||
|
&& Mathf.Abs(a.yMax - b.yMax) <= geometryEpsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TrySpawnWallInRect(Rect targetRect)
|
||||||
|
{
|
||||||
|
if (wallPrefab == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Wall prefab is not assigned.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameBoardSpriteRenderer == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Game board SpriteRenderer is not assigned.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gameBoardBounds = gameBoardSpriteRenderer.bounds;
|
||||||
|
|
||||||
|
Rect boardRect = Rect.MinMaxRect(
|
||||||
|
gameBoardBounds.min.x,
|
||||||
|
gameBoardBounds.min.y,
|
||||||
|
gameBoardBounds.max.x,
|
||||||
|
gameBoardBounds.max.y
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!TryGetRectIntersection(targetRect, boardRect, out Rect clampedRect))
|
||||||
|
{
|
||||||
|
Debug.LogWarning("Target wall rectangle is outside the game board bounds.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject wall = Instantiate(wallPrefab, Vector3.zero, Quaternion.identity);
|
||||||
|
var wallRenderer = wall.GetComponentInChildren<SpriteRenderer>();
|
||||||
|
|
||||||
|
if (wallRenderer == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Wall prefab is missing a SpriteRenderer in children.");
|
||||||
|
Destroy(wall);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float wallPaddingWorldUnits = PixelsToWorldUnits(wallPaddingPixelsPerSide, wallRenderer);
|
||||||
|
Rect paddedWallRect = ExpandRectInsideBounds(clampedRect, wallPaddingWorldUnits, boardRect);
|
||||||
|
|
||||||
|
ApplyWallTransform(wall.transform, wallRenderer, paddedWallRect);
|
||||||
|
spawnedWalls.Enqueue(wall);
|
||||||
|
|
||||||
|
UpdateFreeAreas(paddedWallRect);
|
||||||
|
ResolveWallIntersections(wallRenderer.bounds);
|
||||||
|
DestroyBarSegments();
|
||||||
|
|
||||||
|
if (boardArea <= geometryEpsilon)
|
||||||
|
{
|
||||||
|
boardArea = boardRect.width * boardRect.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
int areaPercentage = boardArea > geometryEpsilon
|
||||||
|
? Mathf.RoundToInt((paddedWallRect.width * paddedWallRect.height / boardArea) * 100.0f)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
player.OnWallSpawned(areaPercentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResolveWallIntersections(Bounds wallBounds)
|
||||||
|
{
|
||||||
|
// Yummies and multipliers are awarded if intersected by the spawned wall.
|
||||||
|
var yummies = GameObject.FindGameObjectsWithTag("Yummy");
|
||||||
|
var multipliers = GameObject.FindGameObjectsWithTag("Multiplier");
|
||||||
|
var shark = GameObject.FindGameObjectWithTag("Shark");
|
||||||
|
|
||||||
|
foreach (var yummy in yummies)
|
||||||
|
{
|
||||||
|
if (yummy == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var yummyRenderer = yummy.GetComponent<SpriteRenderer>();
|
||||||
|
if (yummyRenderer == null || !wallBounds.Intersects(yummyRenderer.bounds))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
YummyBase yummyBase = yummy.GetComponent<YummyBase>();
|
||||||
|
|
||||||
|
if (yummyBase != null)
|
||||||
|
{
|
||||||
|
yummyBase.AwardToPlayer(player);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("YummyBase component not found on yummy object.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var multiplier in multipliers)
|
||||||
|
{
|
||||||
|
if (multiplier == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var multiplierRenderer = multiplier.GetComponent<SpriteRenderer>();
|
||||||
|
if (multiplierRenderer == null || !wallBounds.Intersects(multiplierRenderer.bounds))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Multiplier multiplierComponent = multiplier.GetComponent<Multiplier>();
|
||||||
|
|
||||||
|
if (multiplierComponent != null)
|
||||||
|
{
|
||||||
|
multiplierComponent.AwardToPlayer(player);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("Multiplier component not found on multiplier object.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shark == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sharkRenderer = shark.GetComponent<SpriteRenderer>();
|
||||||
|
if (sharkRenderer == null || !wallBounds.Intersects(sharkRenderer.bounds))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shark sharkComponent = shark.GetComponent<Shark>();
|
||||||
|
if (sharkComponent != null)
|
||||||
|
{
|
||||||
|
sharkComponent.KillShark();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DestroyBarSegments()
|
||||||
|
{
|
||||||
|
GameObject[] barSegments = GameObject.FindGameObjectsWithTag("Bar");
|
||||||
|
|
||||||
|
foreach (GameObject barSegment in barSegments)
|
||||||
|
{
|
||||||
|
Destroy(barSegment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplyWallTransform(Transform wallTransform, SpriteRenderer wallRenderer, Rect targetRect)
|
private void ApplyWallTransform(Transform wallTransform, SpriteRenderer wallRenderer, Rect targetRect)
|
||||||
{
|
{
|
||||||
Vector2 baseSize = wallRenderer.bounds.size;
|
Vector2 baseSize = wallRenderer.bounds.size;
|
||||||
|
|||||||
Reference in New Issue
Block a user