RPG项目01_技能释放

基于“RPG项目01_新输入输出”,

修改脚本文件夹中的SkillBase脚本:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

//回复技能,魔法技能,物理技能
public enum SkillType { Up, Magic, Physics };
public class SkillBase : MonoBehaviour{
    protected GameObject prefab;
    protected SkillType type;//类型
    protected string path = "Skill/";
    protected string skillName;
    protected int attValue;
    public int mp;
    protected People from;//从人物释放
    protected People tPeople;//敌人目标
    protected Dictionary<SkillType, UnityAction> typeWithSkill =
        new Dictionary<SkillType, UnityAction>();
    protected float time = 0;//计时器
    protected float skillTime;//技能冷却时间
    protected float delayTime;//延迟时间
    protected float offset;//偏移量
    protected Vector3 skillPoint;//攻击点
    public bool IsRelease { get; private set; }//技能是否释放
    protected int layer;//技能对哪个一层起作用
    protected Collider[] cs;//技能碰撞体
    public event UnityAction Handle;//处理方法
    protected void Init(){
        IsRelease = true;
        layer = LayerMask.GetMask("MyPlayer") + LayerMask.GetMask("Enemy");
        prefab = LoadManager.LoadGameObject(path + skillName);
        typeWithSkill.Add(SkillType.Magic, MagicHurt);
        typeWithSkill.Add(SkillType.Physics, PhysicsHurt);
        typeWithSkill.Add(SkillType.Up, HpUp);
    }
    #region 技能
    private void MagicHurt(){
        cs = GetColliders();
        foreach (Collider c in cs){
            if (c.tag != from.tag){
                c.GetComponent<People>().BeMagicHit(attValue, from);
                c.GetComponent<People>().Anim.SetTrigger("Hurt");
            }
        }
    }
    private void PhysicsHurt(){
        cs = GetColliders();
        foreach (Collider c in cs){
            if (c.tag != from.tag){
                c.GetComponent<People>().BePhysicsHit(attValue, from);
                c.GetComponent<People>().Anim.SetTrigger("Hurt");
            }
        }
    }
    private void HpUp(){
        cs = GetColliders();
        foreach (Collider c in cs){
            if (c.tag == from.tag){
                c.GetComponent<People>().AddHp(attValue);
            }
        }
    }
    #endregion
    protected virtual Collider[] GetColliders(){
        return null;
    }
    public float GetFillTime(){
        if (IsRelease){
            return 0;
        }
        time -= Time.deltaTime;
        if (time < 0){
            IsRelease = true;
        }
        return time / skillTime;
    }
    public void SetEventHandle(UnityAction fun){
        Handle += fun;
    }
    public bool MayRelease(){
        return (from.Mp + mp >= 0) && IsRelease;
    }
    //携程函数-技能释放执行
    public virtual IEnumerator SkillPrefab(){
        IsRelease = false;
        time = skillTime;
        yield return new WaitForSeconds(delayTime);//等待延迟时间
        typeWithSkill[type]();
        from.AddMp(mp);
        skillPoint = from.transform.position + from.transform.forward * offset;
        Quaternion qua = from.transform.rotation;//施放角度
        GameObject effect = Instantiate(prefab, skillPoint, qua);
        yield return new WaitForSeconds(3);//等待三秒
        Handle?.Invoke();//时间调用
        Destroy(effect);//特效销毁
    }
}
技能基类创建完后创建技能子类StraightSkill

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StraightSkill : SkillBase
{//直线技能
    float length;
    float width;
    public StraightSkill(People p, string _name, SkillType _type,
        float _length, float _width, int _att, int _mp, float _skillTime, float _delayTime, float _offset){
        from = p;
        length = _length;
        width = _width;
        skillName = _name;
        mp = _mp;
        type = _type;
        attValue = _att;
        skillTime = _skillTime;
        delayTime = _delayTime;
        offset = _offset;
        Init();
    }
    protected override Collider[] GetColliders(){
        skillPoint = from.transform.position + from.transform.forward * offset;
        Vector3 bound = new Vector3(width * width, length);
        return Physics.OverlapBox(skillPoint, bound, Quaternion.LookRotation(from.transform.forward), layer);
    }
}
再创建球型子类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

public class SphereSkill : SkillBase
{//球型技能
    float r;
    public SphereSkill(People p, string _name, SkillType _type, float _r,
        int _att, int _mp, float _skillTime, float _delayTime, float _offset){
        from = p;
        r = _r;
        skillName = _name;
        mp = _mp;
        type = _type;
        attValue = _att;
        skillTime = _skillTime;
        delayTime = _delayTime;
        offset = _offset;
        Init();
    }
    protected override Collider[] GetColliders(){
        skillPoint = from.transform.position + from.transform.forward * offset;
        return Physics.OverlapSphere(skillPoint, r, layer);
    }
}

接下来在角色类中修改代码添加技能:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class MyPlayer : People{
    [Header("==============子类变量==============")]
    public Transform toolPanel;//道具面板
    public Transform skillPanel;//技能面板
    //public BagPanel bag;//背包

    CharacterController contro;
    Controls action;

    float rvalue;
    float spdFast = 1;
    bool isHold;//握刀
    GameObject sword;
    GameObject swordBack;
    public Image imageHp;
    public Image imageMp;
    new void Start() {
        base.Start();
        //获取自身角色控制器
        contro = GetComponent<CharacterController>();
        SetInput();
    }
    void SetInput(){
        action = new Controls();
        action.Enable();
        action.MyCtrl.Move.started += Move;
        action.MyCtrl.Move.performed += Move;
        action.MyCtrl.Move.canceled += StopMove;
        action.MyCtrl.Jump.started += Jump;
        action.MyCtrl.Rotate.started += Rotate;
        action.MyCtrl.Rotate.performed += Rotate;
        action.MyCtrl.Fast.started += FastSpeed;
        action.MyCtrl.Fast.performed += FastSpeed;
        action.MyCtrl.Fast.canceled += FastSpeed;
        action.MyCtrl.GetTool.started += ClickNpcAndTool;
        action.MyCtrl.HoldRotate.performed += Hold;
        action.MyCtrl.HoldRotate.canceled += Hold;
        action.MyAtt.Att.started += Attack;
        action.MyAtt.SwordOut.started += SwordOut;
    }
    private void SwordOut(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        Anim.SetBool("SwordOut", !Anim.GetBool("SwordOut"));
    }
    private void Attack(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (EventSystem.current.IsPointerOverGameObject())
        {
            return;
        }
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight"))
        {
            Anim.SetInteger("Att", 1);
            Anim.SetTrigger("AttTrigger");

        }
        else
        {
            int num = Anim.GetInteger("Att");
            if (num == 6)
            {
                return;
            }
            if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Light_Attk_" + num))
            {
                Anim.SetInteger("Att", num + 1);
            }
        }
    }
    public void PlayerAttack(string hurt)
    {
        Collider[] cs = Physics.OverlapBox(attPoint.position, Vector3.one * 0.5f,
            attPoint.rotation, LayerMask.GetMask("Enemy"));
        if (cs.Length <= 0)
        {
            return;
        }
        int value = (int)(Att * Anim.GetInteger("Att") * 0.5f);
        foreach (Collider c in cs)
        {
            print(value);
        }
    }

    public void PlayerAttackHard(string hurt)
    {
        Collider[] cs = Physics.OverlapBox(attPoint.position, Vector3.one * 0.5f,
            attPoint.rotation, LayerMask.GetMask("Enemy"));
        if (cs.Length <= 0)
        {
            return;
        }
        int value = (int)(Att * Anim.GetInteger("Att") * 0.5f);
        foreach (Collider c in cs)
        {
            print(value);
            print("让敌人播放击倒特效");
        }
    }
    private void Hold(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (context.phase == InputActionPhase.Canceled)
        {
            isHold = false;
        }
        else
        {
            isHold = true;
        }
    }
    private void ClickNpcAndTool(InputAction.CallbackContext context)
    {
        //throw new NotImplementedException();
    }
    private void FastSpeed(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Run") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Run_Inplace"))
        {
            if (context.phase == InputActionPhase.Canceled)
            {
                spdFast = 1;
            }
            else
            {
                spdFast = 2;
            }
        }
    }
    private void Rotate(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        rvalue = context.ReadValue<float>();
    }
    private void Jump(InputAction.CallbackContext obj){
        Anim.SetTrigger("Jump");
    }

    private void StopMove(InputAction.CallbackContext context){
        Anim.SetBool("IsRun", false);
    }
    private void Move(InputAction.CallbackContext context){
        if (GameManager.gameState != GameState.Play) {
            return;
        }
        Anim.SetBool("IsRun", true);
    }
    void Ctrl()
    {
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Run") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Run_Inplace") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle")||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight")){
            float f = action.MyCtrl.Move.ReadValue<float>();
            contro.Move(transform.forward * f * Time.deltaTime * spdFast * Spd);
            contro.Move(transform.up * -9.8f * Time.deltaTime);
            if (isHold)
            {
                transform.Rotate(transform.up * rvalue * 0.3f);
            }
        }
    }
    void Update()
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        Ctrl();
    }
    #region 技能
    protected override void InitSkill()
    {
        SphereSkill thunderBombCut = new SphereSkill(this, "雷爆斩", SkillType.Magic, 3, Att * 10, -100, 20, 0.3f, 0);
        skills.Add(1, thunderBombCut);

        SphereSkill windCircleCut = new SphereSkill(this, "旋风斩", SkillType.Physics, 3, Att * 8, -50, 20, 0.2f, 0);
        skills.Add(2, windCircleCut);

        StraightSkill thunderLightCut = new StraightSkill(this, "雷光斩", SkillType.Physics, 7, 0.5f, Att * 7, -50, 20, 0.2f, 0);
        skills.Add(3, thunderLightCut);

        SphereSkill oneCut = new SphereSkill(this, "归一斩", SkillType.Physics, 7, Att * 7, -30, 8, 0.2f, 0);
        skills.Add(4, oneCut);

        StraightSkill crossCut = new StraightSkill(this, "十字斩", SkillType.Physics, 25, 0.5f, Att * 3, -40, 20, 0.2f, 0);
        skills.Add(5, crossCut);


        SphereSkill thunderLargeCut = new SphereSkill(this, "轰雷斩", SkillType.Magic, 7, Att * 15, -120, 25, 0.35f, 0);
        skills.Add(6, thunderLargeCut);
    }
    #endregion
}
在新输入系统中添加Skill文件包

在People基类添加基类

修改MyPlayer代码:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class MyPlayer : People{
    [Header("==============子类变量==============")]
    public Transform toolPanel;//道具面板
    public Transform skillPanel;//技能面板
    //public BagPanel bag;//背包

    CharacterController contro;
    Controls action;

    float rvalue;
    float spdFast = 1;
    bool isHold;//握刀
    GameObject sword;
    GameObject swordBack;
    public Image imageHp;
    public Image imageMp;
    new void Start() {
        base.Start();
        //获取自身角色控制器
        contro = GetComponent<CharacterController>();
        SetInput();
    }
    void SetInput(){
        action = new Controls();
        action.Enable();
        action.MyCtrl.Move.started += Move;
        action.MyCtrl.Move.performed += Move;
        action.MyCtrl.Move.canceled += StopMove;
        action.MyCtrl.Jump.started += Jump;
        action.MyCtrl.Rotate.started += Rotate;
        action.MyCtrl.Rotate.performed += Rotate;
        action.MyCtrl.Fast.started += FastSpeed;
        action.MyCtrl.Fast.performed += FastSpeed;
        action.MyCtrl.Fast.canceled += FastSpeed;
        action.MyCtrl.GetTool.started += ClickNpcAndTool;
        action.MyCtrl.HoldRotate.performed += Hold;
        action.MyCtrl.HoldRotate.canceled += Hold;

        action.MyAtt.Att.started += Attack;
        action.MyAtt.SwordOut.started += SwordOut;

        action.Skill.F1.started += SkillAtt;
        action.Skill.F2.started += SkillAtt;
        action.Skill.F3.started += SkillAtt;
        action.Skill.F4.started += SkillAtt;
        action.Skill.F5.started += SkillAtt;
        action.Skill.F6.started += SkillAtt;
    }

    private void SkillAtt(InputAction.CallbackContext context)
    {
        if (!Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight"))
        {
            return;
        }
        string[] str = context.control.ToString().Split('/');
        int num = int.Parse(str[2][1].ToString());
        SkillBase skill = skills[num];
        if (!skill.MayRelease())
        {
            return;
        }
        Anim.SetTrigger("CSkill" + num);
        ReleaseSkill(skill);
    }

    public void SkillClick(int num)
    {
        if (!Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight"))
        {
            return;
        }
        SkillBase skill = skills[num];
        if (!skill.MayRelease())
        {
            return;
        }
        Anim.SetTrigger("CSkill" + num);
        ReleaseSkill(skill);
    }

    void UpdateSkillTime()
    {
        for (int i = 0; i < skillPanel.childCount; i++)
        {
            if (skills[i + 1].IsRelease)
            {
                continue;
            }
            Image image = skillPanel.GetChild(i).GetChild(0).GetComponent<Image>();
            image.fillAmount = skills[i + 1].GetFillTime();
        }
    }

    private void SwordOut(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        Anim.SetBool("SwordOut", !Anim.GetBool("SwordOut"));
    }
    private void Attack(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (EventSystem.current.IsPointerOverGameObject())
        {
            return;
        }
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight"))
        {
            Anim.SetInteger("Att", 1);
            Anim.SetTrigger("AttTrigger");

        }
        else
        {
            int num = Anim.GetInteger("Att");
            if (num == 6)
            {
                return;
            }
            if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Light_Attk_" + num))
            {
                Anim.SetInteger("Att", num + 1);
            }
        }
    }
    public void PlayerAttack(string hurt)
    {
        Collider[] cs = Physics.OverlapBox(attPoint.position, Vector3.one * 0.5f,
            attPoint.rotation, LayerMask.GetMask("Enemy"));
        if (cs.Length <= 0)
        {
            return;
        }
        int value = (int)(Att * Anim.GetInteger("Att") * 0.5f);
        foreach (Collider c in cs)
        {
            print(value);
        }
    }

    public void PlayerAttackHard(string hurt)
    {
        Collider[] cs = Physics.OverlapBox(attPoint.position, Vector3.one * 0.5f,
            attPoint.rotation, LayerMask.GetMask("Enemy"));
        if (cs.Length <= 0)
        {
            return;
        }
        int value = (int)(Att * Anim.GetInteger("Att") * 0.5f);
        foreach (Collider c in cs)
        {
            print(value);
            print("让敌人播放击倒特效");
        }
    }
    private void Hold(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (context.phase == InputActionPhase.Canceled)
        {
            isHold = false;
        }
        else
        {
            isHold = true;
        }
    }
    private void ClickNpcAndTool(InputAction.CallbackContext context)
    {
        //throw new NotImplementedException();
    }
    private void FastSpeed(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Run") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Run_Inplace"))
        {
            if (context.phase == InputActionPhase.Canceled)
            {
                spdFast = 1;
            }
            else
            {
                spdFast = 2;
            }
        }
    }
    private void Rotate(InputAction.CallbackContext context)
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        rvalue = context.ReadValue<float>();
    }
    private void Jump(InputAction.CallbackContext obj){
        Anim.SetTrigger("Jump");
    }

    private void StopMove(InputAction.CallbackContext context){
        Anim.SetBool("IsRun", false);
    }
    private void Move(InputAction.CallbackContext context){
        if (GameManager.gameState != GameState.Play) {
            return;
        }
        Anim.SetBool("IsRun", true);
    }
    void Ctrl()
    {
        if (Anim.GetCurrentAnimatorStateInfo(0).IsName("Run") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Run_Inplace") ||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle")||
            Anim.GetCurrentAnimatorStateInfo(0).IsName("Idle_Fight")){
            float f = action.MyCtrl.Move.ReadValue<float>();
            contro.Move(transform.forward * f * Time.deltaTime * spdFast * Spd);
            contro.Move(transform.up * -9.8f * Time.deltaTime);
            if (isHold)
            {
                transform.Rotate(transform.up * rvalue * 0.3f);
            }
        }
    }
    void Update()
    {
        if (GameManager.gameState != GameState.Play)
        {
            return;
        }
        Ctrl();
    }
    #region 技能
    protected override void InitSkill()
    {
        SphereSkill thunderBombCut = new SphereSkill(this, "雷爆斩", SkillType.Magic, 3, Att * 10, -100, 20, 0.3f, 0);
        skills.Add(1, thunderBombCut);

        SphereSkill windCircleCut = new SphereSkill(this, "旋风斩", SkillType.Physics, 3, Att * 8, -50, 20, 0.2f, 0);
        skills.Add(2, windCircleCut);

        StraightSkill thunderLightCut = new StraightSkill(this, "雷光斩", SkillType.Physics, 7, 0.5f, Att * 7, -50, 20, 0.2f, 0);
        skills.Add(3, thunderLightCut);

        SphereSkill oneCut = new SphereSkill(this, "归一斩", SkillType.Physics, 7, Att * 7, -30, 8, 0.2f, 0);
        skills.Add(4, oneCut);

        StraightSkill crossCut = new StraightSkill(this, "十字斩", SkillType.Physics, 25, 0.5f, Att * 3, -40, 20, 0.2f, 0);
        skills.Add(5, crossCut);


        SphereSkill thunderLargeCut = new SphereSkill(this, "轰雷斩", SkillType.Magic, 7, Att * 15, -120, 25, 0.35f, 0);
        skills.Add(6, thunderLargeCut);
    }
    #endregion
}
修改MyPlayer代码:

将技能预制体包导入:

运行即可释放技能:

按E拔刀后按F1/F2/F3/F4/F5/F6键释放技能

同一个技能不能连续释放是因为冷却,

如果不同技能释放一个后另一个释放不了是因为mp不够,

设置mp初始及mp最大容量

即可释放完F1技能后还可以释放F2/F3/F4/F5/F6技能:

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2023-12-06 10:56:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-06 10:56:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-06 10:56:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-06 10:56:02       20 阅读

热门阅读

  1. element UI之 el-date-picker 无法选择当前日期

    2023-12-06 10:56:02       32 阅读
  2. [cocos creator] Label设置为RESIZE_HEIGHT,获取height

    2023-12-06 10:56:02       29 阅读
  3. flask学习笔记-01-传送dict信息

    2023-12-06 10:56:02       44 阅读
  4. 一个使用Rust开发的MQTT Broker

    2023-12-06 10:56:02       40 阅读
  5. 专栏测试1--日后删除

    2023-12-06 10:56:02       36 阅读
  6. LeetCode1137. N-th Tribonacci Number

    2023-12-06 10:56:02       38 阅读
  7. IDEA连接Redis注意事项

    2023-12-06 10:56:02       38 阅读
  8. 网络运维神器:H3C高级命令使用全攻略

    2023-12-06 10:56:02       37 阅读
  9. [iOS]常用修饰符详解

    2023-12-06 10:56:02       31 阅读
  10. Linux命令(140)之iostat

    2023-12-06 10:56:02       33 阅读
  11. 十二、h.264解码

    2023-12-06 10:56:02       35 阅读
  12. 【UBUNTU】随手记

    2023-12-06 10:56:02       39 阅读
  13. NVIDIA Jetson NX ubuntu20.04删除多余版本冲突的Boost库

    2023-12-06 10:56:02       42 阅读
  14. 【OpenSSH升级】升级后证书认证登录突然失效

    2023-12-06 10:56:02       44 阅读
  15. C语言 if语句有无(;)分号问题

    2023-12-06 10:56:02       38 阅读