using Cielonos.MainGame.Characters; using SLSUtilities.General; using UnityEngine; namespace Cielonos.MainGame { public class ForceSubmodule : AttackAreaSubmoduleBase { public bool isCustomForce => !isRepulsion && !isSuction; public Vector3 customForce; public bool isRepulsion, isSuction; public float strengthXZ; public float strengthY; public Vector3 finalForce; public bool isDynamicForce; public float dynamicStrength; public bool isLaunch; // 是否为无视抗性的击飞 public float stasisDuration; // 击中后的滞空时长(仅击飞有效) /// /// 施加自定义力 /// public ForceSubmodule(AttackAreaBase attackArea, float dynamicStrength) : base(attackArea) { this.isDynamicForce = true; this.isRepulsion = false; this.isSuction = false; this.dynamicStrength = dynamicStrength; } /// /// 施加自定义力 /// public ForceSubmodule(AttackAreaBase attackArea, Vector3 customForce) : base(attackArea) { this.isDynamicForce = false; this.customForce = customForce; this.isRepulsion = false; this.isSuction = false; } /// /// 施加斥力或吸力 /// public ForceSubmodule(AttackAreaBase attackArea, float strengthXZ, bool isRepulsion, float strengthY = 0) : base(attackArea) { this.isDynamicForce = false; this.strengthXZ = strengthXZ; this.isRepulsion = isRepulsion; this.isSuction = !isRepulsion; this.strengthY = strengthY; } public ForceSubmodule(AttackAreaBase attackArea, float strengthXZ, bool isRepulsion, bool isLaunch, float strengthY = 0, float stasisDuration = 0f) : base(attackArea) { this.isDynamicForce = false; this.strengthXZ = strengthXZ; this.isRepulsion = isRepulsion; this.isSuction = !isRepulsion; this.strengthY = strengthY; this.isLaunch = isLaunch; this.stasisDuration = stasisDuration; } public Vector3 GetFinalForce(CharacterBase target) { if (isRepulsion) { Vector3 repulsionDirection = (target.centerPoint.position - attackArea.topParent.position).Flatten().normalized; finalForce = repulsionDirection * strengthXZ + Vector3.up * strengthY; } else if (isSuction) { Vector3 suctionDirection = (attackArea.topParent.position - target.centerPoint.position).Flatten().normalized; finalForce = suctionDirection * strengthXZ + Vector3.up * strengthY; } else if(isDynamicForce) { Vector3 projectileDirection = attackArea.topParent.forward; finalForce = projectileDirection * dynamicStrength; } else { finalForce = customForce; } return finalForce; } public void ApplyForce(CharacterBase target) { Vector3 force = GetFinalForce(target); if (target.movementSc is AutomataLandMovementSubcontroller automataSc) { automataSc.ApplyHitImpact(force, isLaunch, isLaunch ? stasisDuration : 0f); } else { // 玩家或其他非自动单元处理 target.movementSc.additionalForceSm.AddForce(force, isLaunch); if(force.y > 0) target.movementSc.gravitationalMovement = Vector3.zero; } } } }