유니티 기초

바구니 게임

송현호 2023. 8. 7. 18:11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasketController : MonoBehaviour
{
    private AudioSource audioSource;
    [SerializeField]
    private AudioClip appleSfx;
    [SerializeField]
    private AudioClip bombSfx;
    [SerializeField]
    private GameDirector gameDirector;

    private void Awake()
    {

        
    }

    public void Init()
    {
        GameObject gameDirectorGo = GameObject.Find("GameDirector");
        this.gameDirector = gameDirectorGo.GetComponent<GameDirector>();
        this.audioSource = this.GetComponent<AudioSource>();
        this.appleSfx = GetComponent<AudioClip>();
        this.bombSfx = GetComponent<AudioClip>();
    }

    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        //마우스 왼쪽 클릭 하면 (화면을 클릭하면)Ray를 만들자 
        if (Input.GetMouseButtonDown(0))
        {
            //화면상의 좌표 -> Ray 객체를 생성 
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float maxDistance = 100f;
            //ray를 눈으로 확인 
            Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.green, 2f);

            //ray와 collider의 충돌을 검사하는 메서드 
            //out매개변수를 사용하려면 변수정의를 먼저 해야 한다 
            RaycastHit hit;
            //out키워드를 사용해서 인자로 넣어라 
            //Raycast 메서드에서 연산된 결과를 hit 매개변에 넣어줌 
            //충돌 되었다면 ~ true , 아니면 false 
            if (Physics.Raycast(ray, out hit, maxDistance))
            {
                //The impact point in world space where the ray hit the collider.
                Debug.LogFormat("hit.point:{0}", hit.point);

                //this.gameObject.transform.position = hit.point;
                //바구니의 위치를 충돌한 지점으로 변경
                //this.transform.position = hit.point;
                //x좌표와 z좌표를 반올림 
                float x = Mathf.RoundToInt(hit.point.x);
                float z = Mathf.RoundToInt(hit.point.z);
                //새로운 좌표를 만들고 이동 
                this.transform.position = new Vector3(x, 0, z);
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        Debug.Log(other.tag);

        if (other.tag == "apple")
        {
            Debug.Log("득점");
            this.audioSource.PlayOneShot(this.appleSfx);
            this.gameDirector.IncreaseScore(100);
            this.gameDirector.UpdateScoreUI();
            Destroy(other.gameObject);  //사과또는 폭탄을 제거 
        }
        else if (other.tag == "bomb")
        {
            Debug.Log("감점");
            this.audioSource.PlayOneShot(this.bombSfx);
            this.gameDirector.DecreaseScore(50);
            this.gameDirector.UpdateScoreUI();
            Destroy(other.gameObject);  //사과또는 폭탄을 제거 
        }

        


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

public class ItemController : MonoBehaviour
{
    // Start is called before the first frame update
    private float moveSpeed = 1f;
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //리지드바디가 없는 오브젝트의 이동
        this.transform.Translate(Vector3.down * moveSpeed * Time.deltaTime);
        if(this.transform.position.y <= 0)
        {
            Destroy(this.gameObject);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemGenerator : MonoBehaviour
{
    private float elapsedTime;
    private float spawnTime = 1f;
    public GameObject applePrefab;
    public GameObject bombPrefab;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        this.elapsedTime += Time.deltaTime;

        if(this.elapsedTime >= spawnTime)
        {
            this.CreateItem();
            this.elapsedTime = 0f;
        }
    }

    private void CreateItem()
    {
        int rand = Random.Range(1, 11);
        GameObject itemGo = null;
        if (rand > 2)
        {
            itemGo = Instantiate(this.applePrefab);
        }
        else
        {
            itemGo = Instantiate(this.bombPrefab);
        }

        int x = Random.Range(-1, 2);
        int z = Random.Range(-1, 2);
        itemGo.transform.position = new Vector3(x, 3.5f, z);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameDirector : MonoBehaviour
{
    [SerializeField]
    private Text txtTime;
    [SerializeField]
    private Text txtScore;

    public float time = 6.0f;
    private int score = 0;

    void Start()
    {
        this.UpdateScoreUI();
    }

    public void UpdateScoreUI()
    {
        this.txtScore.text = string.Format("{0} Point", score);
    }

    public void IncreaseScore(int score)
    {
        this.score += score;
    }
    public void DecreaseScore(int score)
    {
        this.score -= score;
    }


    void Update()
    {
        this.time -= Time.deltaTime;    //매프레임마다 감소된 시간을 표시
        this.txtTime.text = this.time.ToString("F1");   //소수점 1자리까지 표시
        if (time <= 0)
        {
            InfoManager.instance.totalScore += this.score;
            LoadEndScene();
        }
    }

    public void LoadEndScene()
    {
        SceneManager.LoadScene("EndScene");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LobbyMain : MonoBehaviour
{
    public List<GameObject> baskets;
    public Button btnStartGame;
    public GameObject button;
    // Start is called before the first frame update
    void Start()
    {
        button.SetActive(false);
        this.btnStartGame.onClick.AddListener(() =>
        {
            this.LoadGameScene();
        });
    }

    // Update is called once per frame
    void Update()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red, 2f);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 1000f))
        {
            Debug.Log(hit.collider.gameObject.name);

            GameObject foundBasketGo = this.baskets.Find(x => x == hit.collider.gameObject);

            int selectedBasketType = this.baskets.IndexOf(foundBasketGo);

            Debug.LogFormat("<color=yellow>selectedBasketType: {0}</color>", selectedBasketType);

            InfoManager.instance.selectedBasketType = selectedBasketType;

            foreach (var go in this.baskets)
            {
                if (go != foundBasketGo)
                {
                    //선택 되지 않은 것들 
                    go.SetActive(false);    //비활성화 
                    button.SetActive(true);
                }
            }
        }

    }

    public void LoadGameScene()
    {
        SceneManager.LoadScene("GameScene");
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InfoManager 
{
    public static readonly InfoManager instance = new InfoManager();

    public int selectedBasketType = -1; //0 노랑 // 1 빨강 // 2 초록
    public int totalScore = 0;
    public InfoManager()
    {

    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class GameMain : MonoBehaviour
{
    [SerializeField]
    private ItemGenerator itemGenerator;
    [SerializeField]
    private List<GameObject> baskPrefab;

    private BasketController basketController;

    // Start is called before the first frame update
    void Start()
    {
        this.CreateBasket();
    }

    private void CreateBasket()
    {
        GameObject prefab = this.baskPrefab[InfoManager.instance.selectedBasketType];
        GameObject basketGo = Instantiate(prefab);
        basketGo.transform.position = Vector3.zero;
        this.basketController = basketGo.GetComponent<BasketController>();
        this.basketController.Init();
    }

    // Update is called once per frame
    
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class EndMain : MonoBehaviour
{
    [SerializeField]
    private Text txtScore;
    [SerializeField]
    private Button btnLobby;
    [SerializeField]
    private Button btnRestart;

    [SerializeField]
    private List<GameObject> basketPrefabs;

    // Start is called before the first frame update
    void Start()
    {
        this.txtScore.text = string.Format("{0} Point", InfoManager.instance.totalScore);

        this.btnLobby.onClick.AddListener(() => {
            InfoManager.instance.totalScore = 0;
            InfoManager.instance.selectedBasketType = -1;
            SceneManager.LoadScene("LobbyScene");
        });

        this.btnRestart.onClick.AddListener(() => {
            InfoManager.instance.totalScore = 0;
            SceneManager.LoadScene("GameScene");
        });

        this.CreateBasket();
    }

    private void CreateBasket()
    {
        int index = InfoManager.instance.selectedBasketType;

        
        GameObject prefab = this.basketPrefabs[index];
        prefab.SetActive(true);
        GameObject basketGo = Instantiate(prefab);
        basketGo.transform.position = Vector3.zero;
    }


}

엔드씬에서 바구니가 보이지 않는 문제가 있었으나 카메라 위치를 수정함으로서 해결됐다.