Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Collection/Projectile.cs
SoulliesOfficial 50ee502684 完善
2026-02-13 09:22:11 -05:00

124 lines
4.4 KiB
C#

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)
{
return;
}
Debug.Log("Projectile HitCharacter: " + characterCollider.name);
CharacterBase targetCharacter = characterCollider.GetComponentInParent<CharacterBase>();
if (targetCharacter == creator) return;
if (targetCharacter != null) // && targetCharacter.HasAnyTag(targetTagList))
{
if (hitSm.checkedObjects.Contains(targetCharacter.gameObject))
{
return;
}
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 AttackResult attackResult)
{
base.HitOnTarget(hitCollider, hitPosition, out attackResult);
if (!attackResult.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 };
}
}
}