Project_WL/Assets/Script/Character/Projectile/ProjectileBase.cs

496 lines
20 KiB
C#
Raw Normal View History

2024-12-15 01:39:39 +00:00
using CodeStage.AntiCheat.ObscuredTypes;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum eProjectileStartPos { None, Shooter, ShooterCenter, Target, TargetCenter, Custom }
public enum eProjectileStrait { Forward, Down }
public class ProjectileData
{
public ProjectileBase m_ProjectileBase;
public Actor shooter, target;
public SkillListTableData m_SkillListTableData;
public OptionConfigTableData m_OptionConfigTableData;
public SkillTypeConfigTableData m_skillTypeConfigTable;
public eEffect m_Skill = eEffect.None;
public eSkillExtraType e_SkillExtraType = eSkillExtraType.None;
2025-02-19 04:14:09 +00:00
public float Speed = 5f, LifeTime = 4f, DamageArea;
2024-12-15 01:39:39 +00:00
public eProjectileStartPos eStartPos = eProjectileStartPos.None;
public Vector3 v3_StartPos;
public bool SetSkillExtraType = true, IsRandomPos, LookTarget = true, CheckOptionWhenStart = true;
public double Amount;
public Action<Actor> Action_OnHit;
ObscuredDouble _BaseDmg;
2025-02-19 04:14:09 +00:00
ObscuredFloat _AddDmgPercent = 1f, _CC_AddTime, _CC_AddDmg, _CC_AddVal1, _CC_AddVal2;
public double BaseDmg { get { return _BaseDmg; } set { _BaseDmg = value; _BaseDmg.RandomizeCryptoKey(); } }
public float AddDmgPercent { get { return _AddDmgPercent; }
set
{
_AddDmgPercent = value;
_AddDmgPercent.RandomizeCryptoKey();
}
}
public float CC_AddTime { get { return _CC_AddTime; } set { _CC_AddTime = value; _CC_AddTime.RandomizeCryptoKey(); } }
public float CC_AddDmg { get { return _CC_AddDmg; } set { _CC_AddDmg = value; _CC_AddDmg.RandomizeCryptoKey(); } }
public float CC_AddVal1 { get { return _CC_AddVal1; } set { _CC_AddVal1 = value; _CC_AddVal1.RandomizeCryptoKey(); } }
public float CC_AddVal2 { get { return _CC_AddVal2; } set { _CC_AddVal2 = value; _CC_AddVal2.RandomizeCryptoKey(); } }
2024-12-15 01:39:39 +00:00
2025-02-09 06:50:27 +00:00
public void Reset()
{
shooter = null;
target = null;
2025-02-19 04:14:09 +00:00
AddDmgPercent = 1f;
2025-02-09 06:50:27 +00:00
eStartPos = eProjectileStartPos.ShooterCenter;
v3_StartPos = Vector3.zero;
LifeTime = 4f;
SetSkillExtraType = true;
LookTarget = true;
IsRandomPos = false;
CheckOptionWhenStart = true;
m_Skill = eEffect.None;
e_SkillExtraType = eSkillExtraType.None;
}
2024-12-15 01:39:39 +00:00
public bool IsSkill() { return !DSUtil.CheckNull(m_SkillListTableData); }
public bool IsSkill(eEffect skill) { return IsSkill() && m_SkillListTableData.e_Skill == skill; }
public Vector3 Get_EffectPos(Actor target)
{
var stcData = m_skillTypeConfigTable;
if (!DSUtil.CheckNull(stcData))
{
Vector3 effectPos;
switch (stcData.e_EffectLocation)
{
case eEffectLocation.Top: effectPos = target.Get_Top_postion(); break;
default: effectPos = target.Get_Center_position(); break;
case eEffectLocation.Bottom: effectPos = target.Get_position(); break;
}
return new Vector3(effectPos.x + stcData.n_EffectPosition_X, effectPos.y + stcData.n_EffectPosition_Y, effectPos.z);
}
return Vector3.right * 1000000f;
}
public float Get_SkillDamagePercent()
{
if (!shooter.IsRole(eRole.Mob))
{
var lv = shooter.Get_ServerData().Get_SkillLv(shooter.m_Role, m_SkillListTableData.n_SkillID);
var tabledmg = m_SkillListTableData.Get_SkillDamage(shooter.Get_StatInfo(), lv);
return tabledmg + (float)shooter.Get_StatInfo().Get_Stat(eStat.SKILL_Multiplier) + AddDmgPercent;
}
return 1f;
2024-12-15 01:39:39 +00:00
}
public ProjectileData Copy()
{
ProjectileData pd = new ProjectileData();
Copy(pd);
return pd;
}
public void Copy(ProjectileData pd)
{
pd.m_ProjectileBase = m_ProjectileBase;
pd.shooter = shooter;
pd.Action_OnHit = Action_OnHit;
pd.target = target;
pd.m_skillTypeConfigTable = m_skillTypeConfigTable;
pd.IsRandomPos = IsRandomPos;
pd.LifeTime = LifeTime;
pd.m_SkillListTableData = m_SkillListTableData;
2025-05-13 02:04:39 +00:00
pd.SetSkillExtraType = SetSkillExtraType;
pd.e_SkillExtraType = e_SkillExtraType;
pd.m_skillTypeConfigTable = m_skillTypeConfigTable;
2024-12-15 01:39:39 +00:00
pd.m_Skill = m_Skill;
pd.Speed = Speed;
pd.v3_StartPos = v3_StartPos;
pd.eStartPos = eStartPos;
2025-02-19 04:14:09 +00:00
pd.AddDmgPercent = AddDmgPercent;
2024-12-15 01:39:39 +00:00
pd.BaseDmg = BaseDmg;
pd.CC_AddTime = CC_AddTime;
pd.CC_AddDmg = CC_AddDmg;
pd.CC_AddVal1 = CC_AddVal1;
pd.CC_AddVal2 = CC_AddVal2;
pd.DamageArea = DamageArea;
}
2025-02-20 01:00:59 +00:00
public void Set_SkillExtra_MakeSkillListTableData(eSkillExtraType skillExtraType, float val1, float val2 = 0f, float ccRate = 1f)
2025-02-20 01:00:59 +00:00
{
e_SkillExtraType = skillExtraType;
m_skillTypeConfigTable = table_skilltypeconfig.Ins.Get_Data_orNull(skillExtraType);
m_SkillListTableData = new SkillListTableData
{
e_SkillExtraType = skillExtraType,
f_ExtraValue1 = val1,
f_ExtraValue2 = val2,
2025-02-20 01:00:59 +00:00
f_ExtraValue4 = ccRate
};
}
2024-12-15 01:39:39 +00:00
}
public class ProjectileBase : MonoBehaviour
{
2025-02-21 23:47:07 +00:00
[Header("충돌 레이어")]
public string ColliderLayer = "Actor";
[Header("관통 여부")]
2024-12-15 01:39:39 +00:00
public bool m_Pierce;
[Header("투사체 타격 시 나올 이펙트(맞은 대상)")]
2024-12-15 01:39:39 +00:00
public string str_HitEffect;
[Header("투사체 타격 시 나올 이펙트(현재 위치)")]
public string str_HitEffect_CurPos;
[Header("시간이 0이 됐을 때 이펙트 표시 여부")]
public bool m_ShowTimeOverEffect = true;
protected bool bFirstLoad = true, isProjectiledata = false, isHitEffect, isHitEffectCurPos;
2025-02-09 06:50:27 +00:00
ProjectileData _projectileData;
protected ProjectileData m_ProjecTileData
{
get { return _projectileData; }
set { _projectileData = value; isProjectiledata = !DSUtil.CheckNull(value); }
}
2024-12-15 01:39:39 +00:00
protected float m_LifeTime;
protected Vector3 v3_scale;
protected Action<double> act_returnDmg;
protected Action<Actor> act_afterFreezing;
DamageInfo m_DamageInfo;
private void Awake()
{
v3_scale = transform.localScale;
isHitEffect = !string.IsNullOrEmpty(str_HitEffect);
isHitEffectCurPos = !string.IsNullOrEmpty(str_HitEffect_CurPos);
}
2024-12-15 01:39:39 +00:00
private void OnEnable()
{
if (bFirstLoad)
{
2025-02-09 06:50:27 +00:00
m_ProjecTileData = new ProjectileData();
2024-12-15 01:39:39 +00:00
Off_FisrLoad();
transform.position = Vector3.one * 100000f;
Off(true);
}
}
2025-05-09 04:27:04 +00:00
public virtual void Off_FisrLoad() { bFirstLoad = false; }
2024-12-15 01:39:39 +00:00
public virtual void Set(ProjectileData _data)
{
2025-02-19 04:14:09 +00:00
_data.CC_AddTime = _data.CC_AddDmg = _data.CC_AddVal1 = _data.CC_AddVal2 = 0f;
2025-02-09 06:50:27 +00:00
_data.Copy(m_ProjecTileData);
m_ProjecTileData.m_ProjectileBase = this;
m_DamageInfo = Get_NewDamageInfo();
2024-12-15 01:39:39 +00:00
var isNullTarget = DSUtil.CheckNull(m_ProjecTileData.target);
2024-12-28 00:20:09 +00:00
if (m_ProjecTileData.IsSkill())
2024-12-15 01:39:39 +00:00
{
var skillData = m_ProjecTileData.m_SkillListTableData;
if (m_ProjecTileData.SetSkillExtraType)
m_ProjecTileData.e_SkillExtraType = skillData.e_SkillExtraType;
2024-12-15 01:39:39 +00:00
}
else
{
transform.localScale = v3_scale;
var statinfo = m_ProjecTileData.shooter.Get_StatInfo();
2024-12-15 01:39:39 +00:00
if (!DSUtil.CheckNull(statinfo))
{
m_ProjecTileData.Speed += (float)statinfo.Get_Stat(eStat.ProjectileSpeed_Up);
2024-12-15 01:39:39 +00:00
transform.localScale += v3_scale * (float)statinfo.Get_Stat(eStat.ProjectileSize_Up);
}
}
WL 리뉴얼 세션 2026-09-06~07 (#760~#800) — 전투·배경·UI·타격감 (조직 PD 로그 #746~#800 · 대화로그 §14~§24) - 전투: Knight@Attack1~3_S 3콤보(4 컨트롤러·클래스별 서브클립) · 타겟팅 4규칙(정면 우선·재타겟·즉시 공격·어그로 금지 · WLTargetingSettings) · 대쉬 후 공격(Stander@Chase_Start · DashDriver · 5 m · 사정거리+0.8 · 근거리 적 우선) · 공격 이동 FrameTable(발 접지 실측 표 · AttackRootMotion) · 충돌 반경/투사체 0.3 배(WLCollisionTuning) · 무적(임시)·펫 금지(WLGameplaySettings) - 검기: NamuFX Slash_B 배리언트 Effect_WLSwingArc 원 피팅 정합 배치 + 캘리브레이션(SlashArcMeasure · SlashTrailSettings) · 찌르기 Effect_WLStab 대기 · 램프 리본(BladeTrail · WL_BladeRibbon.shader · T_WL_BladeRibbonRamp) 보존(drawRibbon 0) - 타격감: Assets/WL/Feel(WLHitFeel · 히트스톱 0.03 · 셰이크 0.10 m · 몹 펀치 1.12 · Actor.Get_Damage 훅 1줄 · 원본 RealCamera 셰이크 결함 대체) - 배경/맵: LMHPOLY Demo_01~10 → WL_Nature01~10(프리팹·씬·NavMesh·스포너·BattleMapConfig) · 물(ToonWaterU) · 포스트 블룸 0.9/0.3 · 잔디(BruteForce·드레싱) 제거 · 마젠타 머티리얼 URP 변환 - UI: 세로 HUD(WL_HUD · 하단 5메뉴 폭 전체 · 채팅/전투 패드 숨김 · WLIngameUiOverride) · Title/TitleInfo 1080×1920 Expand + 배경 높이 fit(WLBackgroundFit) · 로딩 SortOrder_5(WLRawImageAspectSync · 초점표 8장) · Loading1~8 ASTC 6×6 - 도구: AgentScripts/*(LightProbe · WL_MapSwitch · WL760~WL800 프로브/집행/검증 · 상단 사용법 주석) · 에디터 락 프로토콜 파일(staging) - 제외(별도 커밋 예정): Assets/LMHPOLY(703 MB) · Assets/Feel(422 MB) · Assets/Shinabro(300 MB) — 에셋 스토어/구 WL 팩 원본 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 23:24:25 +00:00
// #769 — 몬스터 투사체 크기 배율(설정 에셋 · C45). 플레이어·펫 투사체는 배율 1 로 무변경.
// ProjectileSize_Up 을 더한 "최종 크기"에 곱한다(= 화면에 보이는 최종 크기가 지시대로 줄어든다).
// 스킬 분기는 localScale 을 v3_scale 로 되돌리지 않으므로, 풀 재사용 시 누적되지 않게 원본 스케일을 기준으로 잡는다.
{
float wlScale = WL.Settings.WLCollisionTuning.ProjectileScale(m_ProjecTileData.shooter, gameObject);
if (wlScale != 1f)
transform.localScale = (m_ProjecTileData.IsSkill() ? v3_scale : transform.localScale) * wlScale;
}
m_ProjecTileData.m_skillTypeConfigTable = table_skilltypeconfig.Ins.Get_Data_orNull(m_ProjecTileData.e_SkillExtraType);
if (!isNullTarget && !DSUtil.CheckNull(m_ProjecTileData.m_skillTypeConfigTable) &&
m_ProjecTileData.m_skillTypeConfigTable.e_SkillExtraTiming == eSkillExtraTiming.Start)
m_ProjecTileData.target.Check_Extra(m_DamageInfo);
2024-12-15 01:39:39 +00:00
if (m_ProjecTileData.CheckOptionWhenStart)
2024-12-15 01:39:39 +00:00
{
m_ProjecTileData.CheckOptionWhenStart = false;
m_ProjecTileData.shooter.Check_EnchantOption(m_DamageInfo, false);
2024-12-15 01:39:39 +00:00
}
Set_Checkers();
m_LifeTime = _data.LifeTime;
gameObject.SetActive(true);
switch (_data.eStartPos)
{
case eProjectileStartPos.Shooter: transform.position = _data.shooter.Get_CenterPositionFoward(); break;
case eProjectileStartPos.ShooterCenter: transform.position = _data.shooter.Get_CenterPositionFoward(); break;
default: transform.position = _data.target.Get_CenterPositionFoward(); break;
case eProjectileStartPos.TargetCenter: transform.position = _data.target.Get_CenterPositionFoward(); break;
2024-12-15 01:39:39 +00:00
case eProjectileStartPos.Custom: transform.position = _data.v3_StartPos; break;
}
2024-12-28 00:20:09 +00:00
if (!isNullTarget)
2024-12-15 01:39:39 +00:00
{
if (_data.LookTarget)
{
switch (_data.eStartPos)
{
case eProjectileStartPos.Shooter:
case eProjectileStartPos.Target:
transform.LookAt(_data.target.Get_position());
break;
default:
Vector3 targetPosition = _data.target.Get_Center_position();
targetPosition.y = _data.shooter.Get_Center_position().y;
transform.LookAt(targetPosition);
break;
}
}
}
2025-02-21 03:21:31 +00:00
else if (_data.LookTarget && !DSUtil.CheckNull(_data.shooter))
2024-12-15 01:39:39 +00:00
transform.eulerAngles = _data.shooter.transform.eulerAngles;
}
2025-01-18 04:56:33 +00:00
public virtual void Launch(Vector3 start, Vector3 end, float wavePhase, float waveAmplitude, float waveFrequency) { }
2024-12-15 01:39:39 +00:00
protected void LookAt_ShooterFoward()
{
transform.rotation = m_ProjecTileData.shooter.transform.rotation;
transform.eulerAngles = new Vector3(0f, transform.eulerAngles.y);
}
2025-05-04 00:44:24 +00:00
protected void LookAt_Target()
{
if (!DSUtil.CheckNull(m_ProjecTileData.target))
{
var mypos = m_ProjecTileData.shooter.Get_position();
var targetpos = m_ProjecTileData.target.Get_position();
Vector3 direction = targetpos - mypos;
direction.y = 0f; // 수직 방향 제거 (Y축은 회전하지 않음)
if (direction != Vector3.zero)
{
Quaternion lookRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Euler(0f, lookRotation.eulerAngles.y, 0f); // Y축만 회전
}
}
}
2024-12-15 01:39:39 +00:00
/// <summary>
/// 쿨타임을 감소시킨다. f_ExtraValue1 값을 사용한다.
/// </summary>
protected void Set_ReduceCoolTime_byStep(int step)
{
if (IsStep(step))
m_ProjecTileData.shooter.Set_SkillCoolTime(false, m_ProjecTileData.m_SkillListTableData.n_SkillID,
2024-12-15 01:39:39 +00:00
Get_AwakenData(step, 1));
}
/// <summary>
/// active 스킬 실행 여부
/// </summary>
public void Show_Effect(Actor target, float effectLifeTime = 5f, Action<TurnOff_GO> cceffect = null)
2024-12-15 01:39:39 +00:00
{
InGameInfo.Ins.Show_SkillTypeEffect(m_ProjecTileData, target, effectLifeTime, cceffect);
2024-12-15 01:39:39 +00:00
}
2025-02-09 06:50:27 +00:00
public virtual void Set_Shooter(Actor _shoter) { if (isProjectiledata) m_ProjecTileData.shooter = _shoter; }
2024-12-15 01:39:39 +00:00
protected void Check_TargetBoss()
{
2025-02-09 06:50:27 +00:00
if (isProjectiledata)
2024-12-15 01:39:39 +00:00
{
if (!m_ProjecTileData.target.IsSubRole(eSubRol.Boss) || m_ProjecTileData.target.transform.localScale.x <= 2f)
2024-12-15 01:39:39 +00:00
{
var enemies = Get_Enemies(transform, 8f);
var boss = enemies.Find(f => f.IsSubRole(eSubRol.Boss) || f.transform.localScale.x > 2f);
2024-12-15 01:39:39 +00:00
if (boss != null)
m_ProjecTileData.target = boss;
2024-12-15 01:39:39 +00:00
}
}
}
public ProjectileData Get_ProjectTileData() { return m_ProjecTileData; }
2024-12-15 01:39:39 +00:00
DamageInfo Get_SkillDamage()
{
2025-02-19 04:14:09 +00:00
m_ProjecTileData.AddDmgPercent = m_ProjecTileData.Get_SkillDamagePercent();
var dinfo = m_ProjecTileData.shooter.Get_DamageInfo(m_ProjecTileData,
m_ProjecTileData.CC_AddVal2 > 0 && m_ProjecTileData.m_SkillListTableData.e_Skill == eEffect.Skill_IceBolt &&
m_ProjecTileData.target.IsSkillExtraStatus(eSkillExtraType.Frost));
2024-12-15 01:39:39 +00:00
dinfo.act_returnLastDmg = act_returnDmg;
dinfo.act_AfterFreezing = act_afterFreezing;
return dinfo;
}
protected DamageInfo Get_NewDamageInfo()
{
return m_ProjecTileData.IsSkill() ? Get_SkillDamage() : m_ProjecTileData.shooter.Get_DamageInfo(m_ProjecTileData);
}
2024-12-17 01:48:30 +00:00
protected DamageInfo Get_DamageInfo(bool extradmg = false, bool calcri = true)
{
m_DamageInfo.Damage = m_DamageInfo.NoCriDmg;
2024-12-17 01:48:30 +00:00
m_DamageInfo.bExtraDmg = extradmg;
if (calcri) m_DamageInfo.Cal_Cri(m_ProjecTileData.shooter.m_AttackType, m_ProjecTileData.shooter.Get_StatInfo());
2024-12-17 01:48:30 +00:00
return m_DamageInfo;
}
2024-12-15 01:39:39 +00:00
protected bool IsStep(int _step)
{
var sdata = m_ProjecTileData.shooter.Get_ServerData();
2024-12-15 01:39:39 +00:00
if (!DSUtil.CheckNull(sdata))
{
if (m_ProjecTileData.shooter.IsRole(eRole.PC))
return sdata.Get_SkillAwakenLv(m_ProjecTileData.m_SkillListTableData.n_SkillID) >= _step;
2024-12-15 01:39:39 +00:00
else
return sdata.Get_PetSkillAwakenLv(m_ProjecTileData.shooter.Get_ID()) >= _step;
2024-12-15 01:39:39 +00:00
}
return false;
}
protected Actor Get_NearstEnemy(float dist = 20f)
{ return ActorInfo.Ins.Get_Nearest_EnemyActor_orNull(m_ProjecTileData.shooter.IsEnemy(), transform.position, dist); }
2024-12-15 01:39:39 +00:00
protected List<Actor> Get_Enemies()
{ return ActorInfo.Ins.Get_EnemyActors(m_ProjecTileData.shooter.IsEnemy(), transform.position); }
2024-12-15 01:39:39 +00:00
protected List<Actor> Get_Enemies(Transform tf, float dist)
2024-12-28 00:20:09 +00:00
{
#if UNITY_EDITOR
if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "StatTest")
return new List<Actor> { MainToStatTest.Ins.actors[1] };
#endif
return ActorInfo.Ins.Get_EnemyActors(m_ProjecTileData.shooter.IsEnemy(), tf.position, dist);
2024-12-28 00:20:09 +00:00
}
2024-12-15 01:39:39 +00:00
protected void Show_HitEffect(bool effectbyHit, Actor target)
{
if (isProjectiledata)
{
if (isHitEffect) InGameInfo.Ins.Show_Effect(str_HitEffect, Get_HitEffectPos(effectbyHit, target));
if (isHitEffectCurPos) InGameInfo.Ins.Show_Effect(str_HitEffect_CurPos, transform.position);
}
2024-12-15 01:39:39 +00:00
}
Vector3 Get_HitEffectPos(bool effectbyHit, Actor target)
{
if (DSUtil.CheckNull(target)) effectbyHit = false;
return effectbyHit ? target.Get_Center_position() : transform.position;
}
protected virtual void Off(bool forceoff = false, bool showtimeovereffect = true)
2024-12-15 01:39:39 +00:00
{
if (forceoff || !m_Pierce) gameObject.SetActive(false);
if (!bFirstLoad && showtimeovereffect) Show_HitEffect(false, null);
2024-12-15 01:39:39 +00:00
}
2025-01-02 07:38:57 +00:00
protected IEnumerator Co_Off(float delay)
{
yield return new WaitForSeconds(delay);
Off(true, m_ShowTimeOverEffect);
2025-01-02 07:38:57 +00:00
}
2024-12-15 01:39:39 +00:00
/// <summary>
/// 포물선 움직임
/// </summary>
/// <param name="journeyTime">시작위치에서 종료위치까지 도달하는 시간, 값이 높을수록 느리게 간다.</param>
/// <param name="reduceHeight">Center값을 줄이기, 해당 값이 높을수록 포물선의 높이는 낮아진다.</param>
/// <returns></returns>
protected IEnumerator Co_Move_Split(Action _actreach, Vector3 startpos, Vector3 targetpos, float journeyTime = 1.0f, float reduceHeight = 0.25f)
{
float startTime = Time.time;
while (true)
{
Vector3 center = (startpos + targetpos) * 0.5f; //Center 값만큼 위로 올라간다.
center -= new Vector3(0, 1f * reduceHeight, 0); //y값을 높이면 높이가 낮아진다.
Vector3 riseRelCenter = startpos - center;
Vector3 setRelCenter = targetpos - center;
float fracComplete = (Time.time - startTime) / journeyTime;
transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, fracComplete);
transform.position += center;
if (fracComplete >= 1f)
{
_actreach?.Invoke();
break;
}
yield return null;
}
}
protected IEnumerator Co_Move_Strait(eProjectileStrait direction)
{
while (m_ProjecTileData.LifeTime > 0f)
2024-12-15 01:39:39 +00:00
{
if (DSUtil.CheckNull(m_ProjecTileData.shooter)) break;
2024-12-15 01:39:39 +00:00
if (direction == eProjectileStrait.Forward)
transform.Translate(m_ProjecTileData.Speed * Time.deltaTime * Vector3.forward);
2024-12-15 01:39:39 +00:00
else
transform.Translate(m_ProjecTileData.Speed * Time.deltaTime * Vector3.down);
2024-12-15 01:39:39 +00:00
m_ProjecTileData.LifeTime -= Time.deltaTime;
2024-12-15 01:39:39 +00:00
yield return null;
}
Off(true);
}
protected virtual void OnTriggerEnter(Collider other) { ProcessCollider(other); }
protected virtual void OnCollisionEnter(Collision collision) { ProcessCollider(collision.collider); }
2025-01-18 23:21:18 +00:00
public virtual bool ProcessCollider(Collider other, bool Off_byHit = true, bool noDmg = false)
2024-12-15 01:39:39 +00:00
{
2025-02-09 06:50:27 +00:00
int targetLayer = other.gameObject.layer;
2025-02-21 23:47:07 +00:00
if (isProjectiledata && targetLayer == LayerMask.NameToLayer(ColliderLayer))
2024-12-15 01:39:39 +00:00
{
2025-02-09 06:50:27 +00:00
// 캐싱된 GetComponent 호출
if (!other.TryGetComponent<Actor>(out var hitter)) return false;
if (m_ProjecTileData.shooter.IsEnemy() != hitter.IsEnemy())
{
WL.Combat.Core.CombatEvents.RaiseHitboxHit(this, m_ProjecTileData, hitter, noDmg);
2025-02-09 06:50:27 +00:00
if (!noDmg) hitter.Get_Damage(Get_DamageInfo());
m_ProjecTileData.Action_OnHit?.Invoke(hitter);
if (Off_byHit) Off(false, false);
Show_HitEffect(true, hitter);
return true;
}
2024-12-15 01:39:39 +00:00
}
return false;
}
public void Set_Checkers()
{
var chekers = GetComponentsInChildren<ProjectileHitChecker>(true);
for (int i = 0; i < chekers.Length; i++)
chekers[i].Set(this);
}
public void Set_CheckersSize(float addsize)
{
var chekers = GetComponentsInChildren<ProjectileHitChecker>(true);
for (int i = 0; i < chekers.Length; i++)
chekers[i].Set_Size(addsize);
}
protected float Get_AwakenData(int step, int index)
{
var data = table_skillawakenconfig.Ins.Get_Data_orNull(m_ProjecTileData.m_SkillListTableData.n_SkillID, step);
2024-12-15 01:39:39 +00:00
if (DSUtil.CheckNull(data))
return 0f;
switch (index)
{
case 1: return data.f_ExtraValue1;
case 2: return data.f_ExtraValue2;
case 3: return data.f_ExtraValue3;
default: return 0f;
}
}
protected int Get_FairyCount(eEffect _effect)
{
return m_ProjecTileData.shooter.Get_SelectSkill(_effect) ? 4 : 1;
2024-12-15 01:39:39 +00:00
}
#if UNITY_EDITOR
protected void Add_AwakendLv(int lv)
{
if (m_ProjecTileData.shooter.IsRole(eRole.PC))
2024-12-15 01:39:39 +00:00
for (int i = 0; i < lv; i++)
m_ProjecTileData.shooter.Get_ServerData().Add_SkillAwakenLv(m_ProjecTileData.m_SkillListTableData.n_SkillID);
else if (m_ProjecTileData.shooter.IsRole(eRole.Pet))
m_ProjecTileData.shooter.Get_ServerData().Add_PetLv(m_ProjecTileData.shooter.Get_ID(), lv * 15);
2024-12-15 01:39:39 +00:00
}
#endif
}