Build TravelRun intro and tutorial flow

This commit is contained in:
jongjae0305
2026-07-06 16:15:20 +09:00
parent af26dd4311
commit 2ba3882f1b
153 changed files with 13625 additions and 2086 deletions
+44 -11
View File
@@ -1,4 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// PlayerController는 플레이어 캐릭터로서 Player 게임 오브젝트를 제어한다.
@@ -7,6 +8,7 @@ public class PlayerController : MonoBehaviour {
public float jumpForce = 700f; // 점프 힘
public int maxJumpCount = 2; // 최대 점프 횟수
public float invincibleDuration = 1.5f; // 피해를 입은 뒤 무적 시간
public float groundStickGraceTime = 0.12f; // 발판 이음새에서 접지가 아주 잠깐 끊겨도 유지하는 시간
private int jumpCount = 0; // 누적 점프 횟수
private bool isGrounded = false; // 바닥에 닿았는지 나타냄
@@ -18,6 +20,8 @@ public class PlayerController : MonoBehaviour {
private Animator animator; // 사용할 애니메이터 컴포넌트
private AudioSource playerAudio; // 사용할 오디오 소스 컴포넌트
private SpriteRenderer spriteRenderer; // 플레이어 스프라이트 표시 컴포넌트
private readonly HashSet<Collider2D> groundContacts = new HashSet<Collider2D>(); // 현재 밟고 있는 발판 콜라이더
private float lastGroundedTime = -999f; // 마지막으로 발판에 닿아 있던 시간
private CapsuleCollider2D playerCollider; // 플레이어의 콜라이더 충돌 범위
private Vector2 originalColliderSize; // 기본 자세일 때 콜라이더 크기
@@ -42,7 +46,9 @@ public class PlayerController : MonoBehaviour {
}
private void Update() {
if(isDead || !GameFlowManager.IsGameplayActive)
if(isDead
|| !GameFlowManager.IsGameplayActive
|| (GameManager.instance != null && GameManager.instance.IsTutorialGuidePaused))
{
return;
}
@@ -67,14 +73,15 @@ public class PlayerController : MonoBehaviour {
playerRigidbody.linearVelocity = playerRigidbody.linearVelocity * 0.5f;
}
animator.SetBool("Grounded", isGrounded);
bool groundedForMovement = IsGroundedOrRecentlyGrounded();
animator.SetBool("Grounded", groundedForMovement);
// 달리는 중에 마우스 오른쪽 버튼을 누르고 있는 동안 슬라이딩 유지
if(Input.GetMouseButton(1) && isGrounded && !isSliding)
if(Input.GetMouseButton(1) && groundedForMovement && !isSliding)
{
StartSlide();
}
else if((!Input.GetMouseButton(1) || !isGrounded) && isSliding)
else if((!Input.GetMouseButton(1) || !groundedForMovement) && isSliding)
{
EndSlide();
}
@@ -127,23 +134,43 @@ public class PlayerController : MonoBehaviour {
private void OnCollisionEnter2D(Collision2D collision) {
// 어떤 콜라이더와 닿았으며, 충돌 표면이 위쪽을 보고 있으면
if(collision.contacts[0].normal.y > 0.7f)
if(IsGroundContact(collision))
{
isGrounded = true;
groundContacts.Add(collision.collider);
SetGrounded(true);
jumpCount = 0;
}
}
private void OnCollisionExit2D(Collision2D collision) {
// 바닥에서 벗어났음을 감지하는 처리
isGrounded = false;
if(isSliding)
if(groundContacts.Remove(collision.collider) && groundContacts.Count == 0)
{
EndSlide();
SetGrounded(false);
}
}
private bool IsGroundContact(Collision2D collision) {
for(int i = 0; i < collision.contactCount; i++)
{
if(collision.GetContact(i).normal.y > 0.7f)
{
return true;
}
}
return false;
}
private void SetGrounded(bool grounded) {
isGrounded = grounded;
lastGroundedTime = Time.time;
}
private bool IsGroundedOrRecentlyGrounded() {
return isGrounded || Time.time - lastGroundedTime <= groundStickGraceTime;
}
private void StartSlide() {
isSliding = true;
animator.SetBool("Sliding", true);
@@ -170,7 +197,7 @@ public class PlayerController : MonoBehaviour {
if(GameManager.instance != null && GameManager.instance.TryBlockDamageWithItem())
{
StartCoroutine(InvincibleRoutine());
StartCoroutine(DamageBlockCooldownRoutine());
return;
}
@@ -185,6 +212,12 @@ public class PlayerController : MonoBehaviour {
StartCoroutine(InvincibleRoutine());
}
private IEnumerator DamageBlockCooldownRoutine() {
isInvincible = true;
yield return new WaitForSeconds(0.35f);
isInvincible = false;
}
private IEnumerator InvincibleRoutine() {
isInvincible = true;