유니티 기초

챕터 8 AppleCatch

다모아 2023. 8. 7. 12:20
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasketController : MonoBehaviour
{
    public Transform target;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            //화면상의 좌표 Ray를 만들자
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //ray를 눈으로 확인
            Debug.DrawRay(ray.origin, ray.direction * 100f, Color.green, 2f);

            //ray와 collider의 충돌을 검사하는 메서드
            RaycastHit hitData;
            //충돌되었다면 true , 아니면 false
            if(Physics.Raycast(ray, out hitData, 100f))
            {
                Debug.LogFormat("hit.point: {0}", hitData.point);
            }
        }
    }
}

 

두 물체 충돌은 무조건 둘 중 하나에 Rigidbody가 붙어 있어야함

둘 다 콜라이더가 있어야 함

 

리지드바디가 붙어 있음 중력의 영향을 받는다.

필요 없다면 중력의 영향을 받지 않게 만든다.

 

콜라이더 충돌모드 2가지

콜리전, 트리거

콜리전 모드일 경우 충돌반응 있음

트리거 모드일 경우 뚫고 지나감

 

사용되는 이벤트 함수가 다름

 

중력의 영향안받으려면 Kinematic


BasketController

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

public class BasketController : MonoBehaviour
{
    private AudioSource audioSource;
    [SerializeField]
    private AudioClip bombSfx;
    [SerializeField]
    private AudioClip appleSfx;
    // Start is called before the first frame update
    void Start()
    {
        this.audioSource = this.GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            //화면상의 좌표 Ray를 만들자
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //ray를 눈으로 확인
            Debug.DrawRay(ray.origin, ray.direction * 100f, Color.green, 2f);

            //ray와 collider의 충돌을 검사하는 메서드
            RaycastHit hitData;
            //충돌되었다면 true , 아니면 false
            if(Physics.Raycast(ray, out hitData, 100f))
            {
                Debug.LogFormat("hit.point: {0}", hitData.point);

                //바구니의 위치를 충돌한 지점으로 변경
                //this.transform.position = hitData.point;
                //x좌표와 z좌표를 반올림
                float x = Mathf.RoundToInt(hitData.point.x);
                float z = Mathf.RoundToInt(hitData.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);
        }
        else
        {
            Debug.Log("감점");
            this.audioSource.PlayOneShot(this.bombSfx);
        }

        Destroy(other.gameObject); //사과 또는 폭탄을 제거
    }
}

 

ItemController

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

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

    // Update is called once per frame
    void Update()
    {
        //리지드바디가 없는 오브젝트의 이동
        //this.transform.Translate(방향 * 속도 * 시간);
        //기본이 로컬좌표로 이동
        this.transform.Translate(Vector3.down * this.moveSpeed * Time.deltaTime);

        if(this.transform.position.y <= 0)
        {
            Destroy(this.gameObject); // Destroy(this); 완전히 다른 의미. Component가 제거됌
        }
    }
}

 

ItemGenerator

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

public class ItemGenerator : MonoBehaviour
{
    private float elasedTime; //경과 시간
    private float spawnTime = 1f; // 1초에 한번씩 스폰
    public GameObject applePrefab;
    public GameObject bombPrefab;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //시간 재기
        //변수에 Time.deltaTime더해라
        this.elasedTime += Time.deltaTime;
        //1초가 지났다면
        if(this.elasedTime >= this.spawnTime)
        {
            //아이템을 생성
            this.CreateItem();
            //초기화
            this.elasedTime = 0;
        }
    }

    private void CreateItem()
    {
        //사과 또는 폭탄
        int rand = Random.Range(1, 11); // 1 ~ 10
        GameObject itemGo = null;
        if (rand > 2) //3, 4, 5, 6, 7, 8, 9, 10
        {
            //사과
            itemGo = Instantiate<GameObject>(this.applePrefab);
        }
        else //1, 2
        {
            //폭탄
            itemGo = Instantiate<GameObject>(this.bombPrefab);
        }
        //위치 설정
        //x: -1, 1 [좌 , 우]
        //z: -1, 1 [위 아래]
        int x = Random.Range(-1, 2); // -1, 0, 1
        int z = Random.Range(-1, 2); // -1, 0, 2
        //위치를 설정
        itemGo.transform.position = new Vector3(x, 3.5f, z);
    }
}