티스토리 뷰
*Inventory에서 아이템을 버리는 로직을 구현했었다. 계속 테스트 해보니 문제가 몇가지 있었다.
먼저 기존 로직을 구현한 코드이다
//Vector3 playerPosition = playerTrans.position;
//float radius = 2.5f;
//Vector3 randomPosition;
//// 겹치는 아이템 체크 (Player, Item(Equip,Food,Coin,Ether,Weapon,Relic,Default)
//do
//{
// randomPosition = playerPosition + Random.insideUnitSphere * radius;
// randomPosition += new Vector3(Random.Range(1.5f, 2.5f), Random.Range(1.5f, 2.5f), 0f); //간격 추가
// // (item, player)와 겹치면 다시 반복
// Collider2D[] colliders = Physics2D.OverlapCircleAll(randomPosition, 2f, LayerMask.GetMask("Items", "Player"));
// if (colliders.Length > 0) //1개 개 이상 곂치는
// {
// continue;
// }
// break;
//} while (true);
//Test2 (360도 원의 범위 지정)
//Vector3 playerPosition = playerTrans.position;
//float radius = 2f;
//float itemSpacing = 1.5f; // 아이템 간격
//Vector3 randomPosition;
//// 겹치는 아이템 체크 (Player, Item(Equip,Food,Coin,Ether,Weapon,Relic,Default)
//do
//{
// float randomAngle = Random.Range(0f, 360f); // 0부터 360도까지의 각도 선택
// float randomRadius = Random.Range(0f, radius); // 반지름의 길이 선택
// Vector3 randomOffset = Quaternion.Euler(0f, 0f, randomAngle) * Vector3.right * randomRadius;
// // 아이템 간격을 고려하여 위치를 조정
// randomOffset += new Vector3(Random.Range(-itemSpacing, itemSpacing), Random.Range(-itemSpacing, itemSpacing), 0f);
// randomPosition = playerPosition + randomOffset;
// // (item, player)와 겹치면 다시 반복
// Collider2D[] colliders = Physics2D.OverlapCircleAll(randomPosition, 2f, LayerMask.GetMask("Items", "Player"));
// if (colliders.Length > 0) // 1개 이상 겹치는 경우
// {
// continue;
// }
// break;
//} while (true);
첫번째 문제는 아이템, 플레이어와 충돌하지는 않으나 아이템들끼리의 거리가 너무 가까워 유저가 아이템을 획득하는 데에 어려움이 있었다.
두번째 문제는 랜덤한 위치라 보여졌으나 원 안에 랜덤한 위치가 아닌 반지름을 기준으로 반원 안에서 랜덤한 위치로 생성되고 있었다.
이 두개의 문제를 해결하기위해 어떻게 로직을 수정할지 고민이 됐다.
1.생성되는 WayPoint를 모두 잡아준 후 배열에 요소를 랜덤하게 선택하여 해당 위치에 생성
2.기존 방식대로 랜덤한 범위 안에서 생성
1번 방법을 생각해보니 던전의 상자에서 아이템이 생성되는 것과 다른 방식이었다.
던전에서 생성되는 아이템은 최대 갯수가 12개로 정해져있으나 유저의 인벤토리에서 나오는 아이템의 갯수는
얼마나 늘어날지 모른다.
2번 방법에서 로직을 수정해야했다. 기존 방식에서 어떤부분을 수정할지 생각해봤다.
*아이템은 생성될 떄 최소 1f의 간격을 가지고 생성된다
float minDistance = 1f; 의 최소 거리를 변수로 주고
최소 거리 안에서 랜덤한 값을 기준으로 생성되게 변경했다
=> randomOffset += new Vector2(Random.Range(-minDistance, minDistance), Random.Range(-minDistance, minDistance));
*아이템은 0~360도 의 방향에서 생성된다
float randomAngle = Random.Range(0f, 360f); //0부터 360도까지의 각도 선택
float randomRadius = Random.Range(0f, radius); //반지름의 길이 선택
Vector2 randomOffset = Quaternion.Euler(0f, 0f, randomAngle) * Vector2.right * randomRadius;
=> 기존 반지름만 사용하여 랜덤한 위치를 지정했다면 이번엔 랜덤한 각도를 주고 범위를 설정하는 쪽으로 변경해봤다.
*수정된 전체 코드
private void MakeItemForInventory(string discaredItemName)
{
Debug.Log("인벤토리가 아이템 만들래"); //Inventory
Debug.LogFormat("버린 이름 : {0}", discaredItemName);
var playerTrans = GameObject.FindWithTag("Player").transform;
// 아이템 이름에 맞는 아이템을 생성한다 (아이템 이름은 Wood_Sword)
var dropGo = Instantiate(this.dropItem, playerTrans.parent);
dropGo.tag = "Equipment";
//Test3 (리스트에 위치를 담고 체크, 아이템 간격 짧음 문제)
Vector2 playerPosition = playerTrans.position;
float radius = 2f;
float minDistance = 1f; //아이템 간의 최소 거리 설정
Vector2 randomPosition;
do
{
float randomAngle = Random.Range(0f, 360f); //0부터 360도까지의 각도 선택
float randomRadius = Random.Range(0f, radius); //반지름의 길이 선택
Vector2 randomOffset = Quaternion.Euler(0f, 0f, randomAngle) * Vector2.right * randomRadius;
//아이템 간격을 고려하여 위치를 조정
randomOffset += new Vector2(Random.Range(-minDistance, minDistance), Random.Range(-minDistance, minDistance));
randomPosition = playerPosition + randomOffset+new Vector2(1.5f,1.5f);
//다른 아이템들과의 거리를 체크하여 최소 거리를 유지할 수 있는지 확인
bool isOverlap = false;
Collider2D[] itemColliders = Physics2D.OverlapCircleAll(randomPosition, 2f, LayerMask.GetMask("item", "Player"));
for (int i = 0; i < itemColliders.Length; i++)
{
if (itemColliders[i].gameObject != dropGo)
{
float distance = Vector2.Distance(randomPosition, itemColliders[i].transform.position);
if (distance < minDistance)
{
Debug.LogFormat("{0}/{1}", distance, minDistance);
isOverlap = true;
break;
}
}
}
if (isOverlap)
{
continue;
}
break;
} while (true);
dropGo.transform.position = randomPosition;
var resultSpriteAtlas = AtlasManager.instance.GetAtlasByName("UIEquipmentIcon");
var resultSp = resultSpriteAtlas.GetSprite(discaredItemName);
dropGo.GetComponent<SpriteRenderer>().sprite = resultSp;
dropGo.transform.localScale = new Vector3(3f, 3f, 3f);
dropGo.name = resultSp.name.Replace("(Clone)", "");
}
* 수정 후 테스트를 해보니 또 한가지 문제가 생겼다.
아이템들 끼리 간격체크를 하다 보니 1f 의 거리를 벌렸고 그 후 플레이어와 충돌 하여 버리자마자 다시 인벤토리에 들어가게되는 오류였다. 반지름을 늘리면 좁은 마을 맵에서 아이템이 너무 넓게 분포되는 문제가 있었다
그래서 플레이어와의 거리를 1f ->1.5f 로 수정하고 다시 테스트 해봤다.
randomPosition = playerPosition + randomOffset+new Vector2(1.5f,1.5f);
만족스러운 결과다. 연출이 추가되어야 할 것 같다. Dotween 을 사용하여 인벤토리로 부터 or 유저로 부터
아이템이 포물선을 그리며 DoMove로 구현해볼지 고민이다.
유저가 인벤토리 창을 열고 버리기 버튼을 누를때는 게임 화면이 보이지 않음으로 꼭 구현해야할지 고민도 된다.
'게임클라이언트 프로그래밍 > Guns N Rachel's' 카테고리의 다른 글
UIDice 데이터 연동, 버그수정 (0) | 2023.05.23 |
---|---|
Chest 에서 DropItem 생성 로직 변경, 버그 수정 (0) | 2023.05.22 |
UIShop Cell 생성 로직 변경, 일정 확률로 소모아이템 획득 추가, 히든룸 재화+아이템 획득 버그 수정 (0) | 2023.05.19 |
Chest drop Item 버그 수정 (0) | 2023.05.18 |
히든룸 HiddenChest - Gold,Ether 수급 버그 수정 (0) | 2023.05.17 |