게임엔진/개인 플젝

[Outdated] 농장 시뮬레이터 개인작

ShovelingLife 2024. 4. 30. 13:04

요즘 핫하다는 농장게임 보면서 깃허브에 짱박아둔 플젝 하나가 생각났다

 

UI 및 게임 애니메이션을 구현하기 위해선 DoTween을 많이 사용한다

아래는 DoLocalMoveX 함수로 간단하게 구현

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;

public class UI_manager : MonoBehaviour
{
    public static UI_manager instance;
    public GameObject menu_obj;
    //public Text money_text;
    bool m_is_opened = false;

    int m_current_money = 1000;

    public int current_money_prop
    {
        get
        {
            return m_current_money;
        }

        set
        {
            m_current_money = value;
        }
    }

    private void Awake()
    {
        if (instance == null) instance = this;
        else Destroy(this);
    }

    private void Update()
    {
        //money_text.text = current_money_prop.ToString();
    }

    // 메뉴 버튼
    public void Menu_button()
    {
        if (!m_is_opened) Open_menu();
        else Close_menu();
    }

    // 메뉴 열음
    void Open_menu()
    {
        m_is_opened = true;
        menu_obj.transform.DOLocalMoveX(-200f, 1f);
    }

    // 메뉴 닫음
    void Close_menu()
    {
        m_is_opened = false;
        menu_obj.transform.DOLocalMoveX(0f, 1f);
    }
}

 

다음으로 볼건 상점 스크롤링

 

구매 버튼 누르면 해당되는 식물의 아이콘이 커서를 따라가게 된다

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shop_manager : MonoBehaviour
{
    int m_current_index = 0;
    int m_old_index = 1;

    void Start()
    {

    }

    void Update()
    {

    }

    // 구매 버튼 클릭 시
    public void Purchase_item(string _name)
    {
        switch (_name)
        {
            case "first_plant": 
                m_current_index = 0;
                break;

            case "second_plant":
                m_current_index = 1;
                break;

            case "third_plant":
                m_current_index=2;
                break;

            case "fourth_plant":
                m_current_index=3;
                break;

            case "fifth_plant": 
                m_current_index=4; 
                break;

            case "sixth_plant": 
                m_current_index=5; 
                break;

            case "seventh_plant":
                m_current_index=6;
                break;

            case "eighth_plant":
                m_current_index=7;
                break;

            case "nineth_plant":
                m_current_index=8;
                break;

            case "tenth_plant":
                m_current_index=9;
                break;

            case "eleventh_plant":
                m_current_index=10;
                break;

            case "twelveth_plant":
                m_current_index=11;
                break;
        }
        Object_pooling.instance.Select_seed_bag(m_current_index, m_old_index);
        m_old_index = m_current_index;
        Audio_manager.instance.Play_touch_sound();
        UI_manager.instance.current_money_prop -= 100;
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Object_pooling : MonoBehaviour
{
    // 싱글톤
    public static Object_pooling instance;
    // 가방 관련
    public GameObject[] seed_bag_obj_arr = new GameObject[12];
    public Transform seed_bag_list_transform;
    // 식물 관련
    public GameObject plant_prefab;
    public List<GameObject> plant_obj_list = new List<GameObject>();
    public Transform plants_list_trans;
    int m_max_plants = 18;

    private void Awake()
    {
        if (instance == null) instance = this;
        else Destroy(this);
    }

    void Start()
    {
        Init_seed_bag_arr();
        Init_plants();
    }

    // 씨앗 가방 초기화
    void Init_seed_bag_arr()
    {
        for (int i = 0; i < seed_bag_obj_arr.Length; i++)
        {
            Instantiate(seed_bag_obj_arr[i], seed_bag_list_transform, true);
            seed_bag_obj_arr[i].SetActive(false);
        }
    }

    // 씨앗 가방을 선택함
    public void Select_seed_bag(int _current_bag, int _old_bag)
    {
        seed_bag_list_transform.GetChild(_current_bag).gameObject.SetActive(true);
        seed_bag_list_transform.GetChild(_old_bag).gameObject.SetActive(false);
    }

    // 식물 초기화
    void Init_plants()
    {
        for (int i = 0; i < m_max_plants; i++)
        {
            GameObject tmp_obj = Instantiate(plant_prefab, plants_list_trans, true);
            tmp_obj.SetActive(false);
            plant_obj_list.Add(tmp_obj);
        }
    }

    // 식물 오브젝트 꺼둠
    void Set_active_false_plant_list()
    {
        foreach (var item in plant_obj_list)
        {
            if (item.activeInHierarchy) item.SetActive(false);
        }
    }

    // 식물 오브젝트 가져옴
    public GameObject Get_plant_object()
    {   
        foreach (var item in plant_obj_list)
        {
            if (!item.activeInHierarchy) return item;
        }
        return null;
    }
}

 

작물마다 걸리는 자라는 시간이 다르다 

 

구매하기 버튼을 클릭하면 오브젝트 하나가 커서를 따라갈텐데 여기서 스크립트 컴포넌트가 있을텐데 뷰포트를 그리드 트랜스폼으로 변환하는게 핵심이다

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;

public class Seed_bag_data
{
    public Sprite[] seed_bag_icon_arr;

    Seed_bag_data() { }

    public Seed_bag_data(int _size)
    {
        seed_bag_icon_arr = new Sprite[_size];

        
    }
}

public class Seed_bag : MonoBehaviour
{
    List<Sprite> m_sprite_list = new List<Sprite>();
    Seed_bag_data m_seed_bag_data;
    Vector3 m_mouse_pos;
    public string current_name;
    float m_move_speed = 2f;

    void Start()
    {
        Init_seed_arr();
    }

    void Update()
    {
        Move_along_mouse();
        if (Input.GetMouseButtonDown(0)) Click_terrain();
    }

    // 땅을 클릭시
    void Click_terrain()
    {
        RaycastHit2D hit = Physics2D.Raycast(m_mouse_pos, Vector2.zero);

        if (hit.collider != null)
        {
            if (hit.collider.tag == "Terrain")
            {
                GridLayout gridLayout = hit.collider.transform.parent.GetComponentInParent<GridLayout>();
                Vector3Int cellPosition = gridLayout.WorldToCell(transform.position);
                Vector3 new_pos = cellPosition;
                GameObject tmp_obj;
                new_pos.x += 0.5f;
                new_pos.y += 1;

                // Instantiate
                tmp_obj = Object_pooling.instance.Get_plant_object();
                tmp_obj.transform.position = new_pos;
                tmp_obj.SetActive(true);
                // Set
                tmp_obj.GetComponent<Plant_manager>().Set_data(current_name);
            }
        }
    }

    // 초기화
    void Init_seed_arr()
    {
        foreach (var item in All_plant_data.instance.all_plants_arr)
        {
            if (item.name.EndsWith("_7")) m_sprite_list.Add(item);
        }
        m_seed_bag_data = new Seed_bag_data(m_sprite_list.Count);

        // 재설정
        for (int i = 0; i < m_sprite_list.Count; i++)
        {
            m_seed_bag_data.seed_bag_icon_arr[i] = m_sprite_list[i];
        }
        Array.Reverse(m_seed_bag_data.seed_bag_icon_arr);
        //foreach (var item in m_seed_bag_data.seed_bag_icon_arr)
        //{
        //    Debug.Log(item.name);
        //}        
    }

    // 마우스랑 같이 이동
    void Move_along_mouse()
    {
        m_mouse_pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        transform.position = Vector2.Lerp(transform.position, m_mouse_pos, m_move_speed);
    }
}

빈 땅에 클릭 할 시 작물이 자라는 로직은 코루틴으로 간단하게 구현할 수가 있다

using System;using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public struct s_plant_data
{
    public DateTime date_time;
    public TimeSpan time_span;
    public DateTime plant_time;
    public int current_stage;
}

public class Plant_manager : MonoBehaviour
{
    s_plant_data plant_data;
    Sprite[] m_plant_arr = new Sprite[8];
    SpriteRenderer m_current_sprite_rend;
    public string plant_name;

    private void OnEnable()
    {
       StartCoroutine(IE_Growth_plant());
    }

    // 식물 종류에 따라서 초기화
    public void Set_data(string _plant_name)
    {
        switch (_plant_name)
        {
            case "first_plant": plant_data.time_span = new TimeSpan(0, 0, 2); break; // 첫 농작물 2초
            case "second_plant": plant_data.time_span = new TimeSpan(0, 0, 5); break; // 두번째 농작물 5초
            case "third_plant": plant_data.time_span = new TimeSpan(0, 0, 7); break; // 세번째 농작물 7초
            case "fourth_plant": plant_data.time_span = new TimeSpan(0, 0, 10); break; // 네번째 농작물 10초
            case "fifth_plant": plant_data.time_span = new TimeSpan(0, 0, 13); break; // 다섯번째 농작물 13초
            case "sixth_plant": plant_data.time_span = new TimeSpan(0, 0, 16); break; // 여섯번째 농작물 16초
            case "seventh_plant": plant_data.time_span = new TimeSpan(0, 0, 19); break; // 일곱번째 농작물 19초
            case "eighth_plant": plant_data.time_span = new TimeSpan(0, 0, 22); break; // 여덟번째 농작물 22초
            case "nineth_plant": plant_data.time_span = new TimeSpan(0, 0, 26); break; // 아홉번째 농작물 26초
            case "tenth_plant": plant_data.time_span = new TimeSpan(0, 0, 30); break; // 열번째 농작물 30초
            case "eleventh_plant": plant_data.time_span = new TimeSpan(0, 0, 34); break; // 열한번째 농작물 34초
            case "twelveth_plant": plant_data.time_span = new TimeSpan(0, 0, 38); break; // 열두번째 농작물 38초
        }
        plant_data.date_time = DateTime.Now;
        plant_data.plant_time = plant_data.date_time + plant_data.time_span;
        plant_data.current_stage = 0;
        plant_name = _plant_name;
        Init_resources();
    }

    // 변수 초기화
    public void Init_resources()
    {
        int index = 0;

        foreach (var item in All_plant_data.instance.all_plants_arr)
        {
            if (item.name.StartsWith(plant_name))
            {
                m_plant_arr[index] = item;
                index++;
            }
        }
    }

    // 식물이 성장하는 코루틴
    IEnumerator IE_Growth_plant()
    {
        m_current_sprite_rend = GetComponent<SpriteRenderer>();

        while (true)
        {
            if (plant_data.current_stage > 7)
            {
                StopCoroutine(IE_Growth_plant());
                break;
            }
            m_current_sprite_rend.sprite = m_plant_arr[plant_data.current_stage];
            plant_data.date_time = DateTime.Now;

            if (plant_data.date_time > plant_data.plant_time)
            {
                plant_data.current_stage++;
                plant_data.plant_time = plant_data.date_time + plant_data.time_span;
            }
            yield return null;
        }
    }
}