OneShotOneKill/Assets/Script/InGame/Mgr/ProjectileBase.cs

142 lines
5.0 KiB
C#
Raw Normal View History

2026-01-07 21:27:42 +00:00
using System;
using System.Collections;
using UnityEngine;
public class ProjectileBase : MonoBehaviour
{
ProjectileTableData m_TableData;
Vector3 offset = new Vector3(0f, 0f);
float m_Speed;
private void Awake()
{
//GetComponent<SpriteRenderer>().sortingOrder = 10;
var particles = GetComponentsInChildren<ParticleSystem>();
for (int i = 0; i < particles.Length; i++)
{
var main = particles[i].main;
main.scalingMode = ParticleSystemScalingMode.Hierarchy;
var rend = particles[i].GetComponent<ParticleSystemRenderer>();
if (rend != null)
rend.sortingOrder += 10; // 기존 값에서 +10
}
}
public void Set(ProjectileData pdata, Vector3 start, Vector3 end, Actor target, Action<Actor> act_end)
{
gameObject.SetActive(true);
m_Speed = pdata.m_Speed;
if (m_Speed <= 0f) m_Speed = 15f; // 이펙트 툴용
transform.eulerAngles = Vector3.zero;
offset = new Vector3(m_TableData.f_PositionX, m_TableData.f_PositionY);
end += offset;
if (m_TableData.b_FilpX && transform.localScale.x > 0f)
transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
if (pdata.e_AttackType == eAttackType.Melee)
{ // 즉시 공격
StartCoroutine(Co_Melee(end, target, act_end));
}
else
{ // 투사체 이동
StartCoroutine(Co_Update(start, end, target, act_end));
}
}
IEnumerator Co_Melee(Vector3 end, Actor target, Action<Actor> act_end)
{
transform.position = end;
if (m_TableData != null && !string.IsNullOrEmpty(m_TableData.s_Effect))
{
var delay = table_effect.Ins.Get_Data(m_TableData.s_Effect).f_EffectDelay;
yield return new WaitForSeconds(delay);
EffectMgr.Ins.Show_Effect(m_TableData.s_Effect, transform.position);
}
act_end?.Invoke(target);
yield return new WaitForSeconds(1f);
gameObject.SetActive(false);
}
IEnumerator Co_Update(Vector3 start, Vector3 end, Actor target, Action<Actor> act_end)
{
bool isTarget = target;
transform.position = start;
var ps = GetComponent<ParticleSystem>();
if (ps)
{
// Trail 완전 비활성화
var trails = ps.trails;
bool wasTrailOn = trails.enabled;
trails.enabled = false;
// 파티클 완전 정지 및 초기화
ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
ps.Clear(true);
foreach (var tr in GetComponentsInChildren<TrailRenderer>())
tr.Clear();
// 1프레임 대기 (렌더 버퍼 플러시)
yield return null;
// 파티클 리셋 + Trail 다시 켜기
ps.Simulate(0f, true, true, true);
if (wasTrailOn) trails.enabled = true;
ps.Play(true);
}
while (Vector3.Distance(transform.position, end) > 0.01f)
{
if (isTarget)
{
if (target.IsRole(eRole.Mob) && target.IsDead())
{
var mobindex = target.Get_MobIndex();
if (mobindex < 0) mobindex += 3; // 라인 교체로 내려갔을 수도 있으므로 기존 위치로 잡음
var nexttarget = InGameInfo.Ins.Get_Enemy_orNull(eRole.PC, mobindex + 3);
var nexttarget2 = InGameInfo.Ins.Get_Enemy_orNull(eRole.PC, mobindex + 6);
if (nexttarget && !nexttarget.IsDead())
target = nexttarget;
else if (nexttarget2 && !nexttarget2.IsDead())
target = nexttarget2;
}
end = target.Get_World_Position() + offset;
}
transform.LookAt(end);
transform.position = Vector3.MoveTowards(
transform.position,
end,
m_Speed * Time.deltaTime
);
yield return null;
}
if (m_TableData != null && !string.IsNullOrEmpty(m_TableData.s_Effect))
{
var delay = table_effect.Ins.Get_Data(m_TableData.s_Effect).f_EffectDelay;
yield return new WaitForSeconds(delay);
EffectMgr.Ins.Show_Effect(m_TableData.s_Effect, transform.position);
}
act_end?.Invoke(target);
gameObject.SetActive(false);
}
public void Off_AfterOneShot(ProjectileTableData tdata)
{
m_TableData = tdata;
Set_Scale(tdata.f_Scale);
if (gameObject.activeInHierarchy)
StartCoroutine(Co_Off());
}
public ProjectileTableData Get_Data() { return m_TableData; }
public void Set_Scale(float scale) { transform.localScale = Vector3.one * scale; }
IEnumerator Co_Off()
{
yield return new WaitForSeconds(1f);
gameObject.SetActive(false);
}
}