List를 사용 할 때 마다 이런 기능이 있었으면 좋겠다고 생각한 적이 있다. 바로 리스트에 아이템이 추가되거나 제거 되었을 때 이벤트를 실행 시킬 수 있으면 여러 용도로 사용할 수 있겠다는 생각을 했다. 그래서 C#의 List<T>를 상속받는 자신만의 CustomList를 만들어 보았다.
CustomList.cs
먼저 CustomList.cs 를 생성해서 C#의 List<T>를 상속받는다.
using System.Collections.Generic;
namespace CustomList
{
public interface ICustomListable
{
}
public class CustomList<T> : List<T> where T : ICustomListable
{
public delegate void CustomListEventHandler<T>(T listItem);
public event CustomListEventHandler<T> onAdded;
public event CustomListEventHandler<T> onRemoved;
public new void Add(T newItem)
{
base.Add(newItem);
onAdded?.Invoke(newItem);
}
public new void Remove(T tobeRemoved)
{
base.Remove(tobeRemoved);
onRemoved?.Invoke(tobeRemoved);
}
}
}
CustomList<T> 클래스는 List<T>를 상속받고 T는 인터페이스 ICustomListable를 구현하고 있어야한다.
그리고 CustomList<T>에 아이템을 추가할 때는 public new void Add(T newItem)을 통해서 추가되는데 여기서 포인트는 "new"를 사용하여 기존 C# List<T>가 아닌 CustomList<T>의 Add 메소드를 재정의 해준다. 추가되었을 땐 onAdded 이벤트가 호출된다. Remove도 같은 원리이다.
CustomListManager.cs
다음은 Monobehavior를 상속받는 CustomListManager를 만들어 component로 쓰이는 방법을 보겠다.
using UnityEngine;
namespace CustomList
{
public class Fruit : ICustomListable
{
private string _name;
public string name => _name;
public Fruit(string fruitName)
{
_name = fruitName;
}
}
public class CustomListManager : MonoBehaviour
{
private CustomList<Fruit> fruits = new CustomList<Fruit>();
private void OnEnable()
{
fruits.onAdded += OnFruitAdded;
fruits.onRemoved += OnFruitRemoved;
}
private void OnFruitAdded(Fruit fruit)
{
print(fruit.name + " added to the list!");
}
private void OnFruitRemoved(Fruit fruit)
{
print(fruit.name + " removed from the list!");
}
private void Start()
{
Fruit apple = new Fruit("Apple");
fruits.Add(apple);
Fruit pineapple = new Fruit("Pineapple");
fruits.Add(pineapple);
Fruit orange = new Fruit("Orange");
fruits.Add(orange);
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (fruits.Count == 0)
{
print("No Fruit to be removed!");
return;
}
RemoveTheLastFruit();
}
}
private void RemoveTheLastFruit()
{
int lastIndex = fruits.Count - 1;
Fruit lastFruit = fruits[lastIndex];
fruits.Remove(lastFruit);
}
}
}
예시로 Fruit이라는 클래스를 만들어 CustomList<Fruit> fruits 라는 제작리스트에 추가해보았다. fruits의 onAdded 이벤트에 private void OnFruitAdded를 등록했기 때문에 (fruits.onAdded += OnFruitAdded) 추가될때마다 OnFruitAdded 함수에서 리스트에 아이템이 추가되었을 때 다양한 활용을 해볼수있다. 여기 예시에서는 그냥 fruit의 name을 print 되게 해보았다.
Update() 에서는 마우스 클릭을 했을 시 마지막 index의 fruit이 리스트에서 remove 되게 해주었고, onAdded 이벤트와 동일하게 onRemoved 이벤트가 발동되어서 remove 된 fruit의 name이 print 되게 구현하였다.
나는 CustomList에서 추가,제거 이벤트만 구현했는데 이것 외에도 더 다양한 방법으로 확장 할 수 있으거라 생각한다.
'Unity & C#' 카테고리의 다른 글
C# event에서 listener들을 unsubscribe하는 법 (0) | 2021.10.19 |
---|---|
C# Extension Method 활용하여 MonoBehaviour에서 자주 사용하는 Delay 만들기 (0) | 2021.10.19 |
SourceTree에서 Git LFS 적용하기 (0) | 2021.09.30 |
DOTween (HOTween v2)를 활용한 애니메이션 연출 (0) | 2021.09.16 |
URP에서 VR + PC 두 화면 따로 출력하기 (1) | 2021.09.15 |