오늘의 학습 키워드
1. 필수과제 진행

코드를 대충 다 마무리 했다.
내가 한 부분인 GameManager
using UnityEngine.SceneManagement;
using UnityEngine;
using System.IO;
public class GameManager : MonoBehaviour
{
private readonly string dataPath = "Data";
public int BestScore { get; private set; }
public static GameManager Instance;
private bool isGameOver = false;
private float timeSinceLastDifficultyIncrease = 0f;
private PlayerController player;
[Header("난이도 설정")]
public float difficultyIncreaseInterval = 10f; // 난이도 상승 주기
public float obstacleSpawnRate = 2f; // 초기 스폰간격 (초)
public float obstacleSpeed = 5f; // 초기 장애물 속도
public float playerGodMode = 1f; // 초기 무적 시간 (초)
[Header("난이도 변화량")]
public float spawnRateDecrease = 0.1f;
public float speedIncrease = 0.5f;
public float playerGodModeDecrease = 0.05f;
public int coinCount = 0;
public int score = 0;
private UIManager uiManager;
//UI 매니저 생성후 연결해주세요
public class ScoreData
{
public int bestScore;
}
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else Destroy(gameObject);
uiManager = FindObjectOfType<UIManager>();
}
private void Start()
{
player = FindObjectOfType<PlayerController>();
LoadBestScore();
uiManager.UpdateScore(0, 0);
if (player != null)
player.ActivateGodMode(playerGodMode); // 무적 모드 적용
}
private void Update()
{
timeSinceLastDifficultyIncrease += Time.deltaTime;
if (timeSinceLastDifficultyIncrease >= difficultyIncreaseInterval)
{
IncreaseDifficulty();
timeSinceLastDifficultyIncrease = 0f;
}
}
private void IncreaseDifficulty()
{
//스폰 간격 줄임. 근데 최소값보장
obstacleSpawnRate = Mathf.Max(0.5f, obstacleSpawnRate - spawnRateDecrease);
// 속도는 계속 증가 가능
obstacleSpeed += speedIncrease;
// 무적시간은 너무낮아지지않게 최소값보장.
playerGodMode = Mathf.Max(0.3f, playerGodMode - playerGodModeDecrease);
if (player != null)
{
player.Speed += speedIncrease; // 플레이어 속도도 증가
}
}
public void AddScore(int value)
{
if (!isGameOver)
{
score += value;
coinCount++;
uiManager.UpdateScore(score,coinCount);
}
}
public void GameOver()
{
if (isGameOver) return;
isGameOver = true;
//게임정지
SaveBestScore();
Time.timeScale = 0f;
PlayerController player = FindObjectOfType<PlayerController>();
if (player != null)
player.enabled = false;
uiManager.SetGameOver();
}
public void RestartGame()
{
Time.timeScale = 1f;
SceneLoader.LoadScene(SceneManager.GetActiveScene().name);
}
//GameOverPanel UIManager연결해주세요.
//GameOverUI속 Button에 GameManager.RestartGame() 함수 선택해주세요.
//re:Ui에서 버튼클릭이벤트 연결해두고 게임매니저메소드 호출하는식으로 변경했습니다.
public void PauseGame()
{
Time.timeScale = 0f;
}
public void ResumeGame()
{
Time.timeScale = 1f;
}
public void SaveBestScore()
{
if (score > BestScore)
{
BestScore = score;
ScoreData data = new ScoreData { bestScore = BestScore };
string json = JsonUtility.ToJson(data, true);
string fullPath = Path.Combine(Application.dataPath, "Resources/Data.json");
File.WriteAllText(fullPath, json);
#if UNITY_EDITOR
UnityEditor.AssetDatabase.Refresh(); // 에디터 상에서 바로 반영됨
#endif
}
}
private void LoadBestScore()
{
TextAsset jsonText = Resources.Load<TextAsset>(dataPath);
if (jsonText != null)
{
ScoreData data = JsonUtility.FromJson<ScoreData>(jsonText.text);
BestScore = data.bestScore;
}
else
{
Debug.LogWarning("Data.json 파일없음. 기본값 0 사용.");
BestScore = 0;
}
}
}
오늘은 Data.json을 연결하고 그후에, 로드 , 세이브 까지 작성했다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : Unit
{
private bool isGodMode = false;
private float godModeTimer = 0f;
private bool isDead = false;
public float hitDamage = 20f; // 충돌 시 감소할 체력
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Coin"))
{
GameManager.Instance.AddScore(10);
Destroy(other.gameObject);
return;
}
if (isGodMode || isDead) return;
if (other.CompareTag("Enemy") || other.CompareTag("Obstacle"))
{
TakeDamage(hitDamage);
}
}
private void TakeDamage(float amount)
{
Hp -= amount;
if (Hp <= 0)
{
isDead = true;
GameManager.Instance.GameOver();
return;
}
ActivateGodMode(GameManager.Instance.playerGodMode);
}
protected override float Hp
{
get { return hp; }
set
{
hp = Mathf.Clamp(value, 0, fullHP);
}
}
protected override float JumpForce
{
get { return jumpForce; }
set
{
jumpForce = Mathf.Max(0, value);
}
}
public override float Speed
{
get { return speed; }
set
{
speed = Mathf.Max(0, value);
}
}
private void Awake()
{
base.Awake();
Hp = 100f;
JumpForce = 5f;
Speed = 5f;
}
private void Update()
{
DecreaseHpByDistance();
//땅에 오브젝트가 닿았는지 확인
isGrounded = Physics2D.Raycast(transform.position, Vector2.down, groundRayLength, groundLayer);
//점프
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
Jump();
}
animCtrl.JumpAnim(isGrounded);
//슬라이드
PressedShift = Input.GetKey(KeyCode.LeftShift);
if (PressedShift)
{
Slide(PressedShift);
}
// 무적 시간 감소
if (isGodMode)
{
godModeTimer -= Time.deltaTime;
if (godModeTimer <= 0f)
{
isGodMode = false;
GetComponentInChildren<SpriteRenderer>().color = Color.white; // 색 복원
}
}
}
private void FixedUpdate()
{
Move();
}
public override void Move()
{
tr.Translate(Vector3.right * Speed * Time.fixedDeltaTime, Space.World);
}
public override void Jump()
{
rb.AddForce(Vector2.up * JumpForce, ForceMode2D.Impulse);
}
public override void Slide(bool PressedShift)
{
animCtrl.SlideAnim(PressedShift);
}
public void ActivateGodMode(float duration)
{
isGodMode = true;
godModeTimer = duration;
StartCoroutine(FlashWhileInvincible());
}
private IEnumerator FlashWhileInvincible()
{
SpriteRenderer sr = GetComponentInChildren<SpriteRenderer>();
while (isGodMode)
{
sr.color = new Color(1, 1, 1, 0.5f); // 반투명
yield return new WaitForSeconds(0.1f);
sr.color = Color.white;
yield return new WaitForSeconds(0.1f);
}
}
public override void DecreaseHpByDistance()
{
//거리에 따른 체력 감소
hp -= playerDistance.distance * 0.001f;
}
}
그리고 여기에 있는 부딪혔을때 태그에 따라 반응 하는 코드를 추가로 작성헀다.