
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StartDirector : MonoBehaviour
{
[SerializeField] private Cinemachine.CinemachineVirtualCamera virtualCamera;
[SerializeField] private GameObject player;
[SerializeField] private float titleFadeDuration;
[SerializeField] private float PressAnyKeyFadeDuration;
[SerializeField] private GameObject canvas;
[SerializeField] private CanvasRenderer Title;
[SerializeField] private CanvasRenderer PressAnyKey;
[SerializeField] private GameObject middle;
[SerializeField] private float orthTargetSize;
[SerializeField] private float orthSmoothTime;
private bool game_start = false;
private float velocity = 0.0f;
SpriteRenderer playerSprite;
// Start is called before the first frame update
void Start()
{
playerSprite = player.GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
// PressAnyKey.SetAlpha(Mathf.PingPong(Time.time * blinkSpeed, 1)); // Alpha 값을 0과 1 사이로 반복
if (Input.anyKeyDown && !game_start)
{
StartCoroutine(TitleFadeOut());
StartCoroutine(PressAnykeyFadeOut());
}
if (!game_start)
{
PressAnyKey.SetAlpha(Mathf.PingPong(Time.time * 1f, 0.75f) + 0.25f); // Alpha 값을 0.5와 1 사이로 반복
}
}
private IEnumerator TitleFadeOut()
{
game_start = true;
yield return new WaitForSeconds(1.5f); // 1초 대기
float elapsedTime = 0f;
player.SetActive(true);
while (elapsedTime < titleFadeDuration)
{
elapsedTime += Time.deltaTime;
Title.SetAlpha(Mathf.SmoothStep(1f, 0f, elapsedTime / titleFadeDuration)); // 초반에 급하게 사라지다가 후반에 느리게 사라지게
yield return null;
}
yield return new WaitForSeconds(0.5f); // 0.5초 대기
// 완전히 투명해진 뒤 오브젝트 비활성화
canvas.SetActive(false);
elapsedTime = 0f;
while (elapsedTime < titleFadeDuration)
{
elapsedTime += Time.deltaTime;
// 플레이어 sprite renderer alpha 서서히 증가시키기
if (playerSprite != null)
{
playerSprite.color = new Color(playerSprite.color.r, playerSprite.color.g, playerSprite.color.b, Mathf.SmoothStep(0f, 1f, elapsedTime / titleFadeDuration));
}
yield return null;
}
virtualCamera.Follow = middle.transform;
StartCoroutine(SmoothOrthographicSizeChange());
}
private IEnumerator PressAnykeyFadeOut()
{
float elapsedTime = 0f;
while (elapsedTime < PressAnyKeyFadeDuration)
{
elapsedTime += Time.deltaTime;
PressAnyKey.SetAlpha(Mathf.Lerp(1f, 0f, elapsedTime / PressAnyKeyFadeDuration)); // 서서히 Alpha 값을 0으로
yield return null;
}
}
private IEnumerator SmoothOrthographicSizeChange()
{
while (Mathf.Abs(virtualCamera.m_Lens.OrthographicSize - orthTargetSize) > 0.01f)
{
virtualCamera.m_Lens.OrthographicSize = Mathf.SmoothDamp(
virtualCamera.m_Lens.OrthographicSize,
orthTargetSize,
ref velocity,
orthSmoothTime
);
yield return null;
}
// 플레이어 스크립트 활성화
player.GetComponent<Bar_Judge_Movement>().enabled = true;
}
}
씬 연출 코드.
void Update()
{
if (Input.GetMouseButtonDown(1))
{
player.GameOver(); // 디버그용 게임 오버
}
}
게임 매니저에 대충 게임 오버 기능 달아놨는데
public void GameOver()
{
NoteBlock turnOnBlock = missionBlockCollider.GetComponentInParent<NoteBlock>();
while (turnOnBlock.noteBlockIndex != 0)
{
turnOnBlock.EnableCollider();
turnOnBlock = turnOnBlock.prevNoteBlock.GetComponent<NoteBlock>();
}
인덱스 0인 건 콜라이더를 다시 켜주질 않는다. 이거 누가 짬;
NoteBlock turnOnBlock = missionBlockCollider.GetComponentInParent<NoteBlock>();
while (turnOnBlock != null)
{
turnOnBlock.EnableCollider();
turnOnBlock = (turnOnBlock.prevNoteBlock != null)
? turnOnBlock.prevNoteBlock.GetComponent<NoteBlock>() : null;
}
고쳤다.
if (OffsetTestMode) // 오프셋 계산할때만 작동
{
if (missionBlockIndex == 2)
{
WakeUpAllBlocks();
missionBlockIndex = 0;
}
offsetTest.GetOffset();
}
방금 만들었던 블럭 깨우는 함수 따로 메서드로 빼주고 WakeUpAllBlocks()로 호출
이제 두 블럭 사이 와리가리 무한 반복은 됨.
문제는 85bpm 메트로놈 음원 가져와서 정확히 bpm에 맞게 자르고 재생했는데
시간이 지날때마다 박자가 점점 어긋난다는거. 이래서야 박자 오프셋 테스트가 될 수가 없다.
편집 안 한 30분짜리 그대로 갖다 써봤더니 박자는 맞다. 자르는 과정에서 오차 때문에 박자가 어긋났는듯.
그리고 현재 translate의 문제점이 있다. 1프레임 당 이동하는 시간이 있다 보니까 필연적으로 오차가 발생함.
애써 외면해왔던 문제인데, 이제 정확하게 어떻게 계산되는지 생각을 해야할 것 같음.

정확한 파일 길이는 생성 > 리듬 트랙 (audacity 내장 기능)으로 해결
된줄 알았는데 이것도 Loop를 돌려도 재생 딜레이가 있어서 살짝씩 늦춰진다.
무조건 긴 파일로 해야 딜레이 없이 띵동거리는듯.
내장 기능 소리는 길이 재는 용도로 쓰면 될듯. 소리는 메트로놈이 더 나음.
그냥 5분짜리 박아버리려고 했는데, 분명 로딩 될때까지 기다리는데도 인풋 렉이 발생함.
처음 띵동 시작할 때 렉 걸리면서 점프해버리는게 녹화 렉이나 영상 렉이 아니다.
순수 유니티 에디터 렉임.
아니 처음 시작할 때 렉 걸리는거면 시작하자마자 바로 재생하고 바로 다시 멈춰놓은 다음에
필요할 때 다시 틀면 되겠네? 천잰가;
void Start()
{
playerSprite = player.GetComponent<SpriteRenderer>();
Metronome.Play();
Metronome.Pause();
}
놀랍지만 해결됐다.
엉터리같지만 메모리에 올라오는 딜레이를 없앤다는 점에서 완벽한 해결책.
빌드했을 때 게임 시작시 이것 때문에 렉 걸리는지만 확인해보면 될듯.

스팀에 데모 올리려고 스팀웍스 등록하고 있었는데,
상표권 이슈가 갑자기 생각남.
https://brunch.co.kr/@abcip/11
여기에 적힌 바에 의하면 스타필드는 "내려받기 가능한 컴퓨터 프로그램"이라는 것 때문에 문제 생겼다고 하는데
Etude는 첫 번째 용어인 컴퓨터 작동 소프트웨어가 마음에 걸림.
출시명은 살짝 바꿔야할듯
https://musescore.com/user/38235231/scores/5940010
슈만이 작곡한 Little Etude라는 곡도 있다. 이걸 인트로 bgm으로 쓰면 될듯?