第九章 战斗系统(Combat System)
在SRPG中,大多数情况是指角色与角色之间的战斗。而这种战斗一般有两种模式:
-
地图中直接战斗;
-
有专门的战斗场景。
这两种模式的战斗在数据上没有任何区别,只有战斗动画的区别。
就像之前描述的,SRPG也是RPG,所以战斗方式和回合制RPG的战斗几乎是相同的。主要区别是RPG每个回合需要手动操作(也有自动战斗的),直到战斗结束;而SRPG是自动战斗,且多数情况只有一个回合(额外回合也是由于技能、物品或剧情需要)。且RPG多数是多人战斗,而SRPG多数是每边就一个。
我们这一章就来写一个战斗系统。
文章目录
三 战斗动画(Combat Animation)
在之前,我们已经计算出所有的战斗数据,而且每一步的动画也进行了保存。这样,在这里就可以它们为基准来播放需要的动画。
1 战斗动画控制器(Combat Animation Controller)
同样,我们创建一个组件来控制播放动画(CombatAnimaController
):
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace DR.Book.SRPG_Dev.CombatManagement
{
using DR.Book.SRPG_Dev.Maps;
[DisallowMultipleComponent, RequireComponent(typeof(Combat))]
[AddComponentMenu("SRPG/Combat System/Combat Anima Controller")]
public class CombatAnimaController : MonoBehaviour
{
private Combat m_Combat;
public Combat combat
{
get
{
if (m_Combat == null)
{
m_Combat = GetComponent<Combat>();
}
return m_Combat;
}
}
// TODO 其它属性与方法
}
}
它将依赖于Combat
组件,所以添加了Attribute(RequireComponent(typeof(Combat))
)。
2 控制器属性(Controller Properties)
在播放每一步(或者说角色每一次行动)时,我们需要一个时间间隔。如果连续播放可能会对感官有影响。
[SerializeField]
private float m_AnimationInterval = 1f;
/// <summary>
/// 每个动画的间隔时间
/// </summary>
public float animationInterval
{
get {
return m_AnimationInterval; }
set {
m_AnimationInterval = value; }
}
另外,在播放时我们采用Coroutine
(当然,你也可以使用void Update()
,并使用参数控制播放进程)。
private Coroutine m_AnimaCoroutine;
public bool isAnimaRunning
{
get {
return m_AnimaCoroutine != null; }
}
在最后,我们添加一些Combat
的代理。
public bool isCombatLoaded
{
get {
return combat.isLoaded; }
}
public bool isBattleCalced
{
get {
return combat.stepCount > 0; }
}
public int stepCount
{
get {
return combat.stepCount; }
}
/// <summary>
/// 初始化战斗双方
/// </summary>
/// <param name="mapClass0"></param>
/// <param name="mapClass1"></param>
/// <returns></returns>
public bool LoadCombatUnit(MapClass mapClass0, MapClass mapClass1)
{
return combat.LoadCombatUnit(mapClass0, mapClass1);
}
这些属性中,有一些不是必须的,这取决于你如何控制动画播放。
3 播放动画(Play Animation)
关于动画的播放,要了解一些情况:
-
有一些动画并不是所有的游戏中都存在的(例如躲闪和爆击动画),相当一部分都只是弹出文字提醒,除此之外防守者没有动画;
-
在地图上的攻击动画,需要注意方向问题,是使用四方向还是八方向?使用四方向时,斜线要注意朝向;
-
还要记住,游戏的UI还没有写,动画中可能要通知UI播放UI动画;
-
地图上的动画与单独场景的动画只会播放一个,取决于设置。
创建播放动画方法:
/// <summary>
/// 运行动画
/// </summary>
/// <param name="combat"></param>
/// <param name="inMap"></param>
public void PlayAnimas(bool inMap)
{
if (combat == null || !isCombatLoaded || isAnimaRunning)
{
return;
}
// 如果没有计算,则先计算
if (!isBattleCalced)
{
combat.BattleBegin();
if (!isBattleCalced)
{
Debug.LogError("CombatAnimaController -> calculate error! check the `Combat` code.");
return;
}
}
m_AnimaCoroutine = StartCoroutine(RunningAnimas(inMap));