개발툴/Unity

UniRx 실습 - 간단한 식물 재배 로직 만들어보기

가든_ 2024. 8. 16. 00:12


작물 성장

Observable.Interval(TimeSpan.FromSeconds(timeBetweenStages))
    .Take(growthStages.Length - 1)
    .Subscribe(_ =>
    {
        Debug.Log("농작물이 성장 함");
        currentStage++;
        spriteRenderer.sprite = growthStages[currentStage];

        if (currentStage == growthStages.Length - 1)
        {
            isHarvestable = true;
        }
    })
    .AddTo(this);

 

  • 지정된 시간 간격(timeBetweenStages)마다 농작물이 성장합니다
  • 성장 단계(growthStages.Length - 1)에 도달하면, 농작물의 외형이 변화합니다
  • 농작물이 마지막 성장 단계에 도달하면 수확 가능 상태(isHarvestable)가 됩니다
  • 게임 오브젝트가 파괴될 경우 자동으로 해제

Observable.Interval(TimeSpan.FromSeconds(timeBetweenStages))

 

  • 일정한 시간 간격마다 이벤트를 발생시키는 Observable을 생성합니다
  • TimeSpan.FromSeconds(timeBetweenStages): timeBetweenStages 초마다 이벤트를 발생시키도록 설정합니다
  • ex) timeBetweenStages가 2초라면, 이 Observable은 2초마다 숫자를 증가시키며 이벤트를 발생시킵니다

.Take(growthStages.Length - 1)

  • Observable이 리턴하는 이벤트의 횟수를 제한합니다
  • growthStages.Length - 1 이벤트가 리턴되는 횟수를 농작물의 성장 단계 수 (growthStages.Length)로 제한합니다. 이는 최종 단계에 도달했을때까지만 성장 로직을 실행하도록 하는 역할을 합니다

.Subscribe(_ => { ... })

  • Observable이 이벤트를 리턴할 때마다 지정된 동작을 수행합니다.
Subscribe 블록 내부 동작:
currentStage++; : 현재 농작물의 성장 단계를 증가시킵니다.
spriteRenderer.sprite = growthStages[currentStage]; : currentStage에 해당하는 스프라이트로 농작물의 외형을 변경합니다.
if (currentStage == growthStages.Length - 1) { isHarvestable = true; } : 농작물이 마지막 성장 단계에 도달했을 때, isHarvestable을 true로 설정하여 수확할 수 있음을 표시합니다.

작물 심기

    void Start()
    {
        this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(0))
            .Select(_ => Camera.main.ScreenToWorldPoint(Input.mousePosition))
            .Subscribe(position =>
            {
                PlantCrop(position);
            })
            .AddTo(this);
    }

 

  • 매 프레임마다 마우스 클릭을 감지합니다
  • 마우스 왼쪽 버튼이 눌리면 클릭한 화면 좌표를 월드 좌표로 변환합니다
  • 변환된 좌표를 이용해 PlantCrop 메서드를 호출하여 그 위치에 작물을 심습니다
    • PlantCrop 메서드 : Crop 프리팹을 넘겨받은 위치에 생성합니다

 


this.UpdateAsObservable()

  • Update 메서드처럼 매 프레임마다 실행되는 Observable을 생성합니다

.Where(_ => Input.GetMouseButtonDown(0))

  • 특정 조건이 충족될 때만 이벤트를 처리하도록 필터링합니다
  • Input.GetMouseButtonDown(0) 마우스 왼쪽 버튼이 눌렸을 때만 이벤트를 처리합니다. 이 조건이 true일 때만 다음 단계로 진행합니다

.Select(_ => Camera.main.ScreenToWorldPoint(Input.mousePosition))

  • 이벤트가 발생할 때마다 데이터를 변환합니다
  • Camera.main.ScreenToWorldPoint(Input.mousePosition): 마우스 클릭 위치를 화면 좌표에서 월드 좌표로 변환합니다
화면 좌표: 유니티 화면 상의 2D 좌표
월드 좌표: 3D 공간에서의 좌표, 게임 오브젝트가 존재하는 실제 공간상의 위치
  • 변환된 월드 좌표를 작물을 심을 위치로 사용

.Subscribe(position => { PlantCrop(position); })

  • Observable에서 리턴된 데이터를 구독하여 특정 동작을 수행합니다
  • position: 변환된 월드 좌표를 Subscribe의 파라미터로 전달
  • PlantCrop(position): 전달된 위치(position)에 작물을 심는 메서드 호출

작물 수확하기

    void Start()
    {
        this.UpdateAsObservable()
            .Where(_ => Input.GetMouseButtonDown(1))
            .Select(_ => GetMouseWorldPosition())
            .Subscribe(TryHarvestCrop)
            .AddTo(this);
    }

 

 

  • 매 프레임마다 마우스 우클릭을 감지합니다.
  • 마우스 우클릭 시 클릭 위치를 화면 좌표에서 월드 좌표로 변환합니다.
  • 해당 위치에 작물 수확을 시도합니다.