두 충돌체가 있을때 두 충돌체 모두가 아니라 하나에서만 충돌시 발생하는 로직을 구현하는 방법에 대해서
GetInstanceID() 함수를 통해서 ID 값을 구해온뒤에, 해당 ID 값을 두개의 오브젝트에서 서로 비교를 한뒤에 큰 경우에만 충돌시 동작할 로직을 구현하는 형태의 코드를 접했기 때문에 이 방법에 대한 설명과 함께 앞으로 이런 형태의 로직을 사용하기에 적당한 상황에 대해서 기록해둔다.
코드를 예로들어 보자면,
if(info.FruitIndex == _info.FruitIndex)
{
int thisID = gameObject.GetInstanceID();
int otherID = collision.gameObject.GetInstanceID();
if(thisID > otherID)
{
if (info.FruitIndex >= 3)
{
SoundManager.instance.PlaySound("GrowPlant");
}
else
{
SoundManager.instance.PlaySound("SlimeSeedByyok");
}
GameManager.instance.IncreaseScore(_info.PointsWhenAnnihilated);
if(_info.FruitIndex == FruitSelector.instance.Fruits.Length-1)
{
Destroy(collision.gameObject);
Destroy(gameObject);
}
else
{
Vector3 middlePosition = (transform.position + collision.transform.position) / 2f;
GameObject go = Instantiate(SpawnCombinedFruit(_info.FruitIndex), GameManager.instance.transform);
go.transform.position = middlePosition;
ColliderInformer informer = go.GetComponent<ColliderInformer>();
if(informer != null)
{
informer.WasCombinedIn=true;
}
Destroy(collision.gameObject);
Destroy(gameObject);
}
}
}
이러한 상황에 해당하는데, 두 충돌체 모두에서 GetInstanceID() 를 통해서 ID 값을 받아온뒤,
if(thisID > otherID) { } 로 감싼 부분에서 충돌 발생시 원하는 로직을 작성해둔 형태를 볼 수 있는데, 이렇게 한 것은 결국에 두 충돌체 모두에서 해당 로직이 실행되는 것이 아닌, 하나의 충돌체에서만 해당 로직이 실행해서 중복실행 되는 형태를 방지하기 위한 방법이다. 결국 핵심은 thisID > otherID 형태로 하던, thisID < otherID 형태로 하던 상관없이, 순서를 결정할 사항을 두고, 해당 사항에서 가장 우선인 오브젝트에서 위와같은 로직을 실행시키고, 그 반대인 경우에는 해당 로직을 실행시키지않는 형태라는것이 핵심이다.
위와 같이 여러가지 오브젝트들이 한번에 영향을 받는 동작을 실행할때, 그중에서 중복을 허용하지 않은 상태로 하나가 대표적으로 내가 원하는 형태의 로직을 수행하도록 하기 위해서 유니티 오브젝트의 메서드인 GetInstanceID() 를 사용하는 방법을 사용하도록 하자. 물론 다른 방법도 가능하겠지만 이 방법을 사용하는것이 구현 측면에서나 효율 측면에서 괜찮은 방법이라고 생각된다.
추가적인 정보를 남기기 위해서
GetInstanceID() 함수에 대한 gpt 검색내용을 첨부한다.
gpt 답변내용
`GetInstanceID()` 메서드는 Unity 엔진의 모든 `Object` 클래스의 멤버 메서드로, 해당 객체의 고유한 인스턴스 식별자를 반환합니다. 이 메서드는 `Object` 클래스에서 파생된 모든 클래스에서 사용할 수 있으며, Unity에서 게임 오브젝트나 다른 유형의 오브젝트 간에 구분을 위해 고유 식별자를 생성하는 데 주로 사용됩니다.
`GetInstanceID()` 메서드는 다음과 같은 특징을 갖습니다:
- **고유성:** `GetInstanceID()`가 반환하는 값은 Unity 런타임 중에 오브젝트에 할당된 고유한 정수값입니다. 이 값은 오브젝트가 생성될 때마다 다르게 부여되며, 같은 오브젝트에 대해 같은 값을 유지합니다.
- **비교 용이성:** 두 오브젝트의 `GetInstanceID()` 값을 비교함으로써 두 오브젝트가 같은 것인지 여부를 확인할 수 있습니다. 레퍼런스 비교를 통해 확인하는 것보다 더 안전한 방법 중 하나입니다.
- **null 오브젝트에 대한 안전성:** `null` 또는 파괴된 오브젝트에 대해 `GetInstanceID()`를 호출하면 0이 반환됩니다. 이를 통해 `null` 오브젝트를 쉽게 식별할 수 있습니다.
- **빠른 비교 및 식별:** `GetInstanceID()`를 사용하면 정수 값을 비교하므로 빠르게 동작합니다.
위의 코드에서는 `GetInstanceID()`를 사용하여 두 오브젝트의 인스턴스 식별자를 비교합니다. 이를 통해 현재 오브젝트의 `thisID`와 충돌한 오브젝트의 `otherID`를 비교하여 어느 쪽이 더 큰지를 판단하고, 이에 따라 특정 로직을 수행하고 있습니다. 이는 두 오브젝트 간의 상대적인 식별을 위해 사용되고 있습니다.