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,158 @@
|
||||
using DamageSystem.Events;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace DamageSystem
|
||||
{
|
||||
public enum DamageType
|
||||
{
|
||||
Explosion,
|
||||
Shoot,
|
||||
Physical
|
||||
}
|
||||
|
||||
|
||||
public class DamageableManager : MonoBehaviour
|
||||
{
|
||||
|
||||
[SerializeField] protected float hp = 100.0f;
|
||||
[SerializeField] private float regenerationSpeed = 0.0f;
|
||||
[SerializeField] protected Rigidbody com = null;
|
||||
[SerializeField] private OnDamageEvent onDamage = null;
|
||||
[SerializeField] private UnityEvent onDie = null;
|
||||
[SerializeField] protected OnValueChangeEvent onHPChangeEvent;
|
||||
|
||||
protected bool isDead = false;
|
||||
private float maxHP = 0.0f;
|
||||
|
||||
public float HP { get { return hp; } }
|
||||
public OnDamageEvent OnDamage { get { return onDamage; } }
|
||||
public OnValueChangeEvent OnHPChangeEvent { get { return onHPChangeEvent; } }
|
||||
public UnityEvent OnDie { get { return onDie; } }
|
||||
public bool Invulnerable { get; set; }
|
||||
public bool IsDead { get { return isDead; } }
|
||||
public float MaxHP { get { return maxHP; } }
|
||||
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
maxHP = hp;
|
||||
|
||||
SetDamageablePartsOwner();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
DoRegeneration();
|
||||
}
|
||||
|
||||
protected virtual void DoRegeneration()
|
||||
{
|
||||
if(regenerationSpeed > 0.0f && !isDead)
|
||||
{
|
||||
ModifyHP( regenerationSpeed * Time.deltaTime );
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void SetDamageablePartsOwner()
|
||||
{
|
||||
//get all damageable
|
||||
DamageablePart[] damageableArray = GetComponentsInChildren<DamageablePart>();
|
||||
|
||||
//set his owner
|
||||
for (int n = 0; n < damageableArray.Length; n++)
|
||||
{
|
||||
damageableArray[n].SetOwner( this );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void DoDamage(DamageInfo info, DamageablePart damageable)
|
||||
{
|
||||
|
||||
//if we are dead just apply the impact force
|
||||
if (isDead)
|
||||
{
|
||||
ApplyImpactForce( info, damageable );
|
||||
|
||||
if (onDamage != null)
|
||||
onDamage.Invoke( info , damageable );
|
||||
return;
|
||||
}
|
||||
|
||||
ModifyHP(-info.dmg);
|
||||
|
||||
if (hp <= 0.0f)
|
||||
{
|
||||
TriggerDieEvent();
|
||||
ApplyImpactForce( info, damageable );
|
||||
}
|
||||
|
||||
if (onDamage != null)
|
||||
{
|
||||
onDamage.Invoke( info, damageable );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected virtual void ApplyImpactForce(DamageInfo info, DamageablePart damageable)
|
||||
{
|
||||
//if this AI if no dead it is being controlled by the Animator so dont apply any impact force
|
||||
if (!IsDead)
|
||||
return;
|
||||
|
||||
if (com != null && info.damageType == DamageType.Explosion)
|
||||
{
|
||||
com.AddExplosionForce( info.hitForce, info.hitPoint, info.explosionRadius, info.upwardsModifier, info.forceMode );
|
||||
}
|
||||
else if (damageable.RB != null && info.damageType == DamageType.Shoot)
|
||||
{
|
||||
damageable.RB.AddForceAtPosition( info.hitForce * info.hitDir, info.hitPoint, info.forceMode );
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void TriggerDieEvent()
|
||||
{
|
||||
if (onDie != null)
|
||||
onDie.Invoke();
|
||||
|
||||
isDead = true;
|
||||
}
|
||||
|
||||
public void SetupDamageableLimbs()
|
||||
{
|
||||
Collider[] colliderArray = transform.GetComponentsInChildren<Collider>();
|
||||
|
||||
for (int n = 0; n < colliderArray.Length; n++)
|
||||
{
|
||||
if (colliderArray[n].GetComponent<DamageableLimb>() == null)
|
||||
{
|
||||
colliderArray[n].gameObject.AddComponent<DamageableLimb>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Kill()
|
||||
{
|
||||
ModifyHP(float.MinValue);
|
||||
|
||||
if (onDie != null)
|
||||
onDie.Invoke();
|
||||
}
|
||||
|
||||
public virtual void ModifyHP(float v, bool triggerEvent = true)
|
||||
{
|
||||
hp += v;
|
||||
|
||||
if (hp < 0.0f)
|
||||
hp = 0.0f;
|
||||
if (hp > MaxHP)
|
||||
hp = maxHP;
|
||||
|
||||
if (triggerEvent)
|
||||
{
|
||||
onHPChangeEvent.Invoke(hp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user