2024/06/24 Unity 코딩 응용(아이템 들었다 놓기, 터뜨리기)
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()
월드 좌표를 화면 좌표로 변환하는 기능을 수행한다. 특정 객체의 월드 좌표를 주어진 카메라의 뷰포트에서의 화면 좌표로 변한다.
주요 용도
- UI 연동: 게임 객체의 위치를 화면상의 UI 요소와 동기화할 때 유용함. 예를 들어, 게임 객체의 위치에 따라 UI 마커를 표시하는 경우.
- 마우스 입력 처리: 월드 좌표와 마우스 위치를 비교하거나 동기화할 때 사용됨. 예를 들어, 드래그 앤 드롭 기능 구현 시 객체의 월드 좌표를 화면 좌표로 변환하여 마우스 위치와 연동하는 경우.
- 디버깅: 게임 객체의 월드 좌표가 화면의 어느 위치에 해당하는지 확인할 때 유용함.
참고
Camera.main은 씬에서 태그가 MainCamera로 설정된 카메라를 뜻한다. 이 함수는 카메라의 프로젝션 설정에 따라 월드 좌표를 화면 좌표로 정확하게 변환한다. 변환된 좌표를 사용하여 화면 상의 정확한 위치를 계산할 수 있다.
Camera.main.ScreenToWorldPoint()
화면 좌표를 월드 좌표로 변환하는 기능을 수행한다. 주어진 화면 좌표를 기준으로 카메라 뷰포트에서 월드 좌표로 변환한다.
주요 용도
- 마우스 입력 처리: 마우스 클릭이나 드래그 위치를 월드 좌표로 변환하여 게임 객체와의 상호작용을 구현할 때 사용됨. 예를 들어, 마우스 클릭한 위치에 객체를 이동시키거나, 드래그 앤 드롭 기능을 구현할 때 유용함.
- UI 연동: 화면 좌표를 월드 좌표로 변환하여 게임 내 UI 요소와 연동할 때 사용됨. 예를 들어, 화면의 특정 위치를 기준으로 게임 객체를 배치할 때 사용됨.
- 디버깅: 화면 좌표가 월드 공간에서 어디에 해당하는지 확인할 때 유용함.
작동영상
아이템 터뜨리기
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에 크랙이 있는 구 프리팹을 넣어준다.
그 다음 실행해서 마우스를 클릭해보면 잘 작동하는 것을 볼 수 있다.
작동영상