Files
whdwo798 4dad9e5d5b feat: SongCreator 씬 완성 — Beat Sage URL 지원, info.dat 메타데이터 자동 추출
- BeatSageUploader: audio_url 지원(UploadFromUrl), PollAndDownload 공통화, ZIP 500 오류 3회 재시도
- BeatSageConverter: info.dat 파싱(SongMetadata), BPM 자동 감지 → 노트 타이밍 변환에 적용
- SongCreatorManager: title/BPM 필수 입력 제거, 난이도 4개 자동 선택, GenerateFlowFromUrl 버그 수정
- NasPublisher: audioPath null 허용(URL 흐름에서 로컬 파일 없는 경우 스킵)
- .gitignore/.gitattributes 초기 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:37:34 +09:00

98 lines
3.7 KiB
C#

using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using VRSDK;
namespace DamageSystem
{
//this script controls the melee weapons like the sword,
//in the demo scene and the weapons prefabs, all the weapons can be use as melee weapons to,
//so they use this script
public class VR_MeleeWeapon : MonoBehaviour
{
#region INSPECTOR
[SerializeField] protected FastCollisionListener fastCollisionListener = null;
[SerializeField] protected Transform rayStart = null;
[SerializeField] protected Transform rayEnd = null;
[SerializeField] protected float minSpeed = 0.0f;
[SerializeField] protected float dmg = 0.0f;
[SerializeField] protected float hitForce = 0.0f;
[SerializeField] protected float maxHitForce = 800.0f;
[SerializeField] protected bool canDismember = false;
#endregion
#region PRIVATE
private VR_Grabbable grabbable = null;
private List<Damageable> thisDamageableList = null;
protected DamageInfo damageInfoCache = new DamageInfo();
#endregion
private void Awake()
{
grabbable = GetComponent<VR_Grabbable>();
thisDamageableList = transform.GetComponentsInChildren<Damageable>().ToList();
}
private void Update()
{
//check if we are hitting something
//we do it in the fixed update because the player can move his hands very quickly
if ( grabbable.CurrentGrabState == GrabState.Grab && grabbable.GrabController.Velocity.magnitude > minSpeed )
{
List<Collider> hitColliders = fastCollisionListener.CheckForCollisionsThisFrame();
for (int n = 0; n < hitColliders.Count; n++)
{
TryDoDamage(hitColliders[n].transform, hitColliders[n].transform.position);
}
}
}
protected bool TryDoDamage(Transform target, Vector3 hitPoint)
{
Damageable[] damageableArray = target.GetComponents<Damageable>();
if (damageableArray != null && damageableArray.Length > 0)
{
for (int n = 0; n < damageableArray.Length; n++)
{
if (damageableArray[n] != null && !thisDamageableList.Contains( damageableArray[n]) )
{
RaycastHit hitInfo;
if (Physics.Linecast(rayStart.position, rayEnd.position, out hitInfo, 1 << target.gameObject.layer))
{
DamageInfo damageInfo = CreateDamageInfo(hitInfo.point);
damageableArray[n].DoDamage(damageInfo);
}
}
}
return true;
}
return false;
}
protected virtual DamageInfo CreateDamageInfo(Vector3 hitPoint)
{
Vector3 controllerVelocity = grabbable.GrabController.Velocity;
damageInfoCache.dmg = dmg * controllerVelocity.magnitude;
damageInfoCache.hitDir = controllerVelocity.normalized;
damageInfoCache.hitPoint = hitPoint;
damageInfoCache.hitForce = Mathf.Min( ( controllerVelocity * hitForce ).magnitude, maxHitForce );
damageInfoCache.sender = grabbable.GrabController != null ? grabbable.GrabController.transform.root.gameObject : null;
damageInfoCache.canDismember = canDismember;
return damageInfoCache;
}
}
}