Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Collection/Projectile.cs
SoulliesOfficial 6d7ebc5825 Passion & UI
2026-06-12 17:11:39 -04:00

140 lines
5.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.Inventory;
using Lean.Pool;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class Projectile : AttackAreaBase
{
protected bool ignoreEnvironment = false;
protected int maximumPenetrateCount = 1;
protected int currentPenetrateCount = 0;
public virtual Projectile Initialize(CharacterBase creator, bool ignoreEnvironment, int penetrateCount = 1, params Fraction[] targetFractions)
{
return Initialize(creator, null, ignoreEnvironment, penetrateCount, targetFractions);
}
public virtual Projectile Initialize(CharacterBase creator, ItemBase itemSource,
bool ignoreEnvironment, int penetrateCount = 1, params Fraction[] targetFractions)
{
Projectile projectile = base.Initialize<Projectile>(creator, itemSource, targetFractions);
projectile.ignoreEnvironment = ignoreEnvironment;
projectile.maximumPenetrateCount = penetrateCount;
return projectile;
}
private void OnTriggerStay(Collider other)
{
if (raycastSm != null)
{
HitCharacter(other, default);
HitEnvironment(other, default);
}
}
public override void HitCharacter(Collider characterCollider, Vector3 hitPosition)
{
// 既不在伤害阶段也不在反应窗口,直接跳过
if (!isEnabling && !isReactionActive)
{
return;
}
CharacterBase targetCharacter = characterCollider.GetComponentInParent<CharacterBase>();
if (!IsValidTarget(targetCharacter)) return;
// 已在 grace window 期间成功反应的目标不再处理
if (reactedTargets.Contains(targetCharacter.gameObject))
{
return;
}
if (hitSm.checkedObjects.Contains(targetCharacter.gameObject))
{
return;
}
// 仅在反应窗口内enable 阶段之前或之后),只做反应检测
if (!isEnabling && isReactionActive)
{
HitOnTarget(characterCollider, hitPosition, out Attack.Result graceResult, onlyCheckReaction: true);
if (graceResult.isBlocked || graceResult.isDodged)
{
reactedTargets.Add(targetCharacter.gameObject);
hitSm.AddCheckedObject(targetCharacter.gameObject);
}
return;
}
// 正常 enable 阶段:造成伤害
hitSm.AddCheckedObject(targetCharacter.gameObject);
HitOnTarget(characterCollider, hitPosition, out _);
}
public override void HitEnvironment(Collider other, Vector3 hitPosition)
{
if (ignoreEnvironment)
{
return;
}
if (other.gameObject.layer == LayerMask.NameToLayer("Default") ||
other.gameObject.layer == LayerMask.NameToLayer("Ground") ||
other.gameObject.layer == LayerMask.NameToLayer("Wall") ||
other.gameObject.layer == LayerMask.NameToLayer("FadableEnvironment") ||
other.gameObject.layer == LayerMask.NameToLayer("UnfadableEnvironment"))
{
//特效
GenerateHitEffect(hitPosition);
//音效
PlaySoundFX(hitPosition);
LeanPool.Despawn(topParent.gameObject);
}
}
}
public partial class Projectile
{
protected override void HitOnTarget(Collider hitCollider, Vector3 hitPosition, out Attack.Result result,
bool onlyCheckReaction = false)
{
base.HitOnTarget(hitCollider, hitPosition, out result, onlyCheckReaction);
if (onlyCheckReaction) return;
if (!result.isReflected && ++currentPenetrateCount >= maximumPenetrateCount)
{
LeanPool.Despawn(topParent.gameObject);
}
}
public void Explode(Vector3 hitPosition = default)
{
if (hitPosition == default)
{
hitPosition = transform.position;
}
GenerateHitEffect(hitPosition);
PlaySoundFX(hitPosition);
LeanPool.Despawn(topParent.gameObject);
}
}
public partial class Projectile
{
public void Reflect(CharacterBase newCreator, Vector3 newDirection = default, float newSpeed = 50f)
{
CharacterBase originalCreator = creator;
newDirection = newDirection == default ? (originalCreator.CenterPosition - transform.position).normalized : newDirection;
SetLinearDirectionMoveModule<Projectile>(newDirection, 50f);
this.creator = newCreator;
targetFractions = new List<Fraction> { originalCreator.fraction };
}
}
}