/// <summary>
/// 攻击策略
/// </summary>
public abstract class AttackStrategy
{
/// <summary>
/// 攻击
/// </summary>
/// <param name="attackTarget">攻击目标</param>
/// <returns>给攻击目标造成的伤害</returns>
public abstract float Attack(Transform attacker, Transform attackTarget);
}
/// <summary>
/// 扇形攻击策略
/// </summary>
public class SectorAttackStrategy : AttackStrategy
{
//半径
private float skillRadius;
//角度
private float skillAngle;
//技能释放方向
private Vector3 skillDir;
//最大伤害
private float maxDamage;
public SectorAttackStrategy(float skillRadius, float skillAngle, Vector2 skillDir,float maxDamage)
{
this.skillRadius = skillRadius;
this.skillAngle = skillAngle;
this.skillDir = skillDir;
this.maxDamage = maxDamage;
}
public override float Attack(Transform attacker,Transform attackTarget)
{
//计算攻击者指向被攻击者的方向向量
Vector3 direction = attackTarget.position - attacker.position;
//计算两者距离
float distance = direction.magnitude;
//如果与敌人的距离超越技能半径
if (distance > skillRadius)
return 0;
//计算敌人与玩家的方向与技能方向的夹角
float enemyAngle = Vector3.Angle(direction, skillDir);
//攻击目标不再扇形范围内
if (enemyAngle > skillAngle / 2)
return 0;
//返回伤害【越近伤害越高】
return (skillRadius - distance)/skillRadius * maxDamage;
}
}
/// <summary>
/// 圆形攻击策略
/// </summary>
public class CircleAttackStrategy : AttackStrategy
{
//技能位置
private Vector3 skillPosition;
//技能半径
private float skillRadius;
//高伤害半径
private float maxDamageRadius;
//内层的最大伤害
private float maxDamage;
//外层的最校伤害
private float minDamage;
public CircleAttackStrategy(Vector3 skillPosition, float skillRadius,float maxDamageRadius, float maxDamage, float minDamage)
{
this.skillPosition = skillPosition;
this.skillRadius = skillRadius;
this.maxDamageRadius = maxDamageRadius;
this.maxDamage = maxDamage;
this.minDamage = minDamage;
}
public override float Attack(Transform attacker, Transform attackTarget)
{
//攻击目标与技能圆心的距离
float distance = Vector3.Distance(skillPosition, attackTarget.position);
//不在攻击范围内
if (distance > skillRadius)
return 0;
//在高伤害圈内
if (distance < maxDamageRadius)
return maxDamage;
//在低伤害环内
return minDamage;
}
}
/// <summary>
/// 矩形攻击策略
/// </summary>
public class RectangleAttackStrategy : AttackStrategy
{
private float distance;
private float length;
private float width;
private float damage;
public RectangleAttackStrategy(float distance, float length, float width,float damage)
{
this.distance = distance;
this.length = length;
this.width = width;
this.damage = damage;
}
public override float Attack(Transform attacker, Transform attackTarget)
{
//计算技能中心的坐标
Vector3 skillCenter = attacker.forward * distance + attacker.position;
//技能中心点指向目标的方向向量
Vector3 dir = attackTarget.position - skillCenter;
//求这个方向向量在角色水平和垂直方向的投影向量
Vector3 rightProjection = Vector3.Project(dir, attacker.right);
Vector3 forwardProjection = Vector3.Project(dir, attacker.forward);
//判断长度【不在矩形范围内】
if (rightProjection.magnitude > length / 2
|| forwardProjection.magnitude > width / 2)
return 0;
//在范围内
return damage;
}
}
public class Hero
{
private Transform _transform;
public Transform Transform
{
get => _transform;
set => _transform = value;
}
public Hero(Transform transform)
{
_transform = transform;
}
public void Attack(Hero target,AttackStrategy attackStrategy)
{
float damage = attackStrategy.Attack(_transform, target._transform);
if (damage == 0)
{
Debug.Log("敌人未受到技能伤害...");
}
else
{
Debug.Log("敌人受到了" + damage + "点伤害");
}
}
}
|