Unity类银河战士恶魔城学习总结(P141 Finalising ToolTip优化UI显示)

news2024/11/25 2:47:41

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

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

UI部分暂时完结!!!

本章节优化了UI中物品描述的显示效果,技能描述的显示效果

并且可以批量化更改文本描述

主要通过更改继承实现

UI_ToolTip.cs

以下脚本都不同程度改变了继承

脚本功能概述

  • 提示框位置动态调整: 根据鼠标位置动态调整提示框的位置,避免提示框超出屏幕边界。
  • 字体大小调整: 根据提示框内文本的长度动态调整字体大小,以适配长文本。

方法 1: AdjustPosition()

  • 功能:
    动态调整提示框位置,避免提示框超出屏幕边界。

  • 关键逻辑:
    • mousePosition.x > xLimit
      如果鼠标靠近屏幕右侧,提示框会向左偏移(-xOffset);否则向右偏移(+xOffset)。
    • mousePosition.y > yLimit
      如果鼠标靠近屏幕顶部,提示框会向下偏移(-yOffset);否则向上偏移(+yOffset)。
    • transform.position
      更新提示框的位置为鼠标位置加偏移量的坐标。

方法 2: AdjustFontSize(TextMeshProUGUI _text)

  • 功能:
    根据文本长度动态调整字体大小,防止长文本溢出。
  • 关键逻辑:
    • 如果文本长度大于12个字符,字体大小缩小至80%。
    • 使用TextMeshProUGUI(Unity的高级文本组件)处理文本渲染,支持复杂的文本特效。
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;


//2024.11.22  
//szq
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()
    {
        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);//更新提示框位置为鼠标位置偏移后的点
    }


    public void AdjustFontSize(TextMeshProUGUI _text)//根据文本长度调整字体大小
    {
        if(_text.text.Length > 12 )
            _text.fontSize = _text.fontSize * .8f;
    }
}

UI_SkillToolTip.cs

using TMPro;
using UnityEngine;

public class UI_SkillToolTip : UI_ToolTip
{
    [SerializeField] private TextMeshProUGUI skillText;//显示技能描述的文本组件
    [SerializeField] private TextMeshProUGUI skillName;
    [SerializeField] private TextMeshProUGUI skillCost;
    [SerializeField] private float defaultNameFontSize;

    public void ShowToolTip(string _skillDescprtion, string _skillName,int _price)//显示工具提示
    {
        skillName.text = _skillName;
        skillText.text = _skillDescprtion;
        skillCost.text = "Cost: " + _price;

        AdjustPosition();

        AdjustFontSize(skillName);

        gameObject.SetActive(true);
    }

    public virtual void HideToolTip() //隐藏工具提示
    {
        skillName.fontSize = defaultNameFontSize;
        gameObject.SetActive(false);
    }
}

UI_ItemTooltip.cs

using TMPro;
using UnityEngine;

//2024年11月14日
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)//于显示工具提示,当玩家鼠标悬停在物品上时调用
    {
        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 TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

//物品数量的UI,放在ItemSlot上
// p105添加了Grad Layout Group,自动排列


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>();//获取UI组件
    }

    public void UpdataSlot(InventoryItem _newitem)//更新物品槽
    {
        item = _newitem;// 传入的新物品

        itemImage.color = Color.white;//获取了物品,itemslot透明变成白色,变得可见

        if (item != null)//列表中的物体不是空的
        {
            itemImage.sprite = item.data.icon;//获得图标

            if (item.stackSize > 1)
            {
                itemText.text = item.stackSize.ToString();//显示堆叠数量
            }
            else
            {
                itemText.text = "";//不显示数量
            }
        }
    }

    public void CleanUpSlot()清空物品槽
    {
        item = null;// 将物品槽内物品设为空

        itemImage.sprite = null;// 清除物品图标
        itemImage.color = Color.clear;// 让物品槽变得不可见

        itemText.text = ""; // 清空堆叠数量的显示
    }



    public virtual void OnPointerDown(PointerEventData eventData)//拾取之后点击物品,改成virtual之后可以被子类重写
    {
        if (item == null)//如果物品槽为空
            return;


        if (Input.GetKey(KeyCode.LeftControl))
        {
            Inventory.instance.RemoveItem(item.data);//移除物品
            return;
        }

        if (item.data.itemType == ItemType.Equipment)// 如果点击的物品是装备类型
            Inventory.instance.EquipItem(item.data);//装备物品

        ui.itemToolTip.HideToolTip();//隐藏物品详情
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        if(item == null)
            return;

        ui.itemToolTip.ShowToolTIp(item.data as ItemData_Equipment);//显示物品详情

    }

    public void OnPointerExit(PointerEventData eventData)
    {
        if (item == null)
            return;

        ui.itemToolTip.HideToolTip();//隐藏物品详情
    }
}

ItemData_Equipment.cs

using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;


//2024年11月1日
public enum EquipmentType
{
    Weapon,
    Armor,
    Amulet,//护身符
    Flask//药水瓶
}

[CreateAssetMenu(fileName = "New Item Data", menuName = "Data/Equipment")]//因为继承了ItemData,所以在资源管理器中创建新的Item,创建的物品自带这个脚本

public class ItemData_Equipment : ItemData
{
    public EquipmentType equipmentType;

    [Header("独特效果")]
    public float itemCoolDown;//物品冷却时间
    public ItemEffect[] itemEffects;//可以添加物品的效果
    


    [Header("主属性")]
    public int strength;//力量,1点增加1攻击力和%1爆伤
    public int agility;//敏捷,1点增加1%闪避和%1暴击率
    public int intelligence;//智力,1点增加1法术强度和%1魔抗
    public int vitality;//活力,1点增加3生命值


    [Header("攻击属性")]
    public int damage;
    public int critChance;//暴击率
    public int critPower;//暴击伤害,默认%150



    [Header("防守属性")]
    public int maxHealth;
    public int armor;//护甲
    public int evasion;//闪避
    public int magicResistance;//魔抗


    [Header("魔法属性")]
    public int fireDamage;
    public int iceDamage;
    public int lightningDamage;


    [Header("制作需求")]//Craft requirements
    public List<InventoryItem> craftingMaterials;

    private int descriptionLength;


    public void Effect(Transform _enemyPositon)//执行物品效果
    {
        foreach (var item in itemEffects)
        {
            item.ExcuteEffect(_enemyPositon);
        }
    }


    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.maxHealth.AddModifier(maxHealth);
        playerStats.armor.AddModifier(armor);
        playerStats.evasion.AddModifier(evasion);
        playerStats.magicResistance.AddModifier(magicResistance);

        playerStats.fireDamage.AddModifier(fireDamage);
        playerStats.iceDamage.AddModifier(iceDamage);
        playerStats.lightingDamage.AddModifier(lightningDamage);
    }

    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.maxHealth.RemoveModifier(maxHealth);
        playerStats.armor.RemoveModifier(armor);
        playerStats.evasion.RemoveModifier(evasion);
        playerStats.magicResistance.RemoveModifier(magicResistance);

        playerStats.fireDamage.RemoveModifier(fireDamage);
        playerStats.iceDamage.RemoveModifier(iceDamage);
        playerStats.lightingDamage.RemoveModifier(lightningDamage);

    }


    public override string GetDescription()
    {
        sb.Length = 0;//确保每次调用时是从头开始
        descriptionLength = 0;//重置描述的属性数量

        AddItemDescription(strength, "力量");
        AddItemDescription(agility, "敏捷");
        AddItemDescription(intelligence, "智力");
        AddItemDescription(vitality, "活力");

        AddItemDescription(damage, "伤害");
        AddItemDescription(critChance, "暴击率");
        AddItemDescription(critPower, "暴击伤害");

        AddItemDescription(maxHealth, "生命值");
        AddItemDescription(armor, "护甲");
        AddItemDescription(evasion, "闪避");
        AddItemDescription(magicResistance, "魔抗");

        AddItemDescription(fireDamage, "火焰伤害");
        AddItemDescription(iceDamage, "冰霜伤害");
        AddItemDescription(lightningDamage, "闪电伤害");



        for(int i = 0; i < itemEffects.Length; i++)//遍历物品效果
        {
            if (itemEffects[i].effectDescription.Length>0)
            {
                sb.AppendLine();
                sb.Append("唯一:" + itemEffects[i].effectDescription);
                descriptionLength++;
            }
        }



        if (descriptionLength < 5)//确保最终返回的描述文本至少有 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(_name+";"+_value);
                sb.Append("+ " + _value + " " + _name);//添加属性描述


            descriptionLength++;//每成功添加一个属性
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2247033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oracle的静态注册和动态注册

oracle的静态注册和动态注册 静态注册&#xff1a; 静态注册 : 指将实例的相关信息手动告知 listener 侦 听 器 &#xff0c; 可以使用netmgr,netca,oem 以及直接 vi listener.ora 文件来实现静态注册&#xff0c;在动态注册不稳定时使用&#xff0c;特点是&#xff1a;稳定&…

社交电商专业赋能高校教育与产业协同发展:定制开发AI智能名片及2+1链动商城小程序的创新驱动

摘要&#xff1a;本文围绕社交电商有望成为高校常态专业这一趋势展开深入探讨&#xff0c;剖析国家政策认可下其学科发展前景&#xff0c;着重阐述在专业建设进程中面临的师资短缺及实践教学难题。通过引入定制开发AI智能名片与21链动商城小程序&#xff0c;探究如何借助这些新…

数据指标与标签在数据分析中的关系与应用

导读&#xff1a;分享数据指标体系的文章很多&#xff0c;但讲数据标签的文章很少。实际上&#xff0c;标签和指标一样&#xff0c;是数据分析的左膀右臂&#xff0c;两者同样重要。实际上&#xff0c;很多人分析不深入&#xff0c;就是因为缺少对标签的应用。今天系统的讲解下…

使用Electron将vue2项目打包为桌面exe安装包

目录 一、下载electron模板项目 【electron-quick-start】​ 二、打开项目&#xff0c;安装所有依赖 三、在打exe包的时候报错是因为没有&#xff0c;需要检查并安装之后重新打包&#xff1b; 四、经过这么疯狂的一波操作之后&#xff0c;就可以打包出你想要的exe安装包&am…

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

Linux之NFS共享文件操作

一、注意点 以下操作使用root用户 代理端需要访问服务端的2049、111端口二、nfs下载 # 服务端和代理端都要安装 yum –y install rpcbind yum –y install nfs-utils三、配置共享目录-【服务端】 *修改/etc/exports文件&#xff0c;追加以下内容 /home/app_adm/test ip1(in…

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云

C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用-腾讯云开发者社区-腾讯云 C#学习笔记——窗口停靠控件WeifenLuo.WinFormsUI.Docking使用 发布于 2021-06-10 00:10:59 7.1K0 举报 文章被收录于专栏&#xff1a;c#学习笔记 一、介绍 DockPanelSuite是托管在…

杰发科技AC7840——EEP中RAM的配置

sample和手册中示例代码的sram区地址定义不一样 这个在RAM中使用没有限制&#xff0c;根据这个表格留下足够空间即可 比如需要4096字节的eep空间&#xff0c;可以把RAM的地址改成E000&#xff0c;即E000-EFFF&#xff0c;共4096bytes即可。

web-03

CSS回顾 选择器 标签选择器 标签{}ID选择器 标签中定义ID属性。 #ID值{}类选择器 标签中使用class属性 .类名{}关于DIV/span div任意的大小的长方形&#xff0c;大小css&#xff1a; width, height控制。—换行 span-- 一行内 CSS常用属性 width/height 宽度/高度 定义&…

CI配置项,IT服务的关键要素

随着现今数字经济的不断发展&#xff0c;逐渐成熟的IT 基础设施已不再是简单的竞争优势&#xff0c;而已成为企业生存和发展的基石。然而&#xff0c;仅仅拥有强大的基础设施是不够的。为了保障 IT 服务的平稳运行和持续交付&#xff0c;企业还需要重点关注 IT 服务的核心构建模…

ApiChain-编写迭代单测用例

项目地址&#xff1a;ApiChain 项目主页 写单测用例&#xff0c;就像画一幅有向不循环的图&#xff0c;图中的每个节点是这个单测用例的每一个步骤&#xff0c;连线代表着数据的流向&#xff0c;这幅图通常有一个或者多个起点&#xff0c;但通常只有一个终点。起点的数据来源于…

九、FOC原理详解

1、FOC简介 FOC&#xff08;field-oriented control&#xff09;为磁场定向控制&#xff0c;又称为矢量控制&#xff08;vectorcontrol&#xff09;&#xff0c;是目前无刷直流电机&#xff08;BLDC&#xff09;和永磁同步电机&#xff08;PMSM&#xff09;高效控制的最佳选择…

企业OA管理系统:Spring Boot技术实现与案例研究

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了企业OA管理系统的开发全过程。通过分析企业OA管理系统管理的不足&#xff0c;创建了一个计算机管理企业OA管理系统的方案。文章介绍了企业OA管理系统的系统分析部…

【tensorflow的安装步骤】

创建一个虚拟环境 conda create -n tensorflow python3.6激活虚拟环境 conda activate tensorflow使用镜像源下载 pip install tensorflow1.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/特别特别重要的点&#xff01;&#xff01;&#xff01; 别用WiFi或者校园网下…

网络安全-web架构-nginx配置

1. nginx访问&#xff1a; 访问的是index.html&#xff0c; 访问ip访问的资源就是在/usr/share/nginx/html中&#xff1b; 当nginx不认识&#xff0c;浏览器认识的话&#xff0c;浏览器会自动渲染。 当nginx认识&#xff0c;浏览器不认识的话&#xff0c;浏览器会把它加载成…

ES6 模块化语法

目录 ES6 模块化语法 分别暴露 统一暴露 ​编辑 默认暴露 ES6 模块化引入方式 ES6 模块化语法 模块功能主要由两个命令构成&#xff1a;export 和 import。 ⚫ export 命令用于规定模块的对外接口&#xff08;哪些数据需要暴露&#xff0c;就在数据前面加上关键字即可…

基于Java Springboot高校洗浴管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

stm32如何接收舵机的控制信号(而不是控制舵机)

看到很多如何stm32用pwm信号控制舵机的文章,老生常谈了 我来写一个stm32接收pwm信号的例子 ,这个pwm信号是用来控制舵机的 背景: 我需要接收航模接收机的,用来控制舵机的pwm信号, 得到这个信号后,做其他事情. 初版代码 pwm.h#ifndef _pwm_H #define _pwm_H#include "s…

Postman之pm.test断言操作

系列文章目录 1.Postman之安装及汉化基本使用介绍 2.Postman之变量操作 3.Postman之数据提取 4.Postman之pm.test断言操作 5.Postman之newman Postman之pm.test断言操作 1.断言方法2.连接符3.条件判断符 用于验证请求的响应数据是否符合预期 1.断言方法 pm.test()&#xff1a;…

MySQL面试题补

内连接和外连接的区别&#xff1a; ○1.功能和用法不同&#xff1a;内连接是连接两表都满足情况的数据&#xff1b;而外连接是以一边的表为主表&#xff0c;另一个表只显示匹配的行&#xff1b; ○2.用途&#xff1a;内连接一般是用于检索不同表需要根据共同的列值进行匹配的&a…