Files

112 lines
3.7 KiB
C#
Raw Permalink Normal View History

2026-04-30 14:00:10 +09:00
using System.ComponentModel.Design.Serialization;
using UnityEngine;
using EzySlice;
2026-04-30 14:00:10 +09:00
public class Saber : MonoBehaviour
{
//손잡이랑 검끝 사이를 레이 쏠 예정(검날)
[Header("슬라이스용 직렬화")]
public Transform startSlicePoint;
public Transform endSlicePoint;
public VelocityEstimator velocityEstimator; //속도측정기(검 끝에 달림)
public LayerMask sliceableLayer; //하는김에 얘도 그냥 직렬화
2026-04-30 14:00:10 +09:00
[Header("이펙트 세팅")]
public Material cuttingMaterial; //절단면
public float cutForce = 100f; //잘린 조각 튕기기
[Header("슬라이스 조건 설정")]
[Range(60f, 160f)]
public float sliceAngle = 100f; // 필요 각도 (직렬화해서 인스펙터에서 조절 가능하게)
[Tooltip("이 속도보다 빨라야만 슬라이싱이 작동합니다.")]
public float swingSpeedThreshold = 2.0f; // 필요 최소 속도 (이 값을 조절해서 '갖다 대기'를 방지)
2026-04-30 14:00:10 +09:00
private void FixedUpdate()
2026-04-30 14:00:10 +09:00
{
//손잡이와 검 끝 사이에 선을 그어 체크
bool hasHit = Physics.Linecast(
startSlicePoint.position,
endSlicePoint.position,
out RaycastHit hit,
sliceableLayer);
//체크됐으면
if (hasHit)
2026-04-30 14:00:10 +09:00
{
//hit 된 오브젝트를 타겟으로 자르기 메서드 실행
GameObject target = hit.transform.gameObject;
Vector3 swingVelocity = velocityEstimator.Velocity;
float currentSwingSpeed = swingVelocity.magnitude;
if (currentSwingSpeed > swingSpeedThreshold) // 1단계: 속도 체크
2026-04-30 14:00:10 +09:00
{
// 5. 각도 체크
// swingVelocity.normalized를 쓰면 크기를 무시하고 방향만 비교할 수 있어 더 정확합니다.
float angle = Vector3.Angle(swingVelocity.normalized, target.transform.up);
if (angle > sliceAngle) // 2단계: 각도 체크
{
Slice(target);
}
2026-04-30 14:00:10 +09:00
}
}
}
//자르는 메서드
public void Slice(GameObject target)
{
//1. 자를 평면 방향 구하기
//1-1. 검 방향 벡터
Vector3 saberDirection = endSlicePoint.position - startSlicePoint.position;
2026-04-30 14:00:10 +09:00
//1-2. 검 속도벡터(velocityEstimator.Velocity)
Vector3 velocity = velocityEstimator.Velocity;
//1-3. 두 벡터의 수직인 벡터를 구해서 정규화 = 자르는 면의 방향
Vector3 planeNormal = Vector3.Cross(saberDirection, velocity).normalized;
//2. 자르기
SlicedHull hull = target.Slice(endSlicePoint.position, planeNormal, cuttingMaterial);
if (hull == null)
{
return;
}
//3. 위아래조각 생성(여기부턴 동일)
GameObject upperHull = hull.CreateUpperHull(target, cuttingMaterial);
GameObject lowerHull = hull.CreateLowerHull(target, cuttingMaterial);
//4. 조각들에 SetupHull 물리부여
SetupHull(upperHull);
SetupHull(lowerHull);
//5. 원본은 삭제
Destroy(target);
}
//물리 부여
//얜 거의 안 건드리고 레이어 바꾸는 거만 추가
void SetupHull(GameObject hull)
{
Rigidbody rb = hull.AddComponent<Rigidbody>();
MeshCollider collider = hull.AddComponent<MeshCollider>();
collider.convex = true;//물리충돌용
//잘린 면 방향으로 힘을 가해 튕기게
rb.AddExplosionForce(cutForce, hull.transform.position, 1f);
//레이어 바꿔서 계속 잘리는 거 방지(소리엉킴)
hull.layer = LayerMask.NameToLayer("Default");
Destroy(hull, 3f); // 3초 뒤 삭제
2026-04-30 14:00:10 +09:00
}
2026-04-30 14:00:10 +09:00
}