혹시나 해서 영상도 기제함
코드
using System.Collections.Generic;
using UnityEngine;
public class table_script : MonoBehaviour
{
public Dictionary<int, int> collisionInfo = new Dictionary<int, int>();
public List<string> collidedObjectNames = new List<string>();
// 충돌 시 호출되는 함수
private void OnTriggerEnter2D(Collider2D other)
{
sample_script sampleScript = other.GetComponent<sample_script>();
if (sampleScript != null)
{
int number = sampleScript.number;
// 이미 충돌 정보가 존재하지 않으면 추가
if (!collisionInfo.ContainsKey(number))
{
collisionInfo.Add(number, 1);
Debug.Log($"충돌 정보 저장: number={number}, quantity=1");
}
else
{
// 충돌 정보가 있으면 수량 증가
collisionInfo[number]++;
Debug.Log($"충돌 정보 갱신: number={number}, quantity={collisionInfo[number]}");
}
}
if (other.gameObject.CompareTag("cards"))
{
collidedObjectNames.Add(other.gameObject.name);
Debug.Log($"충돌 객체 이름 저장: {other.gameObject.name}");
}
}
// 충돌 종료 시 호출되는 함수
private void OnTriggerExit2D(Collider2D other)
{
sample_script sampleScript = other.GetComponent<sample_script>();
if (sampleScript != null)
{
int number = sampleScript.number;
if (collisionInfo.ContainsKey(number))
{
collisionInfo[number]--;
// 수량이 0이 되면 제거
if (collisionInfo[number] == 0)
{
collisionInfo.Remove(number);
Debug.Log($"충돌 정보 제거: number={number}");
}
else
{
Debug.Log($"충돌 정보 갱신 (감소): number={number}, quantity={collisionInfo[number]}");
}
}
}
if (other.gameObject.CompareTag("cards"))
{
collidedObjectNames.Remove(other.gameObject.name);
Debug.Log($"충돌 객체 이름 삭제: {other.gameObject.name}");
}
}
// 조합 시도하는 함수
public void Combination()
{
Debug.Log("조합 시작");
Object[] prefabs = Resources.LoadAll("Cards/Objects", typeof(GameObject));
foreach (Object prefab in prefabs)
{
Debug.Log($"조합 시도: {prefab.name}");
if (prefab is GameObject cardPrefab)
{
object_script needsScript = cardPrefab.GetComponent<object_script>();
if (needsScript != null && needsScript.Needs_number != null && needsScript.Needs_quality != null)
{
for (int i = 0; i < needsScript.Needs_number.Count; i++)
{
int number = needsScript.Needs_number[i];
// 충돌 정보가 있는지 확인
if (collisionInfo.ContainsKey(number))
{
if (i < needsScript.Needs_quality.Count && collisionInfo[number] >= needsScript.Needs_quality[i])
{
Debug.Log($"성공: {cardPrefab.name}");
// 조합 성공 시 카드 생성
GameObject newCard = Instantiate(cardPrefab, transform.position + new Vector3(10, 0, 0), Quaternion.identity);
newCard.transform.SetParent(transform.parent);
// 조합에 사용된 카드 제거
RemoveCollidedCards(needsScript);
return;
}
}
else
{
Debug.Log($"{cardPrefab.name} prefab에 충돌 정보가 없습니다.");
}
}
}
else
{
Debug.LogWarning($"{cardPrefab.name} prefab에 object_script 컴포넌트가 없거나 Needs_number/Needs_quality 리스트가 설정되지 않았습니다.");
}
}
}
Debug.Log("조합 실패");
}
// 충돌한 카드를 제거하는 함수 (collidedObjectNames 사용, Needs와 Quality 참조)
private void RemoveCollidedCards(object_script needsScript)
{
if (needsScript == null || needsScript.Needs_number == null || needsScript.Needs_quality == null)
{
Debug.LogError("needsScript가 제대로 설정되지 않았습니다.");
return;
}
List<string> cardsToRemove = new List<string>();
for (int i = 0; i < needsScript.Needs_number.Count; i++)
{
int number = needsScript.Needs_number[i];
int quality = needsScript.Needs_quality[i];
int count = 0;
List<string> foundCards = new List<string>(); // number와 일치하는 카드 이름 저장
// collidedObjectNames에서 number와 일치하는 카드 찾기
foreach (string cardName in collidedObjectNames)
{
GameObject card = GameObject.Find(cardName);
if (card != null)
{
sample_script cardScript = card.GetComponent<sample_script>();
if (cardScript != null && cardScript.number == number)
{
foundCards.Add(cardName);
count++;
if (count >= quality)
{
break;
}
}
}
if (count >= quality)
{
break;
}
}
// 찾은 카드들을 cardsToRemove에 추가
foreach (string cardName in foundCards)
{
cardsToRemove.Add(cardName);
}
}
// quality만큼 카드 삭제
for (int i = 0; i < cardsToRemove.Count; i++)
{
GameObject card = GameObject.Find(cardsToRemove[i]);
if (card != null)
{
Destroy(card);
collidedObjectNames.Remove(cardsToRemove[i]);
sample_script cardScript = card.GetComponent<sample_script>();
if (cardScript != null)
{
int number = cardScript.number;
if (collisionInfo.ContainsKey(number))
{
collisionInfo[number]--;
if (collisionInfo[number] == 0)
{
collisionInfo.Remove(number);
}
}
Debug.Log($"충돌 정보 제거: number={number}");
}
}
else
{
Debug.LogWarning($"이름: {cardsToRemove[i]}에 해당하는 카드를 찾을 수 없습니다.");
collidedObjectNames.Remove(cardsToRemove[i]);
}
}
}
}
폰으로 슬쩍봐서 정확한지는 모르겠는데 지금 삭제할 오브젝트를 전부 찾고 그 뒤에 삭제하잖아 String으로 오브젝트 찾는 과정에서 계속 같은 오브젝트를 찾는거아님? 이미 찾은 오브젝트면 다시 찾도록 해야할거같은디 저거땜에 무조건 종류별로 1개씩만 지워지는거같고 간단하게 본거여서 틀릴수도있는데 일단 확인해봐
Find로 찾다보니 잘못찾는거같은데 GameObject로 찾아보셈
List cardsToRemove = new List(); << 이 리스트를 지역변수 말고 멤버변수로 인스펙터에서 확인하면서 해보셈
Destroy는 특성상 프레임의 맨 마지막에 오브젝트를 날려버림 저 for문이 도는 동안엔 계속 card 가 남아있는 상태고 보니까 카드 종류별로 이름은 전부 같은 상태라 GameObject card = GameObject.Find(cardsToRemove[i]); 이거 할 때 하이라키에서 맨 위에 있는 카드만 찾아지고 여기에만 Destroy 를 예약해두니까 결국 카드는 종류별로 하나씩만 사라지는거
앗 근데 애초에 영역에 충돌했던 카드들도 이름으로 기록해놔서 찾을 때 문제 발생할 것 같은데 한두줄 바꾸는걸론 안될 것 같은데 잠시만... 생각 좀 해봄...
t2 카드 2장 + 0 카드 1장 이거 조합했을 생성되야하는 카드가 안나오는거같은데 이건 버그 아니야?