2026-04-08 스킬시스템 진행중, 폴더구조 변경등
This commit is contained in:
BIN
Assets/01_Scenes/GameScene.unity
LFS
BIN
Assets/01_Scenes/GameScene.unity
LFS
Binary file not shown.
@@ -1 +1 @@
|
||||
public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Hit, Dead, Inertia, Action, Trans, None }
|
||||
public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Cast, Channel, Hit, Dead, Inertia, Action, Trans, None }
|
||||
@@ -57,7 +57,7 @@ public void SetMaxJumpCount(int maxCount)
|
||||
|
||||
#region 상태확인용 헬퍼함수들
|
||||
//지상 이동이 가능한가?
|
||||
public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia && CurrentState != PlayerState.Action && CurrentState != PlayerState.Trans);
|
||||
public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia && CurrentState != PlayerState.Action && CurrentState != PlayerState.Trans && CurrentState != PlayerState.Cast && CurrentState != PlayerState.Channel);
|
||||
//점프가 가능한 상태인가?
|
||||
public bool CanJump()
|
||||
{
|
||||
@@ -81,6 +81,7 @@ public bool CanDodge()
|
||||
if (CurrentState == PlayerState.Inertia) return false;
|
||||
if (CurrentState == PlayerState.Action) return false;
|
||||
if (CurrentState == PlayerState.Trans) return false;
|
||||
if (CurrentState == PlayerState.Cast || CurrentState == PlayerState.Channel) return false;
|
||||
|
||||
// 스태미나 시스템이 있다면 체크
|
||||
// if (CurrentStamina < DodgeCost) return false;
|
||||
@@ -92,8 +93,9 @@ public bool CanDodge()
|
||||
//공격이 가능한 상태인가?
|
||||
public bool CanAttack()
|
||||
{
|
||||
//이미 공격 중이거나 차징 중이면 공격 불가 (연속기가 있다면 바뀔수 있음)
|
||||
if (CurrentState == PlayerState.Attack || CurrentState == PlayerState.Charge)
|
||||
//이미 공격 중이거나 차징/캐스팅/채널링 중이면 공격 불가
|
||||
if (CurrentState == PlayerState.Attack || CurrentState == PlayerState.Charge
|
||||
|| CurrentState == PlayerState.Cast || CurrentState == PlayerState.Channel)
|
||||
return false;
|
||||
|
||||
//피격(Hit) 중이거나 죽었다면(Dead) 공격 불가
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class PlayerHealth : Health
|
||||
public class PlayerHealth : Health, IDamageable
|
||||
{
|
||||
[SerializeField] PlayerStat _pstat;
|
||||
|
||||
@@ -33,6 +33,13 @@ private void Update()
|
||||
|
||||
public void TakeDamage(int damage)
|
||||
{
|
||||
ChangeHP(currentHp - Mathf.Clamp(damage,0,currentHp));
|
||||
ChangeHP(currentHp - Mathf.Clamp(damage, 0, currentHp));
|
||||
}
|
||||
|
||||
public void TakeDamage(int damage, Transform source)
|
||||
{
|
||||
TakeDamage(damage);
|
||||
}
|
||||
|
||||
public Transform GetTransform() => transform;
|
||||
}
|
||||
|
||||
30
Assets/02_Scripts/Skill/Data/DebuffData.cs
Normal file
30
Assets/02_Scripts/Skill/Data/DebuffData.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
public enum DebuffType
|
||||
{
|
||||
DamageOverTime,
|
||||
Slow,
|
||||
StatReduction,
|
||||
Stun
|
||||
}
|
||||
|
||||
[CreateAssetMenu(menuName = "Skill/DebuffData")]
|
||||
public class DebuffData : ScriptableObject
|
||||
{
|
||||
[Header("기본 정보")]
|
||||
public string DebuffName;
|
||||
public Sprite Icon;
|
||||
|
||||
[Header("디버프 설정")]
|
||||
public DebuffType DebuffType;
|
||||
public float Duration;
|
||||
public float TickInterval;
|
||||
public float Value;
|
||||
|
||||
[Header("스택")]
|
||||
public bool Stackable;
|
||||
public int MaxStacks;
|
||||
|
||||
[Header("이펙트")]
|
||||
public GameObject EffectPrefab;
|
||||
}
|
||||
2
Assets/02_Scripts/Skill/Data/DebuffData.cs.meta
Normal file
2
Assets/02_Scripts/Skill/Data/DebuffData.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71747801caf54d74cafaf0cabbc6bed7
|
||||
@@ -2,11 +2,39 @@
|
||||
|
||||
/*
|
||||
사용법:
|
||||
Project에서 Create → Skill/SkillData로 스킬 에셋 생성, 레벨별 수치 입력
|
||||
Create → Skill/WeaponSkillSet로 무기별 스킬 묶음 생성
|
||||
플레이어에 SkillManager + Effect 컴포넌트들 부착
|
||||
무기 변경 시 LoadWeaponSkills(skillSet) 호출
|
||||
입력 시 SkillInput(slotIndex, inputState) 호출
|
||||
1. Project에서 Create → Skill/SkillData로 스킬 에셋 생성, 레벨별 수치 입력
|
||||
2. Create → Skill/WeaponSkillSet로 무기별 스킬 묶음 생성
|
||||
3. Create → Skill/DebuffData로 디버프 에셋 생성 (필요시)
|
||||
4. 플레이어에 SkillModule + 필요한 Effect 컴포넌트들 부착
|
||||
(DamageEffect, AreaEffect, ZoneEffect, BuffEffect, ProjectileEffect)
|
||||
5. 디버프 받는 대상에 StatusEffectReceiver + IDamageable 구현 부착
|
||||
6. 무기 변경 시 LoadWeaponSkills(skillSet) 호출
|
||||
7. 입력 시 SkillInput(slotIndex, inputState) 호출
|
||||
8. Remote 스킬 범위 확인 시 AreaConfirmInput(inputState) 호출
|
||||
|
||||
ActivationType (발동 방식):
|
||||
Instant — 즉시 발동
|
||||
Charge — 누르고 있으면 차징, 놓으면 발동
|
||||
Cast — 시전 시간 후 자동 발동 (피격/회피 시 취소)
|
||||
Channel — 시전 동안 지속적으로 효과 반복 (피격/회피 시 취소)
|
||||
|
||||
CastMethod (발동 위치):
|
||||
Self — 자기 중심 발동 (키 입력 즉시 ActivationType 흐름 시작)
|
||||
Remote — 원격 발동 (마우스로 위치 선택 → 확인 후 ActivationType 흐름 시작)
|
||||
|
||||
TargetType (효과 방식):
|
||||
Single → DamageEffect
|
||||
Area → AreaEffect
|
||||
Self → BuffEffect
|
||||
Projectile → ProjectileEffect
|
||||
Zone → ZoneEffect (설치형)
|
||||
|
||||
조합 예시:
|
||||
Instant + Self → 즉시 자기 주변 발동
|
||||
Instant + Remote → 위치 선택 후 즉시 발동
|
||||
Cast + Remote → 위치 선택 → 캐스팅 → 완료 시 해당 위치에 발동
|
||||
Channel + Remote → 위치 선택 → 해당 위치에서 채널링
|
||||
Charge + Remote → 위치 선택 → 차징 → 릴리스 시 해당 위치에 발동
|
||||
*/
|
||||
|
||||
[CreateAssetMenu(menuName = "Skill/SkillData")]
|
||||
@@ -20,6 +48,7 @@ public class SkillData : ScriptableObject
|
||||
[Header("스킬 분류")]
|
||||
public SkillType SkillType;
|
||||
public ActivationType ActivationType;
|
||||
public CastMethod CastMethod;
|
||||
public TargetType TargetType;
|
||||
|
||||
[Header("애니메이션")]
|
||||
@@ -28,9 +57,15 @@ public class SkillData : ScriptableObject
|
||||
[Header("이펙트")]
|
||||
public GameObject EffectPrefab;
|
||||
|
||||
[Header("범위 지정 (AreaSelect용)")]
|
||||
[Header("범위 지정 (Remote용)")]
|
||||
public GameObject AreaIndicatorPrefab;
|
||||
|
||||
[Header("설치형 (Zone)")]
|
||||
public GameObject ZonePrefab;
|
||||
|
||||
[Header("디버프")]
|
||||
public DebuffData[] AppliedDebuffs;
|
||||
|
||||
[Header("레벨별 수치")]
|
||||
public SkillLevelData[] Levels;
|
||||
|
||||
@@ -50,8 +85,13 @@ public class SkillLevelData
|
||||
public float ManaCost;
|
||||
public float Duration;
|
||||
public float ChargeTimeMax;
|
||||
public float CastTime;
|
||||
public float ChannelDuration;
|
||||
public float TickInterval;
|
||||
public float TickDamage;
|
||||
}
|
||||
|
||||
public enum SkillType { Active, Passive }
|
||||
public enum ActivationType { Instant, Charge, AreaSelect }
|
||||
public enum TargetType { Self, Single, Area, Projectile }
|
||||
public enum ActivationType { Instant, Charge, Cast, Channel }
|
||||
public enum CastMethod { Self, Remote }
|
||||
public enum TargetType { Self, Single, Area, Projectile, Zone }
|
||||
|
||||
@@ -4,10 +4,19 @@ public class AreaEffect : MonoBehaviour, ISkillEffect
|
||||
{
|
||||
public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
{
|
||||
SkillLevelData levelData = skill.CurrentLevelData;
|
||||
float finalDamage = levelData.Damage * chargeRatio;
|
||||
Vector3 center = caster.position + caster.forward * skill.CurrentLevelData.Range;
|
||||
ApplyArea(skill, caster, center, chargeRatio);
|
||||
}
|
||||
|
||||
Vector3 center = caster.position + caster.forward * levelData.Range;
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio)
|
||||
{
|
||||
ApplyArea(skill, caster, targetPos, chargeRatio);
|
||||
}
|
||||
|
||||
private void ApplyArea(SkillInstance skill, Transform caster, Vector3 center, float chargeRatio)
|
||||
{
|
||||
SkillLevelData levelData = skill.CurrentLevelData;
|
||||
int damage = Mathf.RoundToInt(levelData.Damage * chargeRatio);
|
||||
|
||||
if (skill.Data.EffectPrefab != null)
|
||||
{
|
||||
@@ -19,25 +28,21 @@ public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
{
|
||||
if (hit.transform == caster) continue;
|
||||
|
||||
Debug.Log($"[범위] {hit.name}에게 {finalDamage} 데미지");
|
||||
IDamageable target = hit.GetComponent<IDamageable>();
|
||||
if (target != null)
|
||||
{
|
||||
target.TakeDamage(damage, caster);
|
||||
|
||||
if (skill.Data.AppliedDebuffs != null)
|
||||
{
|
||||
StatusEffectReceiver receiver = hit.GetComponent<StatusEffectReceiver>();
|
||||
if (receiver != null)
|
||||
{
|
||||
foreach (var debuff in skill.Data.AppliedDebuffs)
|
||||
receiver.ApplyDebuff(debuff);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos)
|
||||
{
|
||||
SkillLevelData levelData = skill.CurrentLevelData;
|
||||
|
||||
if (skill.Data.EffectPrefab != null)
|
||||
{
|
||||
Instantiate(skill.Data.EffectPrefab, targetPos, Quaternion.identity);
|
||||
}
|
||||
|
||||
Collider[] hits = Physics.OverlapSphere(targetPos, levelData.Range);
|
||||
foreach (Collider hit in hits)
|
||||
{
|
||||
if (hit.transform == caster) continue;
|
||||
|
||||
Debug.Log($"[범위지정] {hit.name}에게 {levelData.Damage} 데미지");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,4 +11,10 @@ public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
|
||||
Debug.Log($"버프 적용: {skill.Data.SkillName}, 지속시간 {levelData.Duration}초");
|
||||
}
|
||||
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio)
|
||||
{
|
||||
// 버프는 항상 시전자 대상이므로 Execute와 동일
|
||||
Execute(skill, caster, chargeRatio);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +4,40 @@ public class DamageEffect : MonoBehaviour, ISkillEffect
|
||||
{
|
||||
public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
{
|
||||
SkillLevelData levelData = skill.CurrentLevelData;
|
||||
float finalDamage = levelData.Damage * chargeRatio;
|
||||
float range = levelData.Range;
|
||||
Vector3 center = caster.position + caster.forward * skill.CurrentLevelData.Range * 0.5f;
|
||||
ApplyDamage(skill, caster, center, chargeRatio);
|
||||
}
|
||||
|
||||
Collider[] hits = Physics.OverlapSphere(caster.position + caster.forward * range * 0.5f, range);
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio)
|
||||
{
|
||||
ApplyDamage(skill, caster, targetPos, chargeRatio);
|
||||
}
|
||||
|
||||
private void ApplyDamage(SkillInstance skill, Transform caster, Vector3 center, float chargeRatio)
|
||||
{
|
||||
SkillLevelData levelData = skill.CurrentLevelData;
|
||||
int damage = Mathf.RoundToInt(levelData.Damage * chargeRatio);
|
||||
|
||||
Collider[] hits = Physics.OverlapSphere(center, levelData.Range);
|
||||
foreach (Collider hit in hits)
|
||||
{
|
||||
if (hit.transform == caster) continue;
|
||||
|
||||
// IDamageable 등 인터페이스가 있으면 여기서 적용
|
||||
Debug.Log($"{hit.name}에게 {finalDamage} 데미지");
|
||||
IDamageable target = hit.GetComponent<IDamageable>();
|
||||
if (target != null)
|
||||
{
|
||||
target.TakeDamage(damage, caster);
|
||||
|
||||
if (skill.Data.AppliedDebuffs != null)
|
||||
{
|
||||
StatusEffectReceiver receiver = hit.GetComponent<StatusEffectReceiver>();
|
||||
if (receiver != null)
|
||||
{
|
||||
foreach (var debuff in skill.Data.AppliedDebuffs)
|
||||
receiver.ApplyDebuff(debuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
public interface ISkillEffect
|
||||
{
|
||||
void Execute(SkillInstance skill, Transform caster, float chargeRatio);
|
||||
void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio);
|
||||
}
|
||||
|
||||
@@ -12,4 +12,17 @@ public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
// 투사체에 데미지 정보 전달
|
||||
// proj.GetComponent<Projectile>()?.Init(skill.CurrentLevelData.Damage * chargeRatio);
|
||||
}
|
||||
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio)
|
||||
{
|
||||
if (skill.Data.EffectPrefab == null) return;
|
||||
|
||||
Vector3 spawnPos = caster.position + Vector3.up;
|
||||
Vector3 direction = (targetPos - spawnPos).normalized;
|
||||
Quaternion rotation = Quaternion.LookRotation(direction);
|
||||
GameObject proj = Instantiate(skill.Data.EffectPrefab, spawnPos, rotation);
|
||||
|
||||
// 투사체에 데미지 정보 전달
|
||||
// proj.GetComponent<Projectile>()?.Init(skill.CurrentLevelData.Damage * chargeRatio);
|
||||
}
|
||||
}
|
||||
|
||||
29
Assets/02_Scripts/Skill/Effects/ZoneEffect.cs
Normal file
29
Assets/02_Scripts/Skill/Effects/ZoneEffect.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class ZoneEffect : MonoBehaviour, ISkillEffect
|
||||
{
|
||||
public void Execute(SkillInstance skill, Transform caster, float chargeRatio)
|
||||
{
|
||||
Vector3 center = caster.position + caster.forward * skill.CurrentLevelData.Range;
|
||||
SpawnZone(skill, center);
|
||||
}
|
||||
|
||||
public void ExecuteAtPosition(SkillInstance skill, Transform caster, Vector3 targetPos, float chargeRatio)
|
||||
{
|
||||
SpawnZone(skill, targetPos);
|
||||
}
|
||||
|
||||
private void SpawnZone(SkillInstance skill, Vector3 position)
|
||||
{
|
||||
if (skill.Data.ZonePrefab == null) return;
|
||||
|
||||
GameObject zoneObj = Instantiate(skill.Data.ZonePrefab, position, Quaternion.identity);
|
||||
ZoneEntity entity = zoneObj.GetComponent<ZoneEntity>();
|
||||
if (entity != null)
|
||||
{
|
||||
SkillLevelData data = skill.CurrentLevelData;
|
||||
float tickDmg = data.TickDamage > 0 ? data.TickDamage : data.Damage;
|
||||
entity.Init(tickDmg, data.Range, data.Duration, data.TickInterval, skill.Data.AppliedDebuffs);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/Skill/Effects/ZoneEffect.cs.meta
Normal file
2
Assets/02_Scripts/Skill/Effects/ZoneEffect.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 681ba972155e69d4e903ca9f06ade300
|
||||
61
Assets/02_Scripts/Skill/Effects/ZoneEntity.cs
Normal file
61
Assets/02_Scripts/Skill/Effects/ZoneEntity.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class ZoneEntity : MonoBehaviour
|
||||
{
|
||||
private float _damage;
|
||||
private float _radius;
|
||||
private float _duration;
|
||||
private float _tickInterval;
|
||||
private DebuffData[] _debuffs;
|
||||
|
||||
private float _lifeTimer;
|
||||
private float _tickAccumulator;
|
||||
|
||||
public void Init(float damage, float radius, float duration, float tickInterval, DebuffData[] debuffs)
|
||||
{
|
||||
_damage = damage;
|
||||
_radius = radius;
|
||||
_duration = duration;
|
||||
_tickInterval = tickInterval > 0 ? tickInterval : 1f;
|
||||
_debuffs = debuffs;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
_lifeTimer += Time.deltaTime;
|
||||
_tickAccumulator += Time.deltaTime;
|
||||
|
||||
if (_tickAccumulator >= _tickInterval)
|
||||
{
|
||||
_tickAccumulator -= _tickInterval;
|
||||
ApplyTickDamage();
|
||||
}
|
||||
|
||||
if (_lifeTimer >= _duration)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyTickDamage()
|
||||
{
|
||||
Collider[] hits = Physics.OverlapSphere(transform.position, _radius);
|
||||
foreach (Collider col in hits)
|
||||
{
|
||||
IDamageable target = col.GetComponent<IDamageable>();
|
||||
if (target == null) continue;
|
||||
|
||||
target.TakeDamage(Mathf.RoundToInt(_damage), transform);
|
||||
|
||||
if (_debuffs != null)
|
||||
{
|
||||
StatusEffectReceiver receiver = col.GetComponent<StatusEffectReceiver>();
|
||||
if (receiver != null)
|
||||
{
|
||||
foreach (var debuff in _debuffs)
|
||||
receiver.ApplyDebuff(debuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/Skill/Effects/ZoneEntity.cs.meta
Normal file
2
Assets/02_Scripts/Skill/Effects/ZoneEntity.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c474ebcf1164e1348b54f06b02241e08
|
||||
@@ -16,11 +16,26 @@ public class SkillModule : MonoBehaviour
|
||||
private int _chargingSlot = -1;
|
||||
private float _chargeTimer = 0f;
|
||||
|
||||
// 범위 지정
|
||||
// 캐스팅
|
||||
private int _castingSlot = -1;
|
||||
private float _castTimer = 0f;
|
||||
|
||||
// 채널링
|
||||
private int _channelingSlot = -1;
|
||||
private float _channelTimer = 0f;
|
||||
private float _channelTickAccumulator = 0f;
|
||||
|
||||
// 범위 지정 (Remote)
|
||||
private int _areaSelectSlot = -1;
|
||||
private GameObject _areaIndicator;
|
||||
|
||||
// Remote 타겟 위치
|
||||
private Vector3 _remoteTargetPos;
|
||||
private bool _hasRemoteTarget;
|
||||
|
||||
public bool IsAreaSelecting => _areaSelectSlot >= 0;
|
||||
public bool IsCasting => _castingSlot >= 0;
|
||||
public bool IsChanneling => _channelingSlot >= 0;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
@@ -36,6 +51,8 @@ private void Update()
|
||||
{
|
||||
TickCooldowns();
|
||||
TickCharge();
|
||||
TickCast();
|
||||
TickChannel();
|
||||
TickAreaSelect();
|
||||
}
|
||||
|
||||
@@ -67,6 +84,7 @@ private ISkillEffect ResolveEffect(TargetType targetType)
|
||||
TargetType.Single => GetComponent<DamageEffect>(),
|
||||
TargetType.Area => GetComponent<AreaEffect>(),
|
||||
TargetType.Projectile => GetComponent<ProjectileEffect>(),
|
||||
TargetType.Zone => GetComponent<ZoneEffect>(),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
@@ -92,18 +110,16 @@ public void SkillInput(int slotIndex, InputState inputState)
|
||||
|
||||
if (!CanUseSkill(skill)) return;
|
||||
|
||||
if (skill.Data.ActivationType == ActivationType.Instant)
|
||||
{
|
||||
ExecuteSkill(slotIndex);
|
||||
}
|
||||
else if (skill.Data.ActivationType == ActivationType.Charge)
|
||||
{
|
||||
StartCharge(slotIndex);
|
||||
}
|
||||
else if (skill.Data.ActivationType == ActivationType.AreaSelect)
|
||||
// Remote 스킬: 먼저 범위 지정 모드 진입
|
||||
if (skill.Data.CastMethod == CastMethod.Remote)
|
||||
{
|
||||
StartAreaSelect(slotIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Self 스킬: 바로 ActivationType 흐름
|
||||
BeginActivation(slotIndex);
|
||||
}
|
||||
}
|
||||
else if (inputState == InputState.Canceled)
|
||||
{
|
||||
@@ -111,6 +127,10 @@ public void SkillInput(int slotIndex, InputState inputState)
|
||||
{
|
||||
ReleaseCharge();
|
||||
}
|
||||
else if (_channelingSlot == slotIndex)
|
||||
{
|
||||
CancelChannel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +148,32 @@ public void AreaConfirmInput(InputState inputState)
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 발동 분기
|
||||
/// <summary>
|
||||
/// ActivationType에 따라 적절한 흐름을 시작
|
||||
/// </summary>
|
||||
private void BeginActivation(int slotIndex)
|
||||
{
|
||||
SkillInstance skill = _equippedSkills[slotIndex];
|
||||
|
||||
switch (skill.Data.ActivationType)
|
||||
{
|
||||
case ActivationType.Instant:
|
||||
ExecuteSkill(slotIndex);
|
||||
break;
|
||||
case ActivationType.Charge:
|
||||
StartCharge(slotIndex);
|
||||
break;
|
||||
case ActivationType.Cast:
|
||||
StartCast(slotIndex);
|
||||
break;
|
||||
case ActivationType.Channel:
|
||||
StartChannel(slotIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 실행
|
||||
private bool CanUseSkill(SkillInstance skill)
|
||||
{
|
||||
@@ -136,7 +182,8 @@ private bool CanUseSkill(SkillInstance skill)
|
||||
PlayerState state = _stateMachine.CurrentState;
|
||||
if (state == PlayerState.Dead || state == PlayerState.Hit
|
||||
|| state == PlayerState.Dodge || state == PlayerState.Trans
|
||||
|| state == PlayerState.Action)
|
||||
|| state == PlayerState.Action || state == PlayerState.Cast
|
||||
|| state == PlayerState.Channel)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -159,12 +206,26 @@ private void ExecuteSkill(int slotIndex)
|
||||
chargeRatio = maxCharge > 0 ? Mathf.Clamp01(_chargeTimer / maxCharge) : 1f;
|
||||
}
|
||||
|
||||
// CastMethod에 따라 실행 방식 분기
|
||||
if (_hasRemoteTarget)
|
||||
{
|
||||
effect?.ExecuteAtPosition(skill, _transform, _remoteTargetPos, chargeRatio);
|
||||
ClearRemoteTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
effect?.Execute(skill, _transform, chargeRatio);
|
||||
}
|
||||
|
||||
skill.StartCooldown();
|
||||
_chargeTimer = 0f;
|
||||
_chargingSlot = -1;
|
||||
}
|
||||
|
||||
private void ClearRemoteTarget()
|
||||
{
|
||||
_hasRemoteTarget = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 차지
|
||||
@@ -200,7 +261,150 @@ private void TickCharge()
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 범위 지정
|
||||
#region 캐스팅
|
||||
private void StartCast(int slotIndex)
|
||||
{
|
||||
_castingSlot = slotIndex;
|
||||
_castTimer = 0f;
|
||||
|
||||
_stateMachine.ChangeState(PlayerState.Cast);
|
||||
|
||||
SkillInstance skill = _equippedSkills[slotIndex];
|
||||
if (!string.IsNullOrEmpty(skill.Data.AnimTrigger))
|
||||
_anim.SetTrigger(skill.Data.AnimTrigger);
|
||||
|
||||
_stateMachine.OnStateChanged += OnCastInterrupted;
|
||||
}
|
||||
|
||||
private void TickCast()
|
||||
{
|
||||
if (_castingSlot < 0) return;
|
||||
|
||||
_castTimer += Time.deltaTime;
|
||||
|
||||
SkillInstance skill = _equippedSkills[_castingSlot];
|
||||
if (_castTimer >= skill.CurrentLevelData.CastTime)
|
||||
{
|
||||
CompleteCast();
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteCast()
|
||||
{
|
||||
if (_castingSlot < 0) return;
|
||||
|
||||
_stateMachine.OnStateChanged -= OnCastInterrupted;
|
||||
ExecuteSkill(_castingSlot);
|
||||
_castingSlot = -1;
|
||||
_castTimer = 0f;
|
||||
}
|
||||
|
||||
private void CancelCast()
|
||||
{
|
||||
_stateMachine.OnStateChanged -= OnCastInterrupted;
|
||||
_castingSlot = -1;
|
||||
_castTimer = 0f;
|
||||
ClearRemoteTarget();
|
||||
}
|
||||
|
||||
private void OnCastInterrupted(PlayerState newState)
|
||||
{
|
||||
if (newState == PlayerState.Hit || newState == PlayerState.Dead
|
||||
|| newState == PlayerState.Dodge)
|
||||
{
|
||||
CancelCast();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 채널링
|
||||
private void StartChannel(int slotIndex)
|
||||
{
|
||||
_channelingSlot = slotIndex;
|
||||
_channelTimer = 0f;
|
||||
_channelTickAccumulator = 0f;
|
||||
|
||||
_stateMachine.ChangeState(PlayerState.Channel);
|
||||
|
||||
SkillInstance skill = _equippedSkills[slotIndex];
|
||||
if (!string.IsNullOrEmpty(skill.Data.AnimTrigger))
|
||||
_anim.SetTrigger(skill.Data.AnimTrigger);
|
||||
|
||||
// 첫 틱 즉시 실행
|
||||
ISkillEffect effect = _skillEffects[slotIndex];
|
||||
ExecuteChannelTick(skill, effect);
|
||||
|
||||
// 쿨다운은 채널 시작 시점에 시작
|
||||
skill.StartCooldown();
|
||||
|
||||
_stateMachine.OnStateChanged += OnChannelInterrupted;
|
||||
}
|
||||
|
||||
private void TickChannel()
|
||||
{
|
||||
if (_channelingSlot < 0) return;
|
||||
|
||||
SkillInstance skill = _equippedSkills[_channelingSlot];
|
||||
SkillLevelData data = skill.CurrentLevelData;
|
||||
|
||||
_channelTimer += Time.deltaTime;
|
||||
_channelTickAccumulator += Time.deltaTime;
|
||||
|
||||
if (_channelTickAccumulator >= data.TickInterval)
|
||||
{
|
||||
_channelTickAccumulator -= data.TickInterval;
|
||||
ISkillEffect effect = _skillEffects[_channelingSlot];
|
||||
ExecuteChannelTick(skill, effect);
|
||||
}
|
||||
|
||||
if (_channelTimer >= data.ChannelDuration)
|
||||
{
|
||||
EndChannel();
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteChannelTick(SkillInstance skill, ISkillEffect effect)
|
||||
{
|
||||
if (_hasRemoteTarget)
|
||||
{
|
||||
effect?.ExecuteAtPosition(skill, _transform, _remoteTargetPos, 1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
effect?.Execute(skill, _transform, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void EndChannel()
|
||||
{
|
||||
_stateMachine.OnStateChanged -= OnChannelInterrupted;
|
||||
_stateMachine.ChangeState(PlayerState.Idle);
|
||||
_channelingSlot = -1;
|
||||
_channelTimer = 0f;
|
||||
_channelTickAccumulator = 0f;
|
||||
ClearRemoteTarget();
|
||||
}
|
||||
|
||||
private void CancelChannel()
|
||||
{
|
||||
_stateMachine.OnStateChanged -= OnChannelInterrupted;
|
||||
_channelingSlot = -1;
|
||||
_channelTimer = 0f;
|
||||
_channelTickAccumulator = 0f;
|
||||
ClearRemoteTarget();
|
||||
}
|
||||
|
||||
private void OnChannelInterrupted(PlayerState newState)
|
||||
{
|
||||
if (newState == PlayerState.Hit || newState == PlayerState.Dead
|
||||
|| newState == PlayerState.Dodge)
|
||||
{
|
||||
CancelChannel();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 범위 지정 (Remote)
|
||||
private void StartAreaSelect(int slotIndex)
|
||||
{
|
||||
_areaSelectSlot = slotIndex;
|
||||
@@ -229,26 +433,19 @@ private void ConfirmAreaSelect()
|
||||
{
|
||||
if (_areaSelectSlot < 0) return;
|
||||
|
||||
SkillInstance skill = _equippedSkills[_areaSelectSlot];
|
||||
ISkillEffect effect = _skillEffects[_areaSelectSlot];
|
||||
int slotIndex = _areaSelectSlot;
|
||||
|
||||
_stateMachine.ChangeState(PlayerState.Attack);
|
||||
|
||||
if (!string.IsNullOrEmpty(skill.Data.AnimTrigger))
|
||||
_anim.SetTrigger(skill.Data.AnimTrigger);
|
||||
|
||||
Vector3 targetPos = _areaIndicator.transform.position;
|
||||
|
||||
if (effect is AreaEffect areaEffect)
|
||||
{
|
||||
areaEffect.ExecuteAtPosition(skill, _transform, targetPos);
|
||||
}
|
||||
|
||||
skill.StartCooldown();
|
||||
// 타겟 위치 저장
|
||||
_remoteTargetPos = _areaIndicator.transform.position;
|
||||
_hasRemoteTarget = true;
|
||||
|
||||
// 인디케이터 정리
|
||||
Destroy(_areaIndicator);
|
||||
_areaIndicator = null;
|
||||
_areaSelectSlot = -1;
|
||||
|
||||
// ActivationType에 따라 흐름 시작
|
||||
BeginActivation(slotIndex);
|
||||
}
|
||||
|
||||
public void CancelAreaSelect()
|
||||
|
||||
55
Assets/02_Scripts/_Shared/Status/DebuffInstance.cs
Normal file
55
Assets/02_Scripts/_Shared/Status/DebuffInstance.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class DebuffInstance
|
||||
{
|
||||
public DebuffData Data { get; private set; }
|
||||
public float RemainingTime { get; private set; }
|
||||
public bool IsExpired => RemainingTime <= 0f;
|
||||
|
||||
private StatusEffectReceiver _receiver;
|
||||
private float _tickAccumulator;
|
||||
private GameObject _visualInstance;
|
||||
|
||||
public DebuffInstance(DebuffData data, StatusEffectReceiver receiver)
|
||||
{
|
||||
Data = data;
|
||||
_receiver = receiver;
|
||||
RemainingTime = data.Duration;
|
||||
_tickAccumulator = 0f;
|
||||
}
|
||||
|
||||
public void OnApply()
|
||||
{
|
||||
if (Data.EffectPrefab != null)
|
||||
{
|
||||
_visualInstance = Object.Instantiate(Data.EffectPrefab, _receiver.transform);
|
||||
}
|
||||
}
|
||||
|
||||
public void Tick(float deltaTime)
|
||||
{
|
||||
RemainingTime -= deltaTime;
|
||||
|
||||
if (Data.DebuffType == DebuffType.DamageOverTime && Data.TickInterval > 0)
|
||||
{
|
||||
_tickAccumulator += deltaTime;
|
||||
if (_tickAccumulator >= Data.TickInterval)
|
||||
{
|
||||
_tickAccumulator -= Data.TickInterval;
|
||||
IDamageable damageable = _receiver.GetComponent<IDamageable>();
|
||||
damageable?.TakeDamage(Mathf.RoundToInt(Data.Value), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRemove()
|
||||
{
|
||||
if (_visualInstance != null)
|
||||
Object.Destroy(_visualInstance);
|
||||
}
|
||||
|
||||
public void RefreshDuration()
|
||||
{
|
||||
RemainingTime = Data.Duration;
|
||||
}
|
||||
}
|
||||
2
Assets/02_Scripts/_Shared/Status/DebuffInstance.cs.meta
Normal file
2
Assets/02_Scripts/_Shared/Status/DebuffInstance.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17e97bf635cef364781fdf5cedc5dfee
|
||||
7
Assets/02_Scripts/_Shared/Status/IDamageable.cs
Normal file
7
Assets/02_Scripts/_Shared/Status/IDamageable.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
public interface IDamageable
|
||||
{
|
||||
void TakeDamage(int damage, Transform source);
|
||||
Transform GetTransform();
|
||||
}
|
||||
2
Assets/02_Scripts/_Shared/Status/IDamageable.cs.meta
Normal file
2
Assets/02_Scripts/_Shared/Status/IDamageable.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd29cb0b94cdd2c4388ff287969a9b5e
|
||||
69
Assets/02_Scripts/_Shared/Status/StatusEffectReceiver.cs
Normal file
69
Assets/02_Scripts/_Shared/Status/StatusEffectReceiver.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class StatusEffectReceiver : MonoBehaviour
|
||||
{
|
||||
private List<DebuffInstance> _activeDebuffs = new List<DebuffInstance>();
|
||||
|
||||
public void ApplyDebuff(DebuffData data)
|
||||
{
|
||||
if (data == null) return;
|
||||
|
||||
if (!data.Stackable)
|
||||
{
|
||||
DebuffInstance existing = _activeDebuffs.Find(d => d.Data == data);
|
||||
if (existing != null)
|
||||
{
|
||||
existing.RefreshDuration();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var d in _activeDebuffs)
|
||||
if (d.Data == data) count++;
|
||||
|
||||
if (count >= data.MaxStacks) return;
|
||||
}
|
||||
|
||||
DebuffInstance instance = new DebuffInstance(data, this);
|
||||
_activeDebuffs.Add(instance);
|
||||
instance.OnApply();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
for (int i = _activeDebuffs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
_activeDebuffs[i].Tick(Time.deltaTime);
|
||||
if (_activeDebuffs[i].IsExpired)
|
||||
{
|
||||
_activeDebuffs[i].OnRemove();
|
||||
_activeDebuffs.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasDebuff(DebuffType type)
|
||||
{
|
||||
foreach (var d in _activeDebuffs)
|
||||
if (d.Data.DebuffType == type) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetDebuffValue(DebuffType type)
|
||||
{
|
||||
float total = 0f;
|
||||
foreach (var d in _activeDebuffs)
|
||||
if (d.Data.DebuffType == type) total += d.Data.Value;
|
||||
return total;
|
||||
}
|
||||
|
||||
public void ClearAllDebuffs()
|
||||
{
|
||||
for (int i = _activeDebuffs.Count - 1; i >= 0; i--)
|
||||
_activeDebuffs[i].OnRemove();
|
||||
_activeDebuffs.Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dafab9c2111f5d640bf9eb470963b85d
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
Assets/06_Skills/VFX.meta
Normal file
8
Assets/06_Skills/VFX.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40612b926034315458eba38db0787f62
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/06_Skills/VFX/SelfMadeVFX.meta
Normal file
8
Assets/06_Skills/VFX/SelfMadeVFX.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e710993297443f4c8d7890d0ed4ead0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1
Assets/06_Skills/VFX/SelfMadeVFX/dumy.txt
Normal file
1
Assets/06_Skills/VFX/SelfMadeVFX/dumy.txt
Normal file
@@ -0,0 +1 @@
|
||||
dumy
|
||||
7
Assets/06_Skills/VFX/SelfMadeVFX/dumy.txt.meta
Normal file
7
Assets/06_Skills/VFX/SelfMadeVFX/dumy.txt.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 806fca355ae44fc4594198b3b11cbb7f
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/06_Skills/VFX/SpecialSkillsEffectsPack.meta
Normal file
8
Assets/06_Skills/VFX/SpecialSkillsEffectsPack.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a56f1a9e9db590a4b9af0dd1f8188562
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ab879817acc49a45a17f2c3e96658e2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83dd87227f362a34ab03155d35cbf27e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e7f2c757d7b9e842ae3ce38fa7fdab6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f554ea584ffd2164790a57d35d896ef3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 006108278f99e584394c13c81bfcb7f9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 513a171cf5a52ed4a8ea91b31db367ff
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_01_StormTornado/Effect_01_LightningTornado.prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 318ac0a9a9480c44c8ff11aec9fb3a43
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_01_StormTornado/Effect_01_LightningTornado/Effect_01_LightningTornado(Base).prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a66ac8cc7bfe6f7449bdb1d44b77fe3e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_01_StormTornado/Effect_01_StormTornado.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b01d1b0ed91e6574fb7be480d5904f54
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80cf365a0d4411a4099f07a0bec382d7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_02_BlackHole/Effect_02_BlackHole.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ac351e1ea5775840a748130301f9b37
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b744a3721083c254eb7cef9b9f835947
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_03_OrbitalStrike/Effect_03_OrbitalAnnihilationBeam.prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a762a5f89618ce24d9193fe9a13cab77
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_03_OrbitalStrike/Effect_03_OrbitalStrike.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a38226080fd00b44ebf9af7d8721c444
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e18c351ac3f6ed7409f6cae5ba1302eb
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_04_ChargeShot/Effect_04_ChargeAndRelease.prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a0c3309985528645b50dffd642237b3
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_04_ChargeShot/Effect_04_ChargeShot.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cf5e13c5eeab8f42bb6134a21c69bde
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a7a46686d4340c4b832ba8d02f87a99
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_12_CosmicHorror/Effect_12_CosmicHorror.prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e119eba0536a144a8bf50ea32e75c28
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_12_CosmicHorror/Effect_12_UniverseEater.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f981b43f8cbe41e49aafda13bfff0653
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96aacb3c58028424aa3e5f4e5c55f12e
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_18_TimeField/Effect_18_TimeField.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1fb8f2eaf22b9b4ba054beca200ac73
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09bdcfb3557270f4f9d606a9d7c61f58
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79be24f135d46964e9f186bacaca2299
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_21_GroundScatter/Effect_21_GroundScatter.prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ae8d95860915148bdf28559c527cbb
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_21_GroundScatter/Effect_21_GroundScatter/Effect_21_GroundScatter(Base).prefab
|
||||
uploadId: 865912
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 519ff72a211faaf43b8be89b3169a13d
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_21_GroundScatter/Effect_21_InnertcoreRelease.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db8e119f1c8e62748be05e35d1f2f610
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8b6a6f913bc4c748af1eb91ba8d1a23
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_28_PurifierBeam/Effect_28_PurifierBeam.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7478b4686dce774e95d61c470603db6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7016aae7bbdcd54fb4bf3a41bf01a60
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_31_LumenJudgement/Effect_31_LumenJudgement.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02dc2d98304de9147b8d151c485a2c1d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a504412f1061444bb18de98ad4be8d6
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_34_WindTurbulance/Effect_34_WindTurbulance.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01974900949ed54468f2a9ceb9a7d830
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34d0599d37e35ac4ebeab64c18d00ccc
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 171146
|
||||
packageName: 100 Special Skills Effects Pack
|
||||
packageVersion: 26.2
|
||||
assetPath: Assets/SpecialSkillsEffectsPack/AllEffects/EffectsSet_1(NotScriptBased)/Effects/Effect_38_GloryBoundary/Effect_38_GloryBoundary.prefab
|
||||
uploadId: 865912
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95bc93955f26d114281032693474c855
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user