当前位置: 首页 > article >正文

Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/

本章节实现了解锁技能后才可以使用技能,先完成了冲刺技能的锁定解锁

Dash_Skill.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


//2024年11月19日添加解锁技能逻辑
public class Dash_Skill : Skill
{
    [Header("Dash")]
    public bool dashUnlocked;
    [SerializeField] private UI_SKillTreeSlot dashUnlockButton;

    [Header("Clone on dash")]
    public bool cloneOmDashUnlocked;
    [SerializeField] private UI_SKillTreeSlot cloneOnDashUnlockButton;

    [Header("Clone on arrival")]
    public bool cloneOnArrivalUnlocked;
    [SerializeField] private UI_SKillTreeSlot cloneOnArrivalUnlockButton;


    public override void UseSkill()
    {
        base.UseSkill();
    }

    protected override void Start()
    {
        base.Start();

        dashUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockDash);
        cloneOnDashUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockCloneOnDash);
        cloneOnArrivalUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockCloneOnArrival);
        
    }


    private void UnlockDash()
    {
        if (dashUnlockButton.unlocked)   
            dashUnlocked = true;
    }

    private void UnlockCloneOnDash()
    {
        if (cloneOnDashUnlockButton.unlocked)
            cloneOmDashUnlocked = true;

    }

    private void UnlockCloneOnArrival()
    {
        if (cloneOnArrivalUnlockButton.unlocked)
            cloneOnArrivalUnlocked = true;
    }

    public void CloneOnDash()
    {
        if (cloneOmDashUnlocked)
            SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);
    }

    public void CloneOnArrival()
    {
        if (cloneOnArrivalUnlocked)
            SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);
    }

}

UI_SKillTreeSlot .cs

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


//2024年11月17日
public class UI_SKillTreeSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    private UI ui;
    private Image skillImage;//当前技能槽的图片组件

    [SerializeField] private int skillPirce;//技能价格
    [SerializeField] private string skillName;
    [TextArea]
    [SerializeField] private string skillDescription;
    [SerializeField] private Color lockedSkillColor;//技能未解锁时的颜色


    public bool unlocked;

    [SerializeField] private UI_SKillTreeSlot[] shouldBeUnlocked;//解锁前置条件
    [SerializeField] private UI_SKillTreeSlot[] shouldBeLocked;//锁定条件



    private void OnValidate()
    {
        gameObject.name = "SkillTreeSlot_UI - " + skillName;
    }

    private void Awake()
    {
        GetComponent<Button>().onClick.AddListener(() => UnlockSkillSlot());//给 Button 组件绑定点击事件,用于触发技能槽解锁逻辑
    }

    private void Start()
    {
        skillImage = GetComponent<Image>();
        ui = GetComponentInParent<UI>();

        skillImage.color = lockedSkillColor;//设置初始颜色为锁定颜色
    }


    public void UnlockSkillSlot()
    {
        if(PlayerManager.instance.HaveEnoughMoney(skillPirce) == false)//检查是否有足够的钱
            return;


        for (int i = 0; i < shouldBeUnlocked.Length; i++)//前置解锁检查
        {
            if (shouldBeUnlocked[i].unlocked == false)
            {
                Debug.Log("不能解锁技能");
                return;
            }
        }


        for (int i = 0; i < shouldBeLocked.Length; i++)//锁定检查
        {
            if (shouldBeLocked[i].unlocked == true)
            {
                Debug.Log("不能解锁技能");
                return;
            }
        }

        unlocked = true;
        skillImage.color = Color.white;
    }


    public void OnPointerEnter(PointerEventData eventData)
    {
        ui.skillToolTip.ShowToolTip(skillDescription, skillName);

        Vector2 mousePosition = Input.mousePosition;

        float xOffset = 0;
        float yOffset = 0;


        if (mousePosition.x > 600)
            xOffset = -150;
        else
            xOffset = 150;//鼠标靠近屏幕右侧时,提示框向左偏移;否则向右偏移

        if (mousePosition.y > 320)

            yOffset = -150;
        else
            yOffset = 150;//鼠标靠近屏幕顶部时,提示框向下偏移;否则向上偏移


        ui.skillToolTip.transform.position = new Vector2(mousePosition.x + xOffset, mousePosition.y + yOffset);//更新提示框位置为鼠标位置偏移后的点
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        ui.skillToolTip.HideToolTip();//鼠标离开槽位时,隐藏技能描述提示框
    }
}

PlayerManager.cs

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

//P63,制作玩家管理器和技能管理器
//可以在SkeletonBattleState中通过PlayerManager.instance.player.transform获取到玩家的位置
public class PlayerManager : MonoBehaviour
{
    //全局访问
    public static PlayerManager instance;//单例模式
    public Player player;

    public int currency;

    private void Awake()
    {
        if (instance != null)
            Destroy(instance.gameObject);
        else
            instance = this;
    }

    public bool HaveEnoughMoney(int _price)//是否有钱去买技能
    {
        if (_price > currency)
        {
            Debug.Log("没有足够的钱");
            return false;
        }
        else
        
        currency -= _price;
        return true;
        
    }
}

Clone_Skill.cs

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

public class Clone_Skill : Skill
{
    [Header("Clone Info")]
    [SerializeField] private GameObject clonePrefab;//克隆原型
    [SerializeField] private float cloneDuration;//克隆持续时间
    [SerializeField] private bool canAttack;// 判断是否可以攻击
    [SerializeField] private bool canCreateCloneOnCounterAttack;
    [Header("Clone can Duplicate")]
    [SerializeField] private bool canDuplicateClone;//可以重复clone
    [SerializeField] private float chanceToDuplicate;//重复clone的几率
    [Header("Crystal instead of clone")]
    public bool crystalInsteadOfClone;//是否使用水晶代替克隆



    public void CreateClone(Transform _clonePosition,Vector3 _offset)//传入克隆位置
    {
        

        if(crystalInsteadOfClone)//克隆转换成水晶
        {
            SkillManager.instance.crystal.CreateCrystal();
            SkillManager.instance.crystal.CurrentCrystalChooseRandomTarget();
            return;
        }


        GameObject newClone = Instantiate(clonePrefab);//创建新的克隆//克隆 original 对象并返回克隆对象。
                                                       

        newClone.GetComponent<Clone_Skill_Controller>().
            SetupClone(_clonePosition, cloneDuration, canAttack,_offset,FindClosesetEnemy(newClone.transform),canDuplicateClone, chanceToDuplicate,player);
        
    }


    
    public void CreateCloneOnCounterAttack(Transform _enemyTransform)
    {
        if(canCreateCloneOnCounterAttack)
            StartCoroutine(CreateCloneWithDelay(_enemyTransform, new Vector3(2 * player.facingDir, 0)));
    }

    private IEnumerator CreateCloneWithDelay(Transform _transform,Vector3 _offset)
    {
        yield return new WaitForSeconds(.4f);
            CreateClone(_transform, _offset);
    }

}


http://www.kler.cn/a/402314.html

相关文章:

  • LLM文档对话 —— pdf解析关键问题
  • 在 WSL2 Ubuntu22.04环境安装 MySQL
  • k8s -20241119
  • 如何解决网站被渗透:全面指南与实践
  • 三天精通一种算法之螺旋矩阵(设计思路),长度最小子数组(滑动窗口)
  • React状态管理详解
  • Ubuntu22.04安装CH343驱动并创建udev规则
  • Vue 专属状态管理库Pinia的使用与实践
  • 解决前后端发版本时候,手动清除浏览器缓存
  • RN开发搬砖经验之—React Native(RN)应用转原生化-Android 平台
  • vite -- 开发环境 热更新
  • iOS 18 导航栏插入动画会导致背景短暂变白的解决
  • Unity中的预制体Prefab
  • Linux设置开机自动执行脚本 rc-local
  • 亚马逊商品详情API接口解析,Json数据示例返回
  • 速盾:CDN是否支持屏蔽IP?
  • Python入门(10)--面向对象进阶
  • 【linux】(13)java虚拟机进程信息-jps
  • Excel——宏教程(1)
  • 代码随想录算法训练营第三十五天| 01背包问题 二维 、01背包问题 一维、416. 分割等和子集 。c++转java