Pivot 값을 0으로 두고 X Scale 값을 조정해서 Hp Bar를 표현했다.

원래 체력을 구현할 때 Image 컴포넌트를 사용해여 Image Type을 Filled로 설정해서 구현했었는데 이런 방법도 있다는 것을 알아두면 좋을 듯하다.
게임 오버 시에 Time.timeScale = 0.0f;를 통해 시간을 멈추고 Retry 버튼이 활성화 되도록 했는데 막상 실행해보면 게임이 멈춘거 같은 느낌이 들지를 않는다. 그 이유는 Update 문은 timeScale에 상관없이 실행되기 때문이다. 물론 Update 문이 실행되어도 시간에 의존적인 이동, 애니메이션 같은 로직은 모두 멈추지만 구현한 이동 방식이 매 프레임마다 Position을 바꿔주는 것으로 이동을 구현했기 때문에 Update 문이 계속 돌아가면 멈추지 않고 계속 이동하는 것처럼 보인다.
이를 해결할 방법이 FixedUpdate이다.
FixedUpdate 메서드 : FixedUpdate는 Time.timeScale에 영향을 받기 때문에 timeScale이 0으로 설정되면 FixedUpdate는 호출되지 않는다.
따라서 존재하는 모든 Update를 FixedUpdate로 바꿔주면 timeScale에 따라 멈추는 것을 확인할 수 있다.
void Update()
{
// timeScale에 상관없이 매 프레임마다 실행
}
void FixedUpdate()
{
// timeScale에 상관없이 FixedDeltaTime 간격마다 실행
// FixedDeltaTime은 timeScale의 영향을 받음
}
arr = arr.OrderBy(x => Random.Range(0f, 7f)).ToArray();
사실 OrderBy는 랜덤하게 섞는 것 뿐만 아니라 오름차순, 내림차순으로 정렬할 때도 쓰이는 함수이다.
// 오름차순
var sortedByLength = strings.OrderBy(s => s.Length).ToArray();
// 내림차순
var sortedDescending = numbers.OrderByDescending(n => n).ToArray();
이 때 매개변수를 위처럼 Random.Range로 무작위 값을 넣어주게 되면 리스트를 랜덤하게 섞는 듯한 효과를 볼 수 있다.
랜덤한 값을 주지 않으면 매번 똑같이 리스트가 섞이게 된다. 랜덤하게 섞이는 것 같지만 매번 똑같이 섞이는 것이기 때문에 우리가 원하는 기능과는 전혀 다르다.
아래와 같이 어떤 변수의 값을 특정 범위 내로 제한하고 싶은 경우가 있다.
if (x > 8.5f) {
x = 8.5f;
}
if (x < -8.5f) {
x = -8.5f;
}
이렇게 쓰는 것보다 아래와 같이 Mathf.clamp를 사용하면 간단하게 표현할 수 있다.
x = Mathf.Clamp(x, -8.5f, 8.5f);
카드 뒤집기 할 때 빠르게 뒤집으면 모든 카드를 한번에 뒤집어서 확인할 수 있다. 이게 Card 마다 일단 눌렀을 때 OpenCard를 매번 실행하게 해서 그런데 실제 카드 뒤집기 게임은 한 번에 최대 2개의 카드까지만 오픈되어 있다.
public void OpenCard() {
Anim.SetBool("isOpen", true);
front.SetActive(true);
back.SetActive(false);
if(GameManager.Instance.firstCard == null) {
GameManager.Instance.firstCard = this;
}
else {
GameManager.Instance.secondCard = this;
GameManager.Instance.isMatched();
}
}
이 부분을 아래처럼 바꾸고, GameManager에서 null 초기화를 closeCard 이후 실행되도록 Invoke 문으로 바꿔주면 secondCard가 null일 때만 카드 오픈이 된다.
public void OpenCard() {
if (GameManager.Instance.secondCard == null) {
Anim.SetBool("isOpen", true);
front.SetActive(true);
back.SetActive(false);
if(GameManager.Instance.firstCard == null) {
GameManager.Instance.firstCard = this;
}
else {
GameManager.Instance.secondCard = this;
GameManager.Instance.isMatched();
}
}
}
public void isMatched() {
if(firstCard.idx == secondCard.idx) {
firstCard.DestroyCard();
secondCard.DestroyCard();
cardCount -= 2;
if (cardCount == 0) {
EndGame();
}
}
else {
firstCard.CloseCard();
secondCard.CloseCard();
}
CardReset();
}
void CardReset() {
Invoke("CardResetInvoke", 0.5f);
}
void CardResetInvoke() {
firstCard = null;
secondCard = null;
}
위처럼 수정하면 실행하면 두 개의 카드가 open 되고 Destroy 되거나 close 되기 전까지 다른 카드를 빠르게 열어서 확인할 수 없다.