Initial commit: Tiny Tackle Heroes Unity project
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using BumpCombat.Core;
|
||||
using BumpCombat.Enemies;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BumpCombat.Constants
|
||||
{
|
||||
[Serializable]
|
||||
public struct SpawnDensityPhase
|
||||
{
|
||||
[Tooltip("다음 단계로 넘어가는 진행시간 (초). 마지막 단계는 무시됩니다.")]
|
||||
public float EndTimeSeconds;
|
||||
[Min(0)] public int CrowdTarget;
|
||||
[Min(0)] public int NormalTarget;
|
||||
|
||||
public SpawnDensityPhase(float endTimeSeconds, int crowdTarget, int normalTarget)
|
||||
{
|
||||
EndTimeSeconds = endTimeSeconds;
|
||||
CrowdTarget = crowdTarget;
|
||||
NormalTarget = normalTarget;
|
||||
}
|
||||
}
|
||||
|
||||
[CreateAssetMenu(menuName = "BumpCombat/Constants/Run and Spawning")]
|
||||
public sealed class RunConstants : ScriptableObject
|
||||
{
|
||||
[Header("런 이벤트 시간표 (초)")]
|
||||
public float[] DevelopmentEliteEventTimes = { 36f, 72f, 108f, 144f, 180f, 216f };
|
||||
public float[] FormalEliteEventTimes = { 180f, 360f, 540f, 720f, 900f, 1080f };
|
||||
public float[] ProductionEliteEventTimes = { 180f, 360f, 540f, 720f };
|
||||
[Min(0f)] public float DevelopmentProgressionMultiplier = 5f;
|
||||
[Min(0f)] public float DevelopmentMidBossEventTime = 120f;
|
||||
[Min(0f)] public float DevelopmentFinalBossEventTime = 240f;
|
||||
[Min(0f)] public float FormalMidBossEventTime = 600f;
|
||||
[Min(0f)] public float FormalFinalBossEventTime = 1200f;
|
||||
[Min(0f)] public float ProductionMidBossEventTime = 600f;
|
||||
[Min(0f)] public float ProductionFinalBossEventTime = 900f;
|
||||
[Min(0)] public int DevelopmentStartupArtifactSelectionCount = 3;
|
||||
[Min(0)] public int ProductionStartupArtifactSelectionCount = 1;
|
||||
[Min(0)] public int LegacyStartupArtifactSelectionCount = 3;
|
||||
|
||||
[Header("스폰 밀도 단계")]
|
||||
[Tooltip("순서대로 시작시점, 1분, 3분, 5분, 10분 이후의 군중형/일반형 목표 수")]
|
||||
public SpawnDensityPhase[] SpawnDensity =
|
||||
{
|
||||
new(60f, 3, 3), new(180f, 6, 4), new(300f, 12, 4),
|
||||
new(600f, 19, 5), new(float.PositiveInfinity, 27, 5),
|
||||
};
|
||||
[Min(0)] public int TimedEventCrowdTarget = 5;
|
||||
[Min(0)] public int TimedEventNormalTarget = 3;
|
||||
[Min(0)] public int FinalBossMaximumCrowdTarget = 2;
|
||||
|
||||
[Header("웨이브")]
|
||||
[Min(1)] public int MaximumAliveEnemies = 100;
|
||||
[Min(1)] public int MaximumBossEncounterEnemies = 8;
|
||||
[Min(0.1f)] public float WaveInterval = 5f;
|
||||
[Min(0.1f)] public float TimedEventWaveInterval = 12f;
|
||||
[Min(1)] public int MaximumWaveSize = 3;
|
||||
[Min(1)] public int MaximumTimedEventWaveSize = 1;
|
||||
[Min(0f)] public float InitialWaveDelay = 0.5f;
|
||||
|
||||
[Header("실제 플레이 유입량·습격")]
|
||||
[Min(0)] public int ProductionWaveCrowdSize = 2;
|
||||
[Min(0)] public int ProductionWaveNormalSize = 1;
|
||||
[Min(0)] public int ProductionTimedEventCrowdSize = 1;
|
||||
[Min(0f)] public float ProductionSwarmInterval = 90f;
|
||||
[Min(0f)] public float ProductionSwarmBossExclusionWindow = 30f;
|
||||
[Min(0f)] public float ProductionSwarmEarlyEndTime = 300f;
|
||||
[Min(0f)] public float ProductionSwarmMidEndTime = 600f;
|
||||
[Min(0)] public int ProductionSwarmEarlyCount = 16;
|
||||
[Min(0)] public int ProductionSwarmMidCount = 20;
|
||||
[Min(0)] public int ProductionSwarmLateCount = 24;
|
||||
[Min(1)] public int ProductionSwarmBatchSize = 4;
|
||||
[Min(0.1f)] public float ProductionSwarmBatchInterval = 2f;
|
||||
|
||||
[Header("스폰 위치")]
|
||||
[Min(0f)] public float SpawnEdgeInset = 0.25f;
|
||||
[Min(0f)] public float PlayerSafeSpawnDistance = 4f;
|
||||
[Min(0f)] public float SpawnCameraMargin = 0.5f;
|
||||
[Min(0f)] public float SummonSpawnRadius = 2.5f;
|
||||
[Min(0f)] public float SummonSpawnMinimumSeparation = 1.5f;
|
||||
[Min(0f)] public float SummonSpawnPlayerClearance = 1.25f;
|
||||
public Vector2 FallbackSpawnHalfExtents = new(14.5f, 7.8125f);
|
||||
[Tooltip("시간 중간보스의 후보 프리팹 종류")]
|
||||
public EnemyKind[] MidBossKinds = { EnemyKind.GreatswordSkeleton, EnemyKind.NecroGolem };
|
||||
|
||||
[Header("이벤트 적 기본 튜닝")]
|
||||
public RunEventEnemyTuning EliteTuning = RunEventEnemyTuning.Create(
|
||||
EnemyKind.Lancer, 3f, 30, 1.25f, Color.white, 1.05f, 1.1f, 0.85f, 1f,
|
||||
0.7f, 1f, 1.1f, 1.15f, 1f, 2, 0.7f, 0.35f, 2, 0.65f, true);
|
||||
public RunEventEnemyTuning MidBossTuning = RunEventEnemyTuning.Create(
|
||||
EnemyKind.GreatswordSkeleton, 8f, 100, 1.6f, new Color(1f, 0.35f, 0.3f),
|
||||
0.9f, 1.25f, 0.95f, 1f, 0.8f, 1.15f, 1f, 1f, 1.35f, 2, 0.7f,
|
||||
0.4f, 3, 0.3f, false);
|
||||
public RunEventEnemyTuning FinalBossTuning = RunEventEnemyTuning.Create(
|
||||
EnemyKind.Warlock, 15f, 0, 2f, new Color(0.75f, 0.35f, 1f), 0.85f,
|
||||
1.25f, 0.9f, 1f, 0.75f, 1f, 1f, 1f, 1.25f, 3, 0.75f, 0.3f,
|
||||
4, 0.15f, false);
|
||||
[Min(1f)] public float ProductionMidBossHealthMultiplier = 7f;
|
||||
[Min(1f)] public float ProductionFinalBossHealthMultiplier = 12f;
|
||||
[Tooltip("순서대로 첫 번째, 두 번째, 세 번째, 이후 시간 엘리트 체력 배율")]
|
||||
public float[] ProductionEliteHealthMultipliers = { 2.5f, 3.5f, 3.5f, 5f };
|
||||
[Tooltip("순서대로 첫 번째, 두 번째, 세 번째, 이후 시간 엘리트 공격 배율")]
|
||||
public float[] ProductionEliteAttackDamageMultipliers = { 1f, 1f, 1.1f, 1.2f };
|
||||
[Tooltip("순서대로 첫 번째, 두 번째, 세 번째, 이후 시간 엘리트 연속 공격 수")]
|
||||
public int[] ProductionEliteAttacksPerSequence = { 1, 2, 3, 2 };
|
||||
[Tooltip("엘리트 순환에 사용할 적 종류")]
|
||||
public EnemyKind[] EliteKinds =
|
||||
{
|
||||
EnemyKind.ArmoredSkeleton,
|
||||
EnemyKind.Werewolf,
|
||||
EnemyKind.Werebear,
|
||||
};
|
||||
[Tooltip("개발 런에서 순서대로 적용할 엘리트 연속 공격 수")]
|
||||
public int[] DevelopmentEliteAttacksPerSequence = { 2, 2, 3 };
|
||||
[Tooltip("생산 런에서 순서대로 적용할 엘리트 경고시간 배율")]
|
||||
public float[] ProductionEliteWarningDurationMultipliers = { 1f, 0.85f, 0.85f, 0.85f };
|
||||
[Tooltip("생산 런에서 순서대로 적용할 엘리트 회복시간 배율")]
|
||||
public float[] ProductionEliteRecoveryDurationMultipliers = { 1f, 0.7f, 0.7f, 0.7f };
|
||||
|
||||
[Header("전장")]
|
||||
public Vector2 ArenaBackgroundHalfExtents = new(15f, 8.4375f);
|
||||
public Vector2 ArenaPlayableHalfExtents = new(15f, 8.4375f);
|
||||
public Vector2 ArenaPlayerPadding = new(0.5f, 0.625f);
|
||||
public Vector2 ArenaCameraViewHalfExtents = new(10f, 5.625f);
|
||||
public Vector2 ArenaCameraDeadZone = new(0.5f, 0.3f);
|
||||
[Min(0f)] public float ArenaCameraSmoothTime = 0.15f;
|
||||
|
||||
public float[] EliteTimes(bool development, bool production)
|
||||
{
|
||||
float[] times = production
|
||||
? ProductionEliteEventTimes
|
||||
: development ? DevelopmentEliteEventTimes : FormalEliteEventTimes;
|
||||
return times ?? Array.Empty<float>();
|
||||
}
|
||||
|
||||
public SpawnDensityPhase GetSpawnDensity(float elapsedTime)
|
||||
{
|
||||
if (SpawnDensity == null || SpawnDensity.Length == 0)
|
||||
{
|
||||
return new SpawnDensityPhase(float.PositiveInfinity, 27, 5);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SpawnDensity.Length - 1; i++)
|
||||
{
|
||||
if (elapsedTime < SpawnDensity[i].EndTimeSeconds)
|
||||
{
|
||||
return SpawnDensity[i];
|
||||
}
|
||||
}
|
||||
|
||||
return SpawnDensity[SpawnDensity.Length - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user