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>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user