Unity에서 3-Match 퍼즐의 병합 로직 이해하기
안녕하세요! 이번에는 Unity에서 3-Match 퍼즐 게임의 병합 로직을 어떻게 구현하는지 공유하려고 합니다. 아직 완벽하게 작동하지 않는 부분이 있어서, 이 부분에 대한 피드백이나 제안도 환영합니다!
MergeManager 클래스 소개
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MergeManager : MonoBehaviour
{
[SerializeField] private GridManager gridManager;
[SerializeField] private float mergeDelay = 0.5f;
public bool CheckForMatches(GameObject character)
{
int horizontalMatches = CountMatches(character, Vector2.right)
+ CountMatches(character, Vector2.left) + 1;
int verticalMatches = CountMatches(character, Vector2.up)
+ CountMatches(character, Vector2.down) + 1;
if (horizontalMatches >= 3 || verticalMatches >= 3)
{
Debug.Log("Merging detected");
if (horizontalMatches >= 3)
{
Debug.Log("Merging horizontally");
StartCoroutine(MergeCharacters(character, Vector2.right,
horizontalMatches - 1));
StartCoroutine(MergeCharacters(character, Vector2.left,
horizontalMatches - 1));
}
if (verticalMatches >= 3)
{
Debug.Log("Merging vertically");
StartCoroutine(MergeCharacters(character, Vector2.up,
verticalMatches - 1));
StartCoroutine(MergeCharacters(character, Vector2.down,
verticalMatches - 1));
}
return true;
}
return false;
}
private int CountMatches(GameObject character, Vector2 direction)
{
int matchCount = 0;
Vector2 currentPosition = character.transform.position;
string characterPrefabName = character.transform.parent.name.Replace
("(Clone)", "").Trim();
while (true)
{
currentPosition += direction;
GameObject otherCharacter =
gridManager.GetCharacterAtPosition(currentPosition);
if (otherCharacter != null)
{
string otherCharacterPrefabName =
otherCharacter.transform.name.Replace("(Clone)", "").Trim();
if (otherCharacterPrefabName == characterPrefabName
&& ShouldConsiderForMatching(otherCharacter))
{
matchCount++;
}
else
{
break;
}
}
else
{
break;
}
}
return matchCount;
}
private bool ShouldConsiderForMatching(GameObject character)
{
return true;
}
private IEnumerator MergeCharacters(GameObject character, Vector2 direction,
int count)
{
Vector2 currentPosition = character.transform.position;
string characterPrefabName = character.transform.parent.name.Replace
("(Clone)", "").Trim();
for (int i = 0; i < count; i++)
{
currentPosition += direction;
GameObject otherCharacter =
gridManager.GetCharacterAtPosition(currentPosition);
if (otherCharacter != null)
{
string otherCharacterPrefabName =
otherCharacter.transform.name.Replace("(Clone)", "").Trim();
if (otherCharacterPrefabName == characterPrefabName
&& ShouldConsiderForMatching(otherCharacter))
{
gridManager.RemoveCharacterAtPosition(currentPosition);
Destroy(otherCharacter);
}
}
}
yield return new WaitForSeconds(mergeDelay);
}
}
변수 설명
-
gridManager
: 그리드를 관리하는 매니저입니다. -
mergeDelay
: 병합 후의 딜레이 시간입니다.
병합 가능 여부 확인하기
public bool CheckForMatches(GameObject character)
{
int horizontalMatches = CountMatches(character, Vector2.right)
+ CountMatches(character, Vector2.left) + 1;
int verticalMatches = CountMatches(character, Vector2.up)
+ CountMatches(character, Vector2.down) + 1;
if (horizontalMatches >= 3 || verticalMatches >= 3)
{
Debug.Log("Merging detected");
if (horizontalMatches >= 3)
{
Debug.Log("Merging horizontally");
StartCoroutine(MergeCharacters(character, Vector2.right,
horizontalMatches - 1));
StartCoroutine(MergeCharacters(character, Vector2.left,
horizontalMatches - 1));
}
if (verticalMatches >= 3)
{
Debug.Log("Merging vertically");
StartCoroutine(MergeCharacters(character, Vector2.up,
verticalMatches - 1));
StartCoroutine(MergeCharacters(character, Vector2.down,
verticalMatches - 1));
}
return true;
}
return false;
}
이 함수는 주어진 캐릭터를 중심으로 연속된 캐릭터들을 찾아 병합 여부를 확인합니다.
연속된 캐릭터 수 세기
private int CountMatches(GameObject character, Vector2 direction)
{
int matchCount = 0;
Vector2 currentPosition = character.transform.position;
string characterPrefabName = character.transform.parent.name.Replace
("(Clone)", "").Trim();
while (true)
{
currentPosition += direction;
GameObject otherCharacter =
gridManager.GetCharacterAtPosition(currentPosition);
if (otherCharacter != null)
{
string otherCharacterPrefabName =
otherCharacter.transform.name.Replace("(Clone)", "").Trim();
if (otherCharacterPrefabName == characterPrefabName
&& ShouldConsiderForMatching(otherCharacter))
{
matchCount++;
}
else
{
break;
}
}
else
{
break;
}
}
return matchCount;
}
이 함수는 주어진 방향으로 연속된 캐릭터의 수를 반환합니다.
캐릭터 병합하기
이 함수는 연속된 캐릭터들을 병합합니다.
private IEnumerator MergeCharacters(GameObject character, Vector2 direction,
int count)
{
Vector2 currentPosition = character.transform.position;
string characterPrefabName = character.transform.parent.name.Replace
("(Clone)", "").Trim();
for (int i = 0; i < count; i++)
{
currentPosition += direction;
GameObject otherCharacter =
gridManager.GetCharacterAtPosition(currentPosition);
if (otherCharacter != null)
{
string otherCharacterPrefabName =
otherCharacter.transform.name.Replace("(Clone)", "").Trim();
if (otherCharacterPrefabName == characterPrefabName
&& ShouldConsiderForMatching(otherCharacter))
{
gridManager.RemoveCharacterAtPosition(currentPosition);
Destroy(otherCharacter);
}
}
}
yield return new WaitForSeconds(mergeDelay);
}
아직 버그가 많은 초기 코드입니다,
참고하시기에는 무리가 있으며, 계속 업데이트 될 예정입니다.