Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
 此代码仅为较上一P有所改变的代码
 
 
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
 
UI_ToolTip.cs
using TMPro;
using UnityEngine;
public class UI_ToolTip : MonoBehaviour
{
    [SerializeField] private float xLimit = 960;
    [SerializeField] private float yLimit = 540;
    [SerializeField] private float xOffset = 150;
    [SerializeField] private float yOffset = 150;
    public virtual void AdjustPosition()//设置toolTip位置函数
    {
        
        Vector2 mousePosition = Input.mousePosition;
        float newXoffset = 0;
        float newYoffset = 0;
        if (mousePosition.x > xLimit)
        {
            newXoffset = -xOffset;
        }
        else
        {
            newXoffset = xOffset;
        }
        if (mousePosition.y > yLimit)
        {
            newYoffset = -yOffset;
        }
        else
        {
            newYoffset = yOffset;
        }
        transform.position = new Vector2(mousePosition.x + newXoffset, mousePosition.y + newYoffset);
        Debug.Log(123);
    }
    public void AdjustFontSize(TextMeshProUGUI _text) //调试文字大小函数
    {
        if(_text.text.Length > 12)
        {
            _text.fontSize = _text.fontSize * .8f;
        }
    }
}
 
Ui_SkillToolTip.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class Ui_SkillToolTip : UI_ToolTip//制作一个可以检查每个技能的描述的窗口
{
    [SerializeField] private TextMeshProUGUI skillDescription;
    [SerializeField] private TextMeshProUGUI skillName;
    [SerializeField] private TextMeshProUGUI skillCost;
    [SerializeField] private float defaultNameFontSize;
    public void ShowToolTip(string _skillDescription,string _skillName,string _SkillCost)
    {
        skillDescription.text = _skillDescription;
        skillName.text = _skillName;
        skillCost.text = "Cost : " +  _SkillCost;
        AdjustPosition();
        AdjustFontSize(skillName);
        gameObject.SetActive(true);
    }
    public void HideToolTip()
    {
        skillName.fontSize = defaultNameFontSize;
        gameObject.SetActive(false);
    }
        
}
 
 UI_SkillTreeSlot.cs
 
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UI_SkillTreeSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
    [SerializeField] private int skillCost;
    [SerializeField] private string skillName;
    [TextArea]
    [SerializeField] private string skillDescription;
    [SerializeField] private Color lockedSkillColor;
    private UI ui;
    public bool unlocked;//一个表示是否解锁的bool值
    private Image skillImage;
    [SerializeField] private UI_SkillTreeSlot[] shouldBeUnlocked;
    [SerializeField] private UI_SkillTreeSlot[] shouldBeLocked;//应该解锁和不该解锁的Slot组和Image
    private void OnValidate()
    {
        gameObject.name = "SkillTreeSlot_UI - " + skillName;
        
    }
    private void Awake()
    {
        GetComponent<Button>().onClick.AddListener(() => UnlockSkillSlot());
    }
    private void Start()
    {
        skillImage = GetComponent<Image>();
        skillImage.color = lockedSkillColor;
        ui = GetComponentInParent<UI>();
    }
    public void UnlockSkillSlot()//一个判断此Skill是否可以解锁的函数
    {
        if (PlayerManager.instance.HaveEnoughMoney(skillCost) == false)
            return;
        Debug.Log("Slot unlocked");
        for (int i = 0; i < shouldBeUnlocked.Length; i++)
        {
            if (shouldBeUnlocked[i].unlocked == false)
            {
                Debug.Log("Cannot unlock skill");
                return;
            }
        }
        for (int i = 0; i < shouldBeLocked.Length; i++)
        {
            if (shouldBeLocked[i].unlocked == true)
            {
                Debug.Log("Cannot unlock skill");
                return;
            }
        }
        unlocked = true;
        skillImage.color = Color.white;
    }
    public void OnPointerEnter(PointerEventData eventData)
    {
        ui.skillToolTip.ShowToolTip(skillDescription, skillName,skillCost.ToString());
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        ui.skillToolTip.HideToolTip();
    }
}
 
UI_statTooltip.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class UI_statToolTip : UI_ToolTip
{
    [SerializeField] private TextMeshProUGUI description;
    public void ShowStatToolTip(string _text)
    {
        Debug.Log(3);
        if (_text == null)
            return;
        Debug.Log(4);
        description.text = _text;
        AdjustPosition();
        gameObject.SetActive(true);
    }
    public void HideStatToolTip()
    {
        description.text = "";
        gameObject.SetActive(false);
    }
}
 
 UI_itemTooltip.cs
 
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class UI_itemTooltip : UI_ToolTip
{
    [SerializeField] private TextMeshProUGUI itemNameText;
    [SerializeField] private TextMeshProUGUI itemTypeText;
    [SerializeField] private TextMeshProUGUI itemDescription;
    [SerializeField] private int defaultFontSize = 32;
    public void ShowToolTip(ItemData_Equipment item)//将item里面的数据读取到对应的text上并显示此组件
    {
        if (item == null)
            return;
        itemNameText.text = item.itemName;
        itemTypeText.text = item.equipmentType.ToString();
        itemDescription.text = item.GetDescription();
        AdjustFontSize(itemNameText);
        AdjustPosition();
        gameObject.SetActive(true);
    }
    public void HideToolTip()//关闭此组件
    {
        itemNameText.fontSize = defaultFontSize;//防止字体越来越小
        gameObject.SetActive(false);
    }
}
 
UI_itemSlot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;
public class UI_itemSlot : MonoBehaviour ,IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler
{
    [SerializeField] protected Image itemImage;
    [SerializeField] protected TextMeshProUGUI itemText;
    protected UI ui;
    public InventoryItem item;
    protected virtual void Start()
    {
        ui = GetComponentInParent<UI>();
    }
    public void UpdateSlots(InventoryItem _newItem)
    {
        item = _newItem;
        itemImage.color = Color.white;
        if (item != null)
        {
            itemImage.sprite = item.data.icon;
            if (item.stackSize > 1)
            {
                itemText.text = item.stackSize.ToString();
            }
            else
            {
                itemText.text = "";
            }
        }
    }
    public void CleanUpSlot()//解决出现UI没有跟着Inventory变化的bug
    {
        item = null;
        itemImage.sprite = null;
        itemImage.color = Color.clear;
        itemText.text = "";
    }
    public virtual void OnPointerDown(PointerEventData eventData)
    {
        if(item == null)//修复点击空白处会报错的bug
        {
            return;
        }
        if(Input.GetKey(KeyCode.LeftControl))
        {
            Inventory.instance.RemoveItem(item.data);
            ui.itemToolTip.HideToolTip();
            return;
        }
        if (item.data.itemType == ItemType.Equipment)
            Inventory.instance.EquipItem(item.data);
        ui.itemToolTip.HideToolTip();//修复已经装备了装备还会出现详细信息栏的bug
    }
    public void OnPointerEnter(PointerEventData eventData)
    {
        if (item == null || item.data == null)
            return;
       
        ui.itemToolTip.ShowToolTip(item.data as ItemData_Equipment);
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        if (item == null || item.data == null)
            return;
        ui.itemToolTip.HideToolTip();
    }
}
 
ItemEffect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemEffect : ScriptableObject
{
    [TextArea]
    public string effectDescription;
    public virtual void ExecuteEffect(Transform _respawnPosition)
    {
        Debug.Log("Effect executed");
    }
}
 
ItemData_Equipment.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum EquipmentType
{
    Weapon,
    Armor,
    Amulet,
    Flask
}
[CreateAssetMenu(fileName = "New Item Data", menuName = "Data/Equipment")]
public class ItemData_Equipment : ItemData
{
    public EquipmentType equipmentType;
    [Header("Unique effect")]
    public float itemCooldown;
    public ItemEffect[] itemEffects;
    [Header("Major stats")]
    public int strength; // 力量 增伤1点 爆伤增加 1% 物抗
    public int agility;// 敏捷 闪避 1% 闪避几率增加 1%
    public int intelligence;// 1 点 魔法伤害 1点魔抗 
    public int vitality;//加血的
    [Header("Offensive stats")]
    public int damage;
    public int critChance;      // 暴击率
    public int critPower;       //150% 爆伤
    [Header("Defensive stats")]
    public int health;
    public int armor;
    public int evasion;//闪避值
    public int magicResistance;
    [Header("Magic stats")]
    public int fireDamage;
    public int iceDamage;
    public int lightingDamage;
    [Header("Craft requirements")]
    public List<InventoryItem> craftingMaterials;
    public int descriptionLength;
    public void AddModifiers()
    {
        PlayerStats playerStats = PlayerManager.instance.player.GetComponent<PlayerStats>();
        playerStats.strength.AddModifier(strength);
        playerStats.agility.AddModifier(agility);
        playerStats.intelligence.AddModifier(intelligence);
        playerStats.vitality.AddModifier(vitality);
        playerStats.damage.AddModifier(damage);
        playerStats.critChance.AddModifier(critChance);
        playerStats.critPower.AddModifier(critPower);
        playerStats.Health.AddModifier(health);
        playerStats.armor.AddModifier(armor);
        playerStats.evasion.AddModifier(evasion);
        playerStats.magicResistance.AddModifier(magicResistance);
        playerStats.fireDamage.AddModifier(fireDamage);
        playerStats.iceDamage.AddModifier(iceDamage);
        playerStats.lightingDamage.AddModifier(lightingDamage);
    }
    public void RemoveModifiers()
    {
        PlayerStats playerStats = PlayerManager.instance.player.GetComponent<PlayerStats>();
        playerStats.strength.RemoveModifier(strength);
        playerStats.agility.RemoveModifier(agility);
        playerStats.intelligence.RemoveModifier(intelligence);
        playerStats.vitality.RemoveModifier(vitality);
        playerStats.damage.RemoveModifier(damage);
        playerStats.critChance.RemoveModifier(critChance);
        playerStats.critPower.RemoveModifier(critPower);
        playerStats.Health.RemoveModifier(health);
        playerStats.armor.RemoveModifier(armor);
        playerStats.evasion.RemoveModifier(evasion);
        playerStats.magicResistance.RemoveModifier(magicResistance);
        playerStats.fireDamage.RemoveModifier(fireDamage);
        playerStats.iceDamage.RemoveModifier(iceDamage);
        playerStats.lightingDamage.RemoveModifier(lightingDamage);
    }
    public void Effect(Transform _enemyPosition)//循环调用Effect类里的Effect的函数
    {
        foreach(var item in itemEffects)
        {
            item.ExecuteEffect(_enemyPosition);
        }
    }
    public override string GetDescription()//让外界能够拿到拼出字符串的函数
    {
        sb.Length = 0;
        descriptionLength = 0;
        AddItemDescription(strength, "strength");
        AddItemDescription(agility, "agility");
        AddItemDescription(intelligence, "intelligence");
        AddItemDescription(vitality, "vitality");
        AddItemDescription(damage, "damage");
        AddItemDescription(critChance, "critChance");
        AddItemDescription(critPower, "critPower");
        AddItemDescription(health, "health");
        AddItemDescription(evasion, "evasion");
        AddItemDescription(armor, "armor");
        AddItemDescription(magicResistance, "magicResistance");
        AddItemDescription(fireDamage, "fireDamage");
        AddItemDescription(iceDamage, "iceDamage");
        AddItemDescription(lightingDamage, "lightingDamage");
        for(int i =0; i < itemEffects.Length;i++)
        {
            if (itemEffects[i].effectDescription.Length > 0)
            {
                sb.AppendLine();
                sb.AppendLine("Unique: " +itemEffects[i].effectDescription);
                descriptionLength++;
            }
        }
        if(descriptionLength < 5)//使窗口拥有最小尺寸
        {
            for(int i = 0;i < 5- descriptionLength;i++)
            {
                sb.AppendLine();
                sb.Append("");
            }
        }
        
        return sb.ToString();
        
    }
    private void AddItemDescription(int _value,string _name)//通过判断拼出想要的字符串的函数
    {
        if(_value != 0)
        {
          
            if(sb.Length >= 0)
                sb.AppendLine();//这是控制行数的
            if(_value > 0)
                sb.Append(" + "+_value + " " + _name);//这是实打实添加字符串的
            descriptionLength++;
            
        }
    }
}
 
Dogge_Skill.cs
using UnityEngine;
using UnityEngine.UI;
public class Dogge_Skill : Skill
{
    [Header("Dodge")]
    [SerializeField] private UI_SkillTreeSlot unlockDoggeButton;
    [SerializeField] private int evasionAmount;
    public bool doggeUnlocked;
    [Header("Mirage dodge")]
    [SerializeField] private UI_SkillTreeSlot unlockMirageDoggeButton;
    public bool dodgemirageUnlocked;
    protected override void Start()
    {
        base.Start();
        unlockDoggeButton.GetComponent<Button>().onClick.AddListener(UnlockDodge);
        unlockMirageDoggeButton.GetComponent<Button>().onClick.AddListener(UnlockMirageDogge);
    }
    private void UnlockDodge()
    {
        if (unlockDoggeButton.unlocked && !doggeUnlocked)
        {
            player.stats.evasion.AddModifier(evasionAmount);
            Inventory.instance.UpdateStatsUI();
            doggeUnlocked = true;
        }
    }
    private void UnlockMirageDogge()
    {
        if (unlockMirageDoggeButton.unlocked)
            dodgemirageUnlocked = true;
    }
    public void CreateMirageOnDoDogge()
    {
        if (dodgemirageUnlocked)
            SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);
    }
}
 
                

















