Unity

2024/06/24 Unity 코딩 응용(아이템 들었다 놓기, 터뜨리기)

민정e 2024. 6. 24. 10:06

void가 아닌 메서드를 사용할땐 꼭 return 값을 넣어주어야한다.

 

아이템 들었다 놓기

 

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

public class Move : MonoBehaviour
{
    Vector3 mousePos; // 마우스 위치와 물체 위치의 차이를 저장할 변수

    // 현재 객체의 월드 좌표를 화면 좌표로 변환하여 반환하는 메소드
    private Vector3 GetMousePos() 
    {
        return Camera.main.WorldToScreenPoint(transform.position);
    }

    // 마우스를 클릭했을 때 호출되는 메소드
    private void OnMouseDown() 
    {
        // 마우스 위치와 객체 위치의 차이를 계산하여 저장
        mousePos = Input.mousePosition - GetMousePos();
    }

    // 마우스를 드래그하는 동안 호출되는 메소드
    private void OnMouseDrag() 
    {
        // 마우스의 현재 위치에서 객체 위치의 차이를 빼서 객체를 이동
        transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition - mousePos);
    }
}

 

Camera.main.WorldToScreenPoint()

월드 좌표를 화면 좌표로 변환하는 기능을 수행한다. 특정 객체의 월드 좌표를 주어진 카메라의 뷰포트에서의 화면 좌표로 변한다.

주요 용도

  1. UI 연동: 게임 객체의 위치를 화면상의 UI 요소와 동기화할 때 유용함. 예를 들어, 게임 객체의 위치에 따라 UI 마커를 표시하는 경우.
  2. 마우스 입력 처리: 월드 좌표와 마우스 위치를 비교하거나 동기화할 때 사용됨. 예를 들어, 드래그 앤 드롭 기능 구현 시 객체의 월드 좌표를 화면 좌표로 변환하여 마우스 위치와 연동하는 경우.
  3. 디버깅: 게임 객체의 월드 좌표가 화면의 어느 위치에 해당하는지 확인할 때 유용함.

참고

Camera.main은 씬에서 태그가 MainCamera로 설정된 카메라를 뜻한다. 이 함수는 카메라의 프로젝션 설정에 따라 월드 좌표를 화면 좌표로 정확하게 변환한다. 변환된 좌표를 사용하여 화면 상의 정확한 위치를 계산할 수 있다.

 

Camera.main.ScreenToWorldPoint()

화면 좌표를 월드 좌표로 변환하는 기능을 수행한다. 주어진 화면 좌표를 기준으로 카메라 뷰포트에서 월드 좌표로 변환한다.

주요 용도

  1. 마우스 입력 처리: 마우스 클릭이나 드래그 위치를 월드 좌표로 변환하여 게임 객체와의 상호작용을 구현할 때 사용됨. 예를 들어, 마우스 클릭한 위치에 객체를 이동시키거나, 드래그 앤 드롭 기능을 구현할 때 유용함.
  2. UI 연동: 화면 좌표를 월드 좌표로 변환하여 게임 내 UI 요소와 연동할 때 사용됨. 예를 들어, 화면의 특정 위치를 기준으로 게임 객체를 배치할 때 사용됨.
  3. 디버깅: 화면 좌표가 월드 공간에서 어디에 해당하는지 확인할 때 유용함.

 

 

작동영상

 

 

아이템 터뜨리기

Blender에서 Cell Fracture로 파츠를 나누어놓은 fbx파일을 불러온다.

각 파츠별로 다 RigidBody와 Mesh Collider를 추가해주고, isKinematic과 Convex에 체크를 해준다.

그리고 다음과 같이 코드를 작성한 다음, fbx파일의 Parent에 해당하는 부분에 스크립트를 넣어준다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UI 네임스페이스 추가

public class Crack : MonoBehaviour
{
    public float minForce;
    public float maxForce;
    public float radius;
    public float destroyDelay;
    public Button explodeButton;


    public void Start()
    {
        foreach (Transform t in transform) // 각 파츠별로 isKinematic 설정 체크해주는 코드
        {
            var rb = t.GetComponent<Rigidbody>();
            if (rb != null)
            {
                rb.isKinematic = true;
            }
        }
    }
    public void OnButtonClick()
    {
        Explode(); // 버튼 클릭 시 Explode 메서드 호출
    }


    public void Explode()
    {
        foreach(Transform t in transform)
        {
            var rb = t.GetComponent<Rigidbody>();

            if(rb != null)
            {
                rb.isKinematic = false; // isKinematic해제
                rb.AddExplosionForce(Random.Range(minForce, maxForce), transform.position, radius); // 터지는 메서드
            }

            Destroy(t.gameObject, destroyDelay); // Delay시간 뒤에 오브젝트가 사라지도록 설정
        }
    }
}

 

작동영상

 

 

 

이번엔 온전한 모양의 구에서 시작하여 마우스를 클릭했을 때 크랙이 있는 오브젝트로 변환, 터지도록 설정해보자

Crack1과 Crack2 스크립트를 다음과 같이 작성해준다.

 

Crack1

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

public class Crack1 : MonoBehaviour
{
    public float minForce;
    public float maxForce;
    public float radius;
    public float destroyDelay;


    public void Start()
    {
        Explode();
    }



    public void Explode()
    {
        foreach (Transform t in transform)
        {
            var rb = t.GetComponent<Rigidbody>();

            if (rb != null)
            {
                rb.AddExplosionForce(Random.Range(minForce, maxForce), transform.position, radius);
            }

            Destroy(t.gameObject, destroyDelay);
        }
    }
}

 

Crack2

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

public class Crack2 : MonoBehaviour
{
    public GameObject origin;
    public GameObject fracture;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // 마우스 왼클릭했을때
        {
            Spawn(); // Spawn함수 실행
        }
    }

    public void Spawn()
    {
        // origin 오브젝트 파괴
        Destroy(origin);
        
        // fracture 프리팹을 인스턴스화하여 fractObj 변수에 할당
        GameObject fractObj = Instantiate(fracture) as GameObject;

        // fractObj의 Crack1 컴포넌트를 찾아서 Explode 함수 호출
        fractObj.GetComponent<Crack1>().Explode();
    }
}

 

 

그 다음, Crack1스크립트와 Crack2 스크립트를 크랙이 있는 구와  온전한 구에 순차적으로 넣어준 다음,

Crack2 스크립트 컴포넌트에 origin에 온전한 구, fracture에 크랙이 있는 구 프리팹을 넣어준다.

 

 

그 다음 실행해서 마우스를 클릭해보면 잘 작동하는 것을 볼 수 있다.

 

작동영상