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