一: 连招思路

首先人物角色上有三个攻击实例对象 Damage,每一个damage定义了攻击的伤害值,攻击距离,触发器名称,伤害的发起者,攻击持续时间,攻击重置时间,伤害的碰撞框大小等字段:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

[System.Serializable]

public class Damage

{

///

/// 触发动画触发器名称

///

public string animationTrigger = "";

///

/// 组合攻击伤害

///

public int damage = 0;

///

/// 伤害的攻击者

///

public GameObject inflictor;

///

/// 组合攻击持续时间

///

public float duration = 1f;

///

/// 连击重置时间 超过这个时间如果没有收到连击序列 连击将会被取消

///

public float comboResetTime = .5f;

[Space(10)]

[Header("hit collider settings")]

public float collSize;

public float collDistance;

public float collHeight;

}

当按下某一个键位的时候,播放对应索引的攻击,如果在攻击时间后再次收到了攻击键位的按下就认为是连击状态,这时候继续播放攻击动作。

二: 代码实现

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class PlayerCombat : MonoBehaviour

{

// 主角的攻击组合

public Damage[] attackCombo;

// 主角的最后一次攻击类型

public Damage lastAttack;

// 记录最后一次攻击时间

public float lastAttackTime;

public PlayerController playerController;

public CharactorState charactorState;

// 最近一次攻击的索引

public int attackIndex = 0;

// 是否是连击状态

public bool continueAttackCombo;

void Awake()

{

playerController = GetComponent();

charactorState = GetComponent();

}

public void combatEvent()

{

Debug.LogWarning("state is " + charactorState.curState);

if (charactorState.curState != UnitState.ATTACK)

{

// 是否在攻击窗口内

bool insideComboWindow = (lastAttack != null && (Time.time < (lastAttackTime + lastAttack.duration + lastAttack.comboResetTime)));

if (insideComboWindow && !continueAttackCombo && attackIndex < attackCombo.Length - 1)

{

// 继续攻击

attackIndex++;

}

else

{

// 重置攻击

attackIndex = 0;

}

doAttack(attackCombo[attackIndex], UnitState.ATTACK);

}

if (charactorState.curState == UnitState.ATTACK && !continueAttackCombo && playerController.pc.isGround)

{

if (attackIndex < attackCombo.Length - 1)

{

// 已经处于攻击状态,且不是连续攻击 将连续攻击状态打开

continueAttackCombo = true;

return;

}

}

}

public void doAttack(Damage damage, UnitState state)

{

Debug.Log("animationTrigger is " + damage.animationTrigger);

if (damage.animationTrigger == "attack3")

{

Debug.Log("attack3");

}

lastAttackTime = Time.time;

lastAttack = damage;

lastAttack.inflictor = this.gameObject;

charactorState.SetState(state);

playerController.playerAnimation.setTrigger(damage.animationTrigger);

Invoke("Ready", damage.duration);

}

public void Ready()

{

Debug.LogWarning("Ready");

if (continueAttackCombo)

{

// 重置是否继续连招动作 因为这个时候玩家没有触发攻击动作

continueAttackCombo = false;

if (attackIndex < attackCombo.Length - 1)

{

attackIndex++;

}

else

{

attackIndex = 0;

}

Debug.LogWarning("连招" + attackCombo[attackIndex].animationTrigger);

if (attackCombo[attackIndex] != null && attackCombo[attackIndex].animationTrigger.Length > 0)

{

doAttack(attackCombo[attackIndex], UnitState.ATTACK);

}

}

// 重置玩家状态

charactorState.SetState(UnitState.IDLE);

}

// Update is called once per frame

void Update()

{

}

}

三:攻击窗口

如果当前主角的状态不是攻击状态,检查是否在攻击时间窗口内,如果在攻击时间窗口内就进行攻击索引的累加,否则攻击索引从0开始

if (charactorState.curState != UnitState.ATTACK)

{

// 是否在攻击窗口内

bool insideComboWindow = (lastAttack != null && (Time.time < (lastAttackTime + lastAttack.duration + lastAttack.comboResetTime)));

if (insideComboWindow && !continueAttackCombo && attackIndex < attackCombo.Length - 1)

{

// 继续攻击

attackIndex++;

}

else

{

// 重置攻击

attackIndex = 0;

}

doAttack(attackCombo[attackIndex], UnitState.ATTACK);

return;

}

if (charactorState.curState == UnitState.ATTACK && !continueAttackCombo && playerController.pc.isGround)

{

if (attackIndex < attackCombo.Length - 1)

{

// 已经处于攻击状态,且不是连续攻击 将连续攻击状态打开

continueAttackCombo = true;

return;

}

}

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: