根据提供的code differences信息,由于没有具体的代码变更内容,我将生成一个通用的commit message模板:
``` docs(readme): 更新文档说明 - 添加项目使用指南 - 完善API接口说明 - 修正错误的配置示例 ```
This commit is contained in:
1 parent
a74d1e62d7
commit
8d58c2223c
167 files changed
+1119
-15679
No files matched your search
@@ -0,0 +1,52 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class ArcherHunterSkill : UnitSkill
|
||||
{
|
||||
[Min(0f)]
|
||||
public float splitShotRadius = 3f;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
GameObject mainTarget = unit.Target;
|
||||
if (mainTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject nearbyOpponent = FindNearbyOpponent(mainTarget);
|
||||
unit.FireSkillProjectile(nearbyOpponent != null ? nearbyOpponent : mainTarget);
|
||||
}
|
||||
|
||||
private GameObject FindNearbyOpponent(GameObject mainTarget)
|
||||
{
|
||||
UnitTeam myTeam = unit.GetComponent<UnitTeam>();
|
||||
if (myTeam == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject nearbyOpponent = null;
|
||||
float nearestSqrDistance = splitShotRadius * splitShotRadius;
|
||||
foreach (UnitTeam opponentTeam in GameObject.FindObjectsOfType<UnitTeam>())
|
||||
{
|
||||
GameObject opponent = opponentTeam.gameObject;
|
||||
if (opponent == null
|
||||
|| opponent == mainTarget
|
||||
|| opponent == unit.gameObject
|
||||
|| opponent.transform.root == unit.transform.root
|
||||
|| !myTeam.IsEnemy(opponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float sqrDistance = (opponent.transform.position - mainTarget.transform.position).sqrMagnitude;
|
||||
if (sqrDistance <= nearestSqrDistance)
|
||||
{
|
||||
nearestSqrDistance = sqrDistance;
|
||||
nearbyOpponent = opponent;
|
||||
}
|
||||
}
|
||||
|
||||
return nearbyOpponent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: CXMasCypUn3kQGV7OBQKx0Mrc9FoG/uoHgJ6krDLXW6ZDWy/4d5TDyk=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
public class ArcherSkill : UnitSkill
|
||||
{
|
||||
[Min(1)]
|
||||
public int volleyArrowCount = 3;
|
||||
|
||||
[Min(0f)]
|
||||
public float volleyArrowDamageMultiplier = 0.7f;
|
||||
|
||||
[Min(0f)]
|
||||
public float volleyArrowInterval = 0.15f;
|
||||
|
||||
private Coroutine volleyCoroutine;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
if (volleyCoroutine != null)
|
||||
{
|
||||
StopCoroutine(volleyCoroutine);
|
||||
}
|
||||
|
||||
volleyCoroutine = StartCoroutine(FireVolley());
|
||||
}
|
||||
|
||||
private IEnumerator FireVolley()
|
||||
{
|
||||
for (int i = 0; i < volleyArrowCount; i++)
|
||||
{
|
||||
// 三连射优先攻击当前目标;目标阵亡后剩余箭矢改打最近敌人。
|
||||
GameObject volleyTarget = unit.Target != null ? unit.Target : FindNearestOpponent();
|
||||
if (volleyTarget == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
unit.FireSkillProjectile(volleyTarget, volleyArrowDamageMultiplier);
|
||||
yield return new WaitForSeconds(volleyArrowInterval);
|
||||
}
|
||||
|
||||
volleyCoroutine = null;
|
||||
}
|
||||
|
||||
private GameObject FindNearestOpponent()
|
||||
{
|
||||
return unit.FindNearestEnemyForSkill();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: XnwW5yykAS0U9mQKwrOcVteeHFnga3JX/QTPS3VU+tZRWJtTrUUK2x4=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class BlueMonsterSkill : UnitSkill
|
||||
{
|
||||
[Min(0f)]
|
||||
public float attackSpeedIncrease = 0.2f;
|
||||
|
||||
[Min(1f)]
|
||||
public float attackSpeedLimit = 2f;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
unit.PlaySkillAnimation(OnRoarFinished);
|
||||
}
|
||||
|
||||
private void OnRoarFinished()
|
||||
{
|
||||
unit.MultiplyAttackSpeed(1f + attackSpeedIncrease, attackSpeedLimit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: C38c5nv/Vn2YC2O93bDcCWKF4BJ2qD0jF/dSHLsVrFDI+CkbTal6Ebk=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class CastleMageSkill : UnitSkill
|
||||
{
|
||||
[Header("小型魔爆参数")]
|
||||
[Min(0.1f)]
|
||||
public float explosionRadius = 1.8f;
|
||||
|
||||
[Min(0f)]
|
||||
public float explosionDamage = 85f;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
GameObject target = unit.Target;
|
||||
UnitTeam myTeam = unit.GetComponent<UnitTeam>();
|
||||
if (target == null || myTeam == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 center = target.transform.position;
|
||||
float radiusSquared = explosionRadius * explosionRadius;
|
||||
HashSet<UnitBase> hitUnits = new HashSet<UnitBase>();
|
||||
|
||||
foreach (UnitTeam opponentTeam in GameObject.FindObjectsOfType<UnitTeam>())
|
||||
{
|
||||
GameObject opponent = opponentTeam.gameObject;
|
||||
if (opponent == null
|
||||
|| opponent.transform.root == unit.transform.root
|
||||
|| !myTeam.IsEnemy(opponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 offset = opponent.transform.position - center;
|
||||
offset.y = 0f;
|
||||
if (offset.sqrMagnitude > radiusSquared)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UnitBase targetUnit = opponent.GetComponentInParent<UnitBase>();
|
||||
if (targetUnit != null && hitUnits.Add(targetUnit))
|
||||
{
|
||||
targetUnit.ReceiveDamage(explosionDamage, unit.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: W3IdsX/5W38NwZRl1j3lHmxfAjBoB+oex9RA+P0ZiHfo6idD8aLHRhg=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class EliteSoldierSkill : UnitSkill
|
||||
{
|
||||
[Header("蓄力重斩参数")]
|
||||
[Min(0f)]
|
||||
public float skillDamage = 125f;
|
||||
|
||||
[Min(0.1f)]
|
||||
public float skillRadius = 2.5f;
|
||||
|
||||
[Header("技能动画")]
|
||||
[Min(0f)]
|
||||
public float skillAnimationDuration = 2.22f;
|
||||
|
||||
private bool isSkillReady;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
if (unit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit.FaceCurrentTarget(0f);
|
||||
isSkillReady = true;
|
||||
unit.PlaySkillAnimation(OnSkillFinished, skillAnimationDuration);
|
||||
}
|
||||
|
||||
// 添加到蓄力重斩动画的命中帧。
|
||||
public void OnSkillHit1()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit.ApplyAreaSkillDamage(skillRadius, skillDamage, false);
|
||||
isSkillReady = false;
|
||||
}
|
||||
|
||||
private void OnSkillFinished()
|
||||
{
|
||||
isSkillReady = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: WnsWvCj+UC/pYq+AWRC8DmC4vGU3+wwjbpdBYlFWVzs1Nq39emaTJR4=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class HumanSoldierSkill : UnitSkill
|
||||
{
|
||||
[Min(0f)]
|
||||
public float bonusAttackMultiplier = 0.5f;
|
||||
|
||||
[Header("技能动画")]
|
||||
[Min(0f)]
|
||||
public float skillAnimationDuration = 0f;
|
||||
|
||||
private bool isSkillReady;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
isSkillReady = true;
|
||||
unit.PlaySkillAnimation(OnSkillFinished, skillAnimationDuration);
|
||||
}
|
||||
|
||||
// 添加到技能攻击动画的第一段命中帧。
|
||||
public void OnSkillHit1()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit.ApplySkillHit(1f, true);
|
||||
}
|
||||
|
||||
// 添加到技能攻击动画的第二段命中帧。
|
||||
public void OnSkillHit2()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit.ApplySkillHit(bonusAttackMultiplier, false);
|
||||
isSkillReady = false;
|
||||
}
|
||||
|
||||
private void OnSkillFinished()
|
||||
{
|
||||
isSkillReady = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: D34esyr4VikoxeCMkgYQYYnUE4qTpWwDd6Pg8VWal5uQ+g1+zaaApAc=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,160 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// 玩家技能系统(召唤师技能)
|
||||
/// 管理技能释放和冷却
|
||||
/// </summary>
|
||||
public class PlayerSkillSystem : MonoBehaviour
|
||||
{
|
||||
[Header("技能1:群体治疗")]
|
||||
public Button skill1Button;
|
||||
public Text skill1CooldownText;
|
||||
public float skill1Cooldown = 20f;
|
||||
public float skill1HealAmount = 100f;
|
||||
private float skill1RemainingCooldown = 0f;
|
||||
|
||||
[Header("技能2:全屏AOE")]
|
||||
public Button skill2Button;
|
||||
public Text skill2CooldownText;
|
||||
public float skill2Cooldown = 20f;
|
||||
public float skill2Damage = 80f;
|
||||
private float skill2RemainingCooldown = 0f;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 绑定按钮点击事件
|
||||
if (skill1Button != null)
|
||||
{
|
||||
skill1Button.onClick.AddListener(UseSkill1);
|
||||
}
|
||||
|
||||
if (skill2Button != null)
|
||||
{
|
||||
skill2Button.onClick.AddListener(UseSkill2);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// 更新技能1冷却
|
||||
if (skill1RemainingCooldown > 0)
|
||||
{
|
||||
skill1RemainingCooldown -= Time.deltaTime;
|
||||
if (skill1Button != null)
|
||||
{
|
||||
skill1Button.interactable = false;
|
||||
}
|
||||
if (skill1CooldownText != null)
|
||||
{
|
||||
skill1CooldownText.text = Mathf.CeilToInt(skill1RemainingCooldown).ToString();
|
||||
skill1CooldownText.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skill1Button != null)
|
||||
{
|
||||
skill1Button.interactable = true;
|
||||
}
|
||||
if (skill1CooldownText != null)
|
||||
{
|
||||
skill1CooldownText.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新技能2冷却
|
||||
if (skill2RemainingCooldown > 0)
|
||||
{
|
||||
skill2RemainingCooldown -= Time.deltaTime;
|
||||
if (skill2Button != null)
|
||||
{
|
||||
skill2Button.interactable = false;
|
||||
}
|
||||
if (skill2CooldownText != null)
|
||||
{
|
||||
skill2CooldownText.text = Mathf.CeilToInt(skill2RemainingCooldown).ToString();
|
||||
skill2CooldownText.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skill2Button != null)
|
||||
{
|
||||
skill2Button.interactable = true;
|
||||
}
|
||||
if (skill2CooldownText != null)
|
||||
{
|
||||
skill2CooldownText.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用技能1:群体治疗
|
||||
/// </summary>
|
||||
public void UseSkill1()
|
||||
{
|
||||
if (skill1RemainingCooldown > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"释放技能1:群体治疗(恢复 {skill1HealAmount} 生命)");
|
||||
|
||||
// 对所有友方单位施加治疗
|
||||
BuffSystem.Instance.ApplyGroupHeal(skill1HealAmount);
|
||||
|
||||
// 开始冷却
|
||||
skill1RemainingCooldown = skill1Cooldown;
|
||||
|
||||
// TODO: 播放技能特效
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用技能2:全屏AOE伤害
|
||||
/// </summary>
|
||||
public void UseSkill2()
|
||||
{
|
||||
if (skill2RemainingCooldown > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"释放技能2:全屏AOE(造成 {skill2Damage} 伤害)");
|
||||
|
||||
// 对所有敌方单位造成伤害
|
||||
var enemies = FindObjectsOfType<UnitBase>();
|
||||
int hitCount = 0;
|
||||
|
||||
foreach (var unit in enemies)
|
||||
{
|
||||
var team = unit.GetComponent<UnitTeam>();
|
||||
if (team != null && team.teamId == 1) // 敌方
|
||||
{
|
||||
var healthBar = unit.GetComponent<WorldHealthBar>();
|
||||
if (healthBar != null && !healthBar.IsDead)
|
||||
{
|
||||
healthBar.TakeDamage(skill2Damage);
|
||||
hitCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"全屏AOE命中 {hitCount} 个敌人");
|
||||
|
||||
// 开始冷却
|
||||
skill2RemainingCooldown = skill2Cooldown;
|
||||
|
||||
// TODO: 播放技能特效
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置所有技能冷却(测试用)
|
||||
/// </summary>
|
||||
public void ResetAllCooldowns()
|
||||
{
|
||||
skill1RemainingCooldown = 0f;
|
||||
skill2RemainingCooldown = 0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: CisbvXyoUn8k0PkPTbzEfXpqiXSMhTjkHc15rVEtnbXL0NUaW4VkyD8=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,62 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class ShieldGuardSkill : UnitSkill
|
||||
{
|
||||
[Header("盾牌参数")]
|
||||
[Min(1f)]
|
||||
public float shieldDurability = 220f;
|
||||
|
||||
[Min(0.1f)]
|
||||
public float shieldDuration = 4f;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
public float damageReduction = 0.35f;
|
||||
|
||||
public Vector3 shieldLocalPosition = new Vector3(0f, 1f, 0.7f);
|
||||
|
||||
public Vector3 shieldSize = new Vector3(1.5f, 1.8f, 0.12f);
|
||||
|
||||
private ShieldBarrier shield;
|
||||
|
||||
public ShieldBarrier ActiveShield => shield;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
EnsureShield();
|
||||
shield.Refresh(shieldDurability, shieldDuration, shieldLocalPosition, shieldSize);
|
||||
}
|
||||
|
||||
public override float ModifyIncomingDamage(float damage, GameObject attacker)
|
||||
{
|
||||
if (shield == null || !shield.IsActive)
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
if (shield.TryBlock(attacker, damage))
|
||||
{
|
||||
return damage * (1f - damageReduction);
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
private void EnsureShield()
|
||||
{
|
||||
if (shield != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject shieldObject = new GameObject("ShieldBarrier");
|
||||
shieldObject.transform.SetParent(unit.transform, false);
|
||||
|
||||
BoxCollider boxCollider = shieldObject.AddComponent<BoxCollider>();
|
||||
boxCollider.isTrigger = true;
|
||||
boxCollider.size = shieldSize;
|
||||
|
||||
shield = shieldObject.AddComponent<ShieldBarrier>();
|
||||
shield.Configure(unit, boxCollider);
|
||||
shieldObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: BntMsS6pUymOHB/6dKfMA7C7qYr3zT7pDxKENaWTJXDll6CyvBaNH2k=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class StoneGolemSkill : UnitSkill
|
||||
{
|
||||
[Header("地裂参数")]
|
||||
[Min(0f)]
|
||||
public float skillDamage = 110f;
|
||||
|
||||
[Min(0.1f)]
|
||||
public float skillRadius = 2f;
|
||||
|
||||
[Min(0f)]
|
||||
public float stunDuration = 1f;
|
||||
|
||||
[Header("技能动画")]
|
||||
[Min(0f)]
|
||||
public float skillAnimationDuration = 0f;
|
||||
|
||||
[Header("特效")]
|
||||
public GameObject shockwaveEffectPrefab;
|
||||
|
||||
private bool isSkillReady;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
if (unit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unit.FaceCurrentTarget(0f);
|
||||
isSkillReady = true;
|
||||
unit.PlaySkillAnimation(OnSkillFinished, skillAnimationDuration);
|
||||
}
|
||||
|
||||
// 添加到地裂技能动画的命中帧;在命中帧结算伤害和眩晕。
|
||||
public void OnSkillHit1()
|
||||
{
|
||||
if (!isSkillReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成扩散光圈特效
|
||||
if (shockwaveEffectPrefab != null)
|
||||
{
|
||||
Vector3 effectPosition = unit.transform.position;
|
||||
var effectObj = Instantiate(shockwaveEffectPrefab, effectPosition, shockwaveEffectPrefab.transform.rotation);
|
||||
|
||||
// 可选:动态配置特效参数(不配置则使用Prefab默认值)
|
||||
var effect = effectObj.GetComponent<ShockwaveEffect>();
|
||||
if (effect != null)
|
||||
{
|
||||
// 根据技能范围动态设置扩散半径
|
||||
effect.overrideRadius = skillRadius;
|
||||
// 可以设置颜色,例如:effect.overrideColor = new Color(1f, 0.8f, 0.2f, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
unit.ApplyAreaSkillDamage(skillRadius, skillDamage, false);
|
||||
unit.ApplyAreaStun(skillRadius, stunDuration);
|
||||
isSkillReady = false;
|
||||
}
|
||||
|
||||
private void OnSkillFinished()
|
||||
{
|
||||
isSkillReady = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: CC8d5C+qVXL85oNIASr9QqmYpLwsA9tVuzUYro25oZb3NHl6w2iNA1E=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
public abstract class UnitSkill : MonoBehaviour
|
||||
{
|
||||
protected UnitBase unit;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
unit = GetComponent<UnitBase>();
|
||||
}
|
||||
|
||||
public abstract void ReleaseSkill();
|
||||
|
||||
public virtual float ModifyIncomingDamage(float damage, GameObject attacker)
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: Wi9K4CiqAHqIYi4iwkLvt2K24jVu7gOoQzrHgM9LxGqhLcEJqXPR69Y=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class WerewolfSkill : UnitSkill
|
||||
{
|
||||
[Header("狼嚎效果")]
|
||||
[Min(0f)]
|
||||
public float attackSpeedIncrease = 0.2f;
|
||||
|
||||
[Min(0f)]
|
||||
public float duration = 5f;
|
||||
|
||||
private bool buffActive;
|
||||
private float buffEndTime;
|
||||
|
||||
public override void ReleaseSkill()
|
||||
{
|
||||
ApplyHowlBuff();
|
||||
}
|
||||
|
||||
private void ApplyHowlBuff()
|
||||
{
|
||||
if (buffActive)
|
||||
{
|
||||
buffEndTime = Time.time + duration;
|
||||
return;
|
||||
}
|
||||
|
||||
buffActive = true;
|
||||
buffEndTime = Time.time + duration;
|
||||
unit.MultiplyAttackSpeed(1f + attackSpeedIncrease, 2f);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (buffActive && Time.time >= buffEndTime)
|
||||
{
|
||||
buffActive = false;
|
||||
unit.MultiplyAttackSpeed(1f / (1f + attackSpeedIncrease), 2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: CX1K4XmqUC1Wf0EVbqMJfAnOkX/FLXd2ZcMaE6q7L8nno/KCp7gb5kA=
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user