二、有限状态机技能构思

一、技能系统设计思想

二、模型层与挥出一刀

(一)添加玩家攻击状态

在State文件夹中添加一个脚本

这个脚本继承状态基类StateBase;并且持有玩家控制器;

先进行初始化,大体上与移动逻辑一致

然后重写基类里面的周期函数

public class Player_Attack : StateBase<PlayerState>
{
	public Player_Controller player;
	public override void Init(FSMController<PlayerState> controller, PlayerState stateType)
	{
		base.Init(controller, stateType);
		player = controller as Player_Controller;
	}
	public override void OnEnter()
	{
		//攻击
		Attack();
	}
	public override void OnExit() { }
	public override void OnUpdate() { }
	public void Attack() { }
}

(二)移动状态切换到攻击状态

1、先在玩家控制器中添加一个枚举状态(攻击)

2、写一个方法判断是否是攻击状态

3、状态切换

需要在移动的代码中时刻判断当前的枚举状态

(三)模型层驱动动画

先添加一个Bool值的变量 判断移动和攻击状态的切换

注:不需要退出时间

在模型层代码中,调用这个动画

(四)攻击动画的动画事件

1、动画添加动画事件

对应事件函数

//开启技能伤害
private void StartSkillHit()
{
	//开启刀光的拖尾
	//启用伤害检测的触发器
}
//停止技能伤害
private void StopSkillHit()
{
	//关闭刀光的拖尾
	//停止伤害检测的触发器
}
//技能结束
private void SkillOver()
{
	animator.SetBool("攻击", false);
	player.ChangeState<Player_Move>(PlayerState.Player_Move);
}

2、Bug解决方法

在调用了攻击的方法之后

会出现人物攻击之后,无法运行

原因是:当前接管人物的还是Play_Attack状态,而不是Play_Move状态

因此需要在攻击结束的方法中传递泛型(移动状态)

攻击时会调用这个事件,所以接管人物状态重新变为移动

三、武器层与武器拖尾

1、拖尾及触发器制作

2、代码实现

先声明变量 触发器、拖尾组件

先初始化,将这两个组件设置为false
在调用时,设置为true

因为停止攻击时候,要全部设置为false,所以就直接调用这个停止的方法

注:拖尾组件有单独的接口开关

3、判断怪物的受攻击次数

当玩家的面前有多个怪物,碰撞体较大,可能会出现多次触发的情况
因此需要保证:目标是怪物,并且是第一次触发

使用一个List集合,然后每一次攻击往这个集合里面添加一个对应的敌人

攻击结束后清除。

public class WeaponCollide : MonoBehaviour
{
    public BoxCollider BoxCollider;
    public TrailRenderer TrailRenderer;
	private List<GameObject> monsterList;

    public void Init()
    {
		//BoxCollider.enabled = false;
		//TrailRenderer.emitting = false;
		
		monsterList = new List<GameObject>();
		StopSkillHit();

	}
	public void StartSkillHit()
	{
		BoxCollider.enabled = true;
		TrailRenderer.emitting = true;
	}
	public void StopSkillHit()
	{
		BoxCollider.enabled = false;
		TrailRenderer.emitting = false;
		//清空怪物列表
		monsterList.Clear();
	}
	private void OnTriggerEnter(Collider other)
	{
		//保证一段伤害只会击中一次怪物
		//对方是怪物,并且我此次攻击第一次碰到他
		if (other.tag == "Monster" && !monsterList.Contains(other.gameObject))
		{
			//输出伤害
			monsterList.Add(other.gameObject);
			//TODO:实际输出伤害给敌人,附加硬直、击退、击飞、生命值消减...
		}
	}
}

四、怪物受伤:硬直、击退、掉血

1、怪物的动画设置

一般怪物会有多个受伤的动画,进行切换调用。

首先给怪物模型一个父物体Monster

设置三个触发状态,受伤结束返回待机状态,两个受伤状态切换条件是对方

全部取消退出时间


在模型层实现动画的跳转
声明变量动画控制器;声明一个当前动画的索引

初始化获取这个动画组件

写一个方法,播放当前的受伤动画,因为加了一

所以先执行受伤1,然后判断,如果当前是受伤1,就调用受伤2

写一个受伤结束的方法,将触发器播放为受伤结束,动画执行完会回到待机状态

public class Monster_Model : MonoBehaviour
{
    private Animator animator;
    private int currHurtAnimationIndex = 1;//当前受伤动画的索引
    public void Init()
    {
        animator = GetComponent<Animator>();
    }
    public void PlayHurtAnimation()//播放受伤动画
    {
        animator.SetTrigger("受伤" + currHurtAnimationIndex);
        if (currHurtAnimationIndex == 1) currHurtAnimationIndex = 2;
        else currHurtAnimationIndex = 1;

    }
    public void StopHurtAnimation()
    {
        animator.SetTrigger("受伤结束");
    }
}

在怪物控制层实现调用逻辑

public class Monster_Controller : MonoBehaviour
{
    private Monster_Model model;

	private int hp = 100;
	private void Start()
	{
		model=transform.Find("Model").GetComponent<Monster_Model>();
		model.Init();
	}
	//受伤
	public void Hurt()
	{
		//注意目前都是采用硬编码,先实现功能
		//硬直与播放动画
		model.PlayHurtAnimation();
		CancelInvoke("HurtOver");//取消之前可能还在执行中的硬直
		Invoke("HurtOver", 3);//一秒硬直
		//击退 击飞

		//生命值减少
	}
	private void HurtOver()//受伤结束
	{
		model.StopHurtAnimation();
	}
}

2、怪物的受伤逻辑

怪物受伤会有三种效果:硬直、击退、掉血

硬直

使用延迟函数和取消延迟函数的方法,播放受伤动画并且持续一段时间

击退

首先需要几个变量

1、布尔值是否击中

2、V3变量 受击的位移

3、受击过渡时间

4、当前时间

首先在Update中进行一直判断是否受到伤害,而这个条件会在伤害方法调用时,置为true

使用Ucc在进行位移,好处是不会穿模,对应的API有Move和SimpleMove

效果是受击后有一个向上的位移然后向下,所以else中给出一个向下的位移

五、ScriptableObject基本使用

代码需要继承ScriptableObject

一般用作配置数据等功能,也支持Resource.Load的方法

代码开头可以使用编辑器扩展功能,CreateAssetMenu(),这是一个特性

filename是这个配置文件创造出来的默认名称,后续可以修改,所以比较鸡肋

menuname是一个路径

写三个类并且在上面持有这三个类,方便再别的代码中调用类中的配置文件
无法通过声明这个代码调用类方法。只能配置文件持有这个类在调用类中的配置信息

类中的信息如果显示出来,需要一个特性Serializable

[CreateAssetMenu(fileName = "技能配置", menuName ="配置/技能配置/技能数据")]
public class Conf_SkillData : ScriptableObject
{
    //技能名称
    public string Name;
    //释放数据
    public Skill_ReleaseModel ReleaseModel;
    //命中数据
    public Skill_HitModel HitModel;
    //结束数据
    public Skill_EndModel EndModel;

	/// <summary>
	/// 技能释放
	/// </summary>
	[Serializable]
	public class Skill_ReleaseModel
    {

    }
    /// <summary>
    /// 技能命中
    /// </summary>
    [Serializable]
    public class Skill_HitModel
    {
        public int DamageValue;
        
    }
	/// <summary>
	/// 技能结束
	/// </summary>
	[Serializable]
	public class Skill_EndModel
    {

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值