2026-05-29 로딩기능

This commit is contained in:
2026-05-29 12:25:32 +09:00
parent 7ad70e7997
commit 3190f10d7d
19 changed files with 167 additions and 29 deletions

Binary file not shown.

BIN
Assets/01_Scenes/StartScene.unity LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 574088315a171654bbc98babcf5060aa
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4179e627078d1c649986e7fa997e344d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
using System;
using System.Threading;
using UnityEngine;
public static class Util
{
/// 특정 시간(초) 후에 액션을 실행
public static async Awaitable RunDelayed(float delay, Action action, CancellationToken token = default)
{
try
{
// 유니티 전용 비동기 대기
await Awaitable.WaitForSecondsAsync(delay, token);
// 함수 실행
action?.Invoke();
}
catch (OperationCanceledException)
{
// 취소되었을 때의 처리 (필요 시)
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ff3976febb8799345a121b8ca2a28e3d

View File

@@ -28,6 +28,7 @@ public class Enemy : MonoBehaviour, IDamageable
[SerializeField] private Color _hitFlashColor = Color.red; // 깜빡 색상 [SerializeField] private Color _hitFlashColor = Color.red; // 깜빡 색상
[SerializeField] private float _hitStunDuration = 0.25f; // ActionData 값이 없을 때 쓰는 기본 경직 시간 [SerializeField] private float _hitStunDuration = 0.25f; // ActionData 값이 없을 때 쓰는 기본 경직 시간
[SerializeField] private string _hitAnimationState = "HitDamage"; // 공격 데이터에 피격 애니가 없을 때 재생할 기본 State [SerializeField] private string _hitAnimationState = "HitDamage"; // 공격 데이터에 피격 애니가 없을 때 재생할 기본 State
[SerializeField] private bool _hasSuperArmor = false; // true면 경직/넉백 무시 (데미지·플래시는 받음). 보스 등 패턴 유지용
// ─── 넉백 / 벽 반사 파라미터 ───────────────────────────────────────── // ─── 넉백 / 벽 반사 파라미터 ─────────────────────────────────────────
[Header("Hit Bounce")] [Header("Hit Bounce")]
@@ -92,7 +93,7 @@ public class Enemy : MonoBehaviour, IDamageable
public bool IsGrabbable => _isGrabbable; public bool IsGrabbable => _isGrabbable;
public bool IsInvulnerable => _isInvulnerable; public bool IsInvulnerable => _isInvulnerable;
public bool IsInHitReaction => _hitStunTimer > 0f || _hitReactionTimer > 0f || _isHitPositionCorrecting || _flashTimer > 0f; public bool IsInHitReaction => _hitStunTimer > 0f || _hitReactionTimer > 0f || _isHitPositionCorrecting || _flashTimer > 0f;
public bool CanUseAI => !IsDead && !_isGrabbed && !IsInHitReaction; public bool CanUseAI => !IsDead && !_isGrabbed && (_hasSuperArmor || !IsInHitReaction);
public event Action OnDamaged; public event Action OnDamaged;
@@ -287,29 +288,34 @@ public void TakeDamage(int amount, Vector2 hitVelocity = default, string hitReac
// 무적이면 데미지/플래시/넉백 전부 무시. // 무적이면 데미지/플래시/넉백 전부 무시.
if (_isInvulnerable) return; if (_isInvulnerable) return;
float appliedHitStunDuration = hitStunDuration >= 0f ? hitStunDuration : _hitStunDuration;
_hitStunTimer = Mathf.Max(_hitStunTimer, appliedHitStunDuration);
OnDamaged?.Invoke(); OnDamaged?.Invoke();
_isGrabbed = false; _isGrabbed = false;
StartHitFlash(); StartHitFlash(); // 피격 플래시는 슈퍼아머여도 유지 (타격감 피드백)
PlayHitAnimation(hitReactionAnimationState);
// 새 피격이 반응 속도를 전부 결정하므로, 이전 튕김/넉백 속도는 먼저 제거한다. // 슈퍼아머: 경직 타이머·피격 모션·넉백·위치 보정을 전부 생략 → 패턴이 안 끊긴다.
if (_rb != null) if (!_hasSuperArmor)
{ {
_hitReactionTimer = 0f; float appliedHitStunDuration = hitStunDuration >= 0f ? hitStunDuration : _hitStunDuration;
_rb.linearVelocity = Vector2.zero; _hitStunTimer = Mathf.Max(_hitStunTimer, appliedHitStunDuration);
_lastVelocity = Vector2.zero; PlayHitAnimation(hitReactionAnimationState);
BeginHitTargetPositionCorrection(hitTargetPosition, correctHitTargetY, hitPositionSolidMask, hitPositionCorrectionDuration); // 새 피격이 반응 속도를 전부 결정하므로, 이전 튕김/넉백 속도는 먼저 제거한다.
if (_rb != null)
Vector2 nextVelocity = GetHitReactionVelocity(hitVelocity);
if (nextVelocity != Vector2.zero)
{ {
_rb.linearVelocity = nextVelocity; _hitReactionTimer = 0f;
_lastVelocity = nextVelocity; _rb.linearVelocity = Vector2.zero;
_hitReactionTimer = _hitReactionDuration; _lastVelocity = Vector2.zero;
BeginHitTargetPositionCorrection(hitTargetPosition, correctHitTargetY, hitPositionSolidMask, hitPositionCorrectionDuration);
Vector2 nextVelocity = GetHitReactionVelocity(hitVelocity);
if (nextVelocity != Vector2.zero)
{
_rb.linearVelocity = nextVelocity;
_lastVelocity = nextVelocity;
_hitReactionTimer = _hitReactionDuration;
}
} }
} }

View File

@@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data;
using System.Threading; using System.Threading;
using TMPro; using TMPro;
using UnityEditor.Playables;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@@ -74,7 +72,11 @@ public class WaveManager : MonoBehaviour
private void Start() private void Start()
{ {
OnAllWavesCleared += StageClearEvent; OnAllWavesCleared += StageClearEvent;
if (_startOnAwake) StartWaves();
if (_startOnAwake)
{
_ = Util.RunDelayed(1f,StartWaves,destroyCancellationToken);
}
} }
private void OnDestroy() private void OnDestroy()

View File

@@ -1,10 +1,19 @@
using System; using System;
using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneLoadManager : MonoBehaviour public class SceneLoadManager : MonoBehaviour
{ {
public static SceneLoadManager Instance; public static SceneLoadManager Instance;
public GameObject LoadingScreen;
public Image LoadingBack;
public Image LoadingBar;
public TMP_Text LoadingText;
public TMP_Text LoadingDesc;
private void Awake() private void Awake()
{ {
if (Instance == null) if (Instance == null)
@@ -47,11 +56,17 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
public void SetSceneLoadingProgressValue(float value) public void SetSceneLoadingProgressValue(float value)
{ {
LoadingBar.fillAmount = value;
LoadingText.text = $"{(value * 100):F0}% 로딩중";
} }
public void SetSceneLoadingProgressValue(float value,string loadingText)
{
public void ShowLoadingScreen()
{
LoadingScreen.SetActive(true);
}
public void HideLoadingScreen()
{
LoadingScreen.SetActive(false);
} }
public void RequestSceneChange(string sceneName) public void RequestSceneChange(string sceneName)
@@ -66,6 +81,8 @@ private async Awaitable SceneChange(string sceneName)
//로딩바 수치 0으로 설정 //로딩바 수치 0으로 설정
SetSceneLoadingProgressValue(0f); SetSceneLoadingProgressValue(0f);
ShowLoadingScreen();
AsyncOperation op = SceneManager.LoadSceneAsync(sceneName); AsyncOperation op = SceneManager.LoadSceneAsync(sceneName);
//자동 전환을 하고 싶지 않을 경우 해당값을 false로 두었다가 true로 바꾸면 그 때 전환됨 //자동 전환을 하고 싶지 않을 경우 해당값을 false로 두었다가 true로 바꾸면 그 때 전환됨
@@ -106,6 +123,7 @@ private async Awaitable SceneChange(string sceneName)
await Awaitable.NextFrameAsync(this.destroyCancellationToken); await Awaitable.NextFrameAsync(this.destroyCancellationToken);
} }
HideLoadingScreen();
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 76518ea418ac2c042bd3f2fbacb6ef73
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
public class GameStartMenu : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 262ea0233379d764f8febbbbbf4a3572

8
Assets/13_Font.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9ce61450de6a40b4f8b2bd1f7ed2e992
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 410a6a4ee139d2248a64c0d89ed4bbfb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/13_Font/MaruMinya.ttf LFS Normal file

Binary file not shown.

View File

@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: 73782f8bf1f391a4ea4d89f22c818efe
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontNames:
- x12y12pxMaruMinyaHangul
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant: