Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Collection/Projectile.cs
SoulliesOfficial 39b43680a9 爆更
2026-07-18 03:16:20 -04:00

135 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;
// 投射物在发射后独立于发射者的局部冻结,但仍受全局和阵营群体时间效果影响。
protected override CreatorTimePolicy DefaultTimePolicy => CreatorTimePolicy.CreatorWithoutLocalTime;
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;
}
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, newSpeed);
this.creator = newCreator;
targetFractions = new List<Fraction> { originalCreator.fraction };
}
}
}