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

项目02《游戏-08-开发》Unity3D

基于      项目02《游戏-07-开发》Unity3D      ,

本次任务做物品相互与详情的功能,

首先要做 点击相应,

接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象,

双击PackageCell.cs脚本修改代码:添加鼠标响应接口,

三个接口分别对鼠标的点击,进入,退出事件,

Alt + Enter 实现这三个接口,

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
    Transform UIIcon;
    Transform UIHead;
    Transform UINew;
    Transform UISelect;
    Transform UILevel;
    Transform UIStars;
    Transform UIDeleteSelect;

    //动态数据
    PackageLocalItem packageLocalData;
    //静态数据
    PackageTableItem packageTableItem;
    //父物体也就是PackagePanel本身
    PackagePanel uiParent;

    void Awake(){
        InitUIName();
    }
    void InitUIName(){
        UIIcon = transform.Find("Top/Icon");
        UIHead = transform.Find("Top/Head");
        UINew = transform.Find("Top/New");
        UILevel = transform.Find("Bottom/LevelText");
        UIStars = transform.Find("Bottom/Stars");
        UISelect = transform.Find("Select");
        UIDeleteSelect = transform.Find("DeleteSelect");

        UIDeleteSelect.gameObject.SetActive(false);
    }
    //刷新
    public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
        //数据初始化
        this.packageLocalData = packageLocalData;
        this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
        this.uiParent = uiParent;
        //等级信息
        UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
        //是否是新获得?
        UINew.gameObject.SetActive(this.packageLocalData.isNew);
        Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
        //物品的图片
        Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
        if (t != null){
            Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
            // 继续处理 Sprite 对象
            UIIcon.GetComponent<Image>().sprite = temp;
        }
        else{
            // 处理纹理加载失败的情况
            Debug.LogError("Failed to load texture.");
        }
        //刷新星级
        RefreshStars();
    }
    //刷新星级
    public void RefreshStars(){
        for (int i = 0; i < UIStars.childCount; i++){
            Transform star = UIStars.GetChild(i);
            if (this.packageTableItem.star > i)
                star.gameObject.SetActive(true);
            else
                star.gameObject.SetActive(false);
        }
    }

    public void OnPointerClick(PointerEventData eventData){
        Debug.Log($"OnPointerClick {eventData.ToString()}");
    }

    public void OnPointerEnter(PointerEventData eventData){
        Debug.Log($"OnPointerEnter {eventData.ToString()}");
    }

    public void OnPointerExit(PointerEventData eventData){
        Debug.Log($"OnPointerExit {eventData.ToString()}");
    }
}
回到unity编辑器中,

运行项目当我们鼠标悬停在武器Icon上就会有输出显示,

下一步是处理点击事件具体响应逻辑,

当鼠标点击物品时,右侧的详情界面会根据物品的信息进行刷新,

DetailPanel是PackagePanel下的子物体,也是我们要处理的对象,我们要对DetailPanel详情界面进行更新,

所以我们在Scripts脚本文件夹中添加一个脚本PackageDetail.cs用来更新详情界面DetailPanel对象,

然后将PackageDetail.cs脚本绑定在DetailPanel对象身上,

类似于上集的PackageCell逻辑,我们可以把DetailPanel也当作一个独立的对象进行处理,

双击PackagDetail.cs脚本修改代码:

using UnityEngine;
using UnityEngine.UI;

public class PackageDetail : MonoBehaviour{
    Transform UIStars;
    Transform UIDescription;
    Transform UIIcon;
    Transform UITitle;
    Transform UILevelText;
    Transform UISkillDescription;

    PackageLocalItem packageLocalData;
    PackageTableItem packageTableItem;
    PackagePanel uiParent;

    void Awake(){
        InitUIName();
        Test();
    }
    void Test() {
        Refresh(MainGame.Instance.GetPackageLocalData()[1], null);
    }
    void InitUIName(){
        UIStars = transform.Find("Center/Stars");
        UIDescription = transform.Find("Center/Description");
        UIIcon = transform.Find("Center/Icon");
        UITitle = transform.Find("Top/Title");
        UILevelText = transform.Find("Bottom/LevelPnl/LevelText");
        UISkillDescription = transform.Find("Bottom/Description");
    }
    public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent) {
        //初始化:动态数据,静态数据,父物品逻辑
        this.packageLocalData = packageLocalData;
        this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
        this.uiParent = uiParent;
        //等级
        UILevelText.GetComponent<Text>().text = string.Format($"Lv.{this.packageLocalData.level.ToString()}");
        //简短描述
        UIDescription.GetComponent<Text>().text = this.packageTableItem.description;
        //详细描述
        UISkillDescription.GetComponent<Text>().text = this.packageTableItem.skillDescription;
        //物品名称
        UITitle.GetComponent<Text>().name = this.packageTableItem.name;
        //图片加载
        Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
        Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
        UIIcon.GetComponent<Image>().sprite = temp;
        //星级处理
        RefreshStars();
    }
    public void RefreshStars(){
        for (int i = 0; i < UIStars.childCount; i++) {
            Transform star = UIStars.GetChild(i);
            if(this.packageTableItem.star > i)
                star.gameObject.SetActive(true);
            else
                star.gameObject.SetActive(false);
        }
    }
}
回到unity编辑器中,运行项目可见详情页面被替换成

测试方法的第二张图片,

下一步要做的事情是当点击某个物品时,详情界面会根据鼠标点击的物品进行展示,

打开PackagePanel.cs脚本修改代码: 这是背包的主题逻辑部分

当前选中的物品总要被记录,把记录的地方放在PackagePanel中,

using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
    Transform UIMenu;
    Transform UIMenuWeapon;
    Transform UIMenuFood;
    Transform UITabName;
    Transform UICloseBtn;
    Transform UICenter;
    Transform UIScrollView;
    Transform UIDetailPanel;
    Transform UILeftBtn;
    Transform UIRightBtn;
    Transform UIDeletePanel;
    Transform UIDeleteBackBtn;
    Transform UIDeleteInfoText;
    Transform UIDeleteConfirmBtn;
    Transform UIBottomMenus;
    Transform UIDeleteBtn;
    Transform UIDetailBtn;

    //添加
    public GameObject PackageUIItemPrefab;

    //添加 表示当前选中的物品时哪一个uid
    string _chooseUid;
    public string ChooseUid {
        get { return _chooseUid; }
        set {
            _chooseUid = value;
            RefreshDetail();
        }
    }
    void RefreshDetail() {
        //找到uid对应的动态数据
        PackageLocalItem localItem = MainGame.Instance.GetPackageLocalItemByUId(ChooseUid);
        //刷新详情界面
        UIDetailPanel.GetComponent<PackageDetail>().Refresh(localItem, this);
    }
    override protected void Awake(){
        base.Awake();
        InitUI();
    }
    //添加1
    void Start(){
        RefreshUI();
    }
    //添加1
    void RefreshUI(){
        RefreshScroll();
    }
    //添加1
    void RefreshScroll(){
        //清理滚动容器中原本的物品
        RectTransform scrollContent = UIScrollView.GetComponent<ScrollRect>().content;
        for (int i = 0; i < scrollContent.childCount; i++)
            Destroy(scrollContent.GetChild(i).gameObject);
        //获取本地数据的方法拿到自己身上背包数据 并且根据背包数据初始化滚动容器
        foreach (PackageLocalItem localData in MainGame.Instance.GetSortPackageLocalData()){
            Transform PackageUIItem = Instantiate(PackageUIItemPrefab.transform, scrollContent) as Transform;

            PackageCell packageCell = PackageUIItem.GetComponent<PackageCell>();
            //添加2
            packageCell.Refresh(localData, this);
        }
    }
    void InitUI(){
        InitUIName();
        InitClick();
    }
    void InitUIName(){
        UIMenu = transform.Find("TopCenter/Menu");
        UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
        UIMenuFood = transform.Find("TopCenter/Menus/Food");
        UITabName = transform.Find("LeftTop/TabName");
        UICloseBtn = transform.Find("RightTop/Close");
        UICenter = transform.Find("Center");
        UIScrollView = transform.Find("Center/Scroll View");
        UIDetailPanel = transform.Find("Center/DetailPanel");
        UILeftBtn = transform.Find("Left/Button");
        UIRightBtn = transform.Find("Right/Button");

        UIDeletePanel = transform.Find("Bottom/DeletePanel");
        UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
        UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
        UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
        UIBottomMenus = transform.Find("Bottom/BottomMenus");
        UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
        UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");

        UIDeletePanel.gameObject.SetActive(false);
        UIBottomMenus.gameObject.SetActive(true);
    }
    void InitClick(){
        UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
        UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
        UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
        UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
        UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);

        UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
        UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
        UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
        UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
    }

    void OnDetail(){
        print(">>>>>>> OnDetail()");
    }
    void OnDelete(){
        print(">>>>>>> OnDelete()");
    }
    void OnDeleteConfirm(){
        print(">>>>>>> OnDeleteConfirm()");
    }
    void OnDeleteBack(){
        print(">>>>>>> OnDeleteBack()");
    }
    void OnClickRight(){
        print(">>>>>>> OnClickRight()");
    }
    void OnClickLeft(){
        print(">>>>>>> OnClickLeft()");
    }
    void OnClickWeapon(){
        print(">>>>>>> OnClickWeapon()");
    }
    void OnClickFood(){
        print(">>>>>>> OnClickFood()");
    }
    void OnClickClose(){
        ClosePanel();
    }
}
因为物品的逻辑是写在PackageCell.cs脚本中,

那么找到PackageCell点击的回调方法,

也就是OnPointerClick()方法,

修改PackageCell.cs脚本:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
    Transform UIIcon;
    Transform UIHead;
    Transform UINew;
    Transform UISelect;
    Transform UILevel;
    Transform UIStars;
    Transform UIDeleteSelect;

    //动态数据
    PackageLocalItem packageLocalData;
    //静态数据
    PackageTableItem packageTableItem;
    //父物体也就是PackagePanel本身
    PackagePanel uiParent;

    void Awake(){
        InitUIName();
    }
    void InitUIName(){
        UIIcon = transform.Find("Top/Icon");
        UIHead = transform.Find("Top/Head");
        UINew = transform.Find("Top/New");
        UILevel = transform.Find("Bottom/LevelText");
        UIStars = transform.Find("Bottom/Stars");
        UISelect = transform.Find("Select");
        UIDeleteSelect = transform.Find("DeleteSelect");

        UIDeleteSelect.gameObject.SetActive(false);
    }
    //刷新
    public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
        //数据初始化
        this.packageLocalData = packageLocalData;
        this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
        this.uiParent = uiParent;
        //等级信息
        UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
        //是否是新获得?
        UINew.gameObject.SetActive(this.packageLocalData.isNew);
        Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
        //物品的图片
        Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
        if (t != null){
            Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
            // 继续处理 Sprite 对象
            UIIcon.GetComponent<Image>().sprite = temp;
        }
        else{
            // 处理纹理加载失败的情况
            Debug.LogError("Failed to load texture.");
        }
        //刷新星级
        RefreshStars();
    }
    //刷新星级
    public void RefreshStars(){
        for (int i = 0; i < UIStars.childCount; i++){
            Transform star = UIStars.GetChild(i);
            if (this.packageTableItem.star > i)
                star.gameObject.SetActive(true);
            else
                star.gameObject.SetActive(false);
        }
    }

    public void OnPointerClick(PointerEventData eventData){
        if (this.uiParent.ChooseUid == this.packageLocalData.uid)
            return;
        //根据点击设置最新的uid 进而刷新详情界面
        this.uiParent.ChooseUid = this.packageLocalData.uid;
    }

    public void OnPointerEnter(PointerEventData eventData){
        Debug.Log($"OnPointerEnter {eventData.ToString()}");
    }

    public void OnPointerExit(PointerEventData eventData){
        Debug.Log($"OnPointerExit {eventData.ToString()}");
    }
}
回到unity编辑器中运行项目,点开背包点击物品查看详情页面的更新,

已实现点击背包物品更换详情页面,

下一步实现UI动画点击效果动画,

首先在ACs动画控制器文件包中创建一个UI文件夹准备放UI动画,

在UI文件夹中创建两个PackageAC背包控制器,

其中PackageAC1代表鼠标掠过的动画控制器,PackageAC2代表鼠标选中的动画控制器,

在PackageItem预制体空间下创建两个空物体,

设置尺寸,

设置子物体Image为拉伸模式

重命名Image为Image1,并设置比例为1.1

再创建Image2,同样设置比例为1.2,拉伸模式

同样添加选中图片,

接下来在ACs的UI文件夹中创建动画Animation,命名为PackageSelectAni

在这个文件夹再创建两个动画,分别对应 鼠标进入物品 和 退出物品 的效果,

下一步绑定组件Animator,将PackageAC1拖拽给 选中对象,

打开PackageAC1动画控制器,将PackageSelectAni动画拖拽在动画控制器中,

创建一个空状态并连线,

然后添加Trigger类型的变量,

接着双击打开Animation这个窗口,

选中设置谁的动画,

同样添加Image2的color,

点击左上角的红点即可进入录制模式,点击播放修改两个image的d颜色为0,再次点击结束录制即可,

同样方法绑定鼠标点击对象组件Animator并拖拽PackageAC2,

双击PackageAC2进入动画控制器,并拖拽其余两个动画,

还是把默认条件设置为空状态,

然后创建两个转换变量In 和 Out,用来设置切换鼠标进入与鼠标退出,

对于MouseOverAni这个对象添加一个Image,并设置大小,拉伸模式

我们先将SelectAni隐藏,

还是添加一个color,

1.点击录制,

2.拖动动画线到中间,设置color d 为 0,

3.调试:

4.结束录制,

同样手法配置PackageMouseOut动画,

提醒:In的动画color透明度变化是 0 - 1 - 0,而Out的动画color透明度变化是 1 - 0,

           Select的动画为 0.5 - 1-0.5 - 0,总之最后透明度均为0,

动画控制器设置完成,

下一步修改PackageCell.cs脚本:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
    Transform UIIcon;
    Transform UIHead;
    Transform UINew;
    Transform UISelect;
    Transform UILevel;
    Transform UIStars;
    Transform UIDeleteSelect;

    //添加
    Transform UISelectAni;
    Transform UIMouseOverAni;

    //动态数据
    PackageLocalItem packageLocalData;
    //静态数据
    PackageTableItem packageTableItem;
    //父物体也就是PackagePanel本身
    PackagePanel uiParent;

    void Awake(){
        InitUIName();
    }
    void InitUIName(){
        UIIcon = transform.Find("Top/Icon");
        UIHead = transform.Find("Top/Head");
        UINew = transform.Find("Top/New");
        UILevel = transform.Find("Bottom/LevelText");
        UIStars = transform.Find("Bottom/Stars");
        UISelect = transform.Find("Select");
        UIDeleteSelect = transform.Find("DeleteSelect");
        //添加
        UIMouseOverAni = transform.Find("MouseOverAni");
        UISelectAni = transform.Find("SelectAni");

        UIDeleteSelect.gameObject.SetActive(false);
        //添加
        UIMouseOverAni.gameObject.SetActive(false);
        UISelectAni.gameObject.SetActive(false);
    }
    //刷新
    public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
        //数据初始化
        this.packageLocalData = packageLocalData;
        this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
        this.uiParent = uiParent;
        //等级信息
        UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
        //是否是新获得?
        UINew.gameObject.SetActive(this.packageLocalData.isNew);
        Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
        //物品的图片
        Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
        if (t != null){
            Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
            // 继续处理 Sprite 对象
            UIIcon.GetComponent<Image>().sprite = temp;
        }
        else{
            // 处理纹理加载失败的情况
            Debug.LogError("Failed to load texture.");
        }
        //刷新星级
        RefreshStars();
    }
    //刷新星级
    public void RefreshStars(){
        for (int i = 0; i < UIStars.childCount; i++){
            Transform star = UIStars.GetChild(i);
            if (this.packageTableItem.star > i)
                star.gameObject.SetActive(true);
            else
                star.gameObject.SetActive(false);
        }
    }

    public void OnPointerClick(PointerEventData eventData){
        if (this.uiParent.ChooseUid == this.packageLocalData.uid)
            return;
        //根据点击设置最新的uid 进而刷新详情界面
        this.uiParent.ChooseUid = this.packageLocalData.uid;
        UISelectAni.gameObject.SetActive(true);
        UISelectAni.GetComponent<Animator>().SetTrigger("In");
    }

    public void OnPointerEnter(PointerEventData eventData){
        UIMouseOverAni.gameObject.SetActive(true);
        UIMouseOverAni.GetComponent<Animator>().SetTrigger("In");
    }

    public void OnPointerExit(PointerEventData eventData){
        Debug.Log($"OnPointerExit {eventData.ToString()}");
    }
}
 

最后这个操作可以确保我们的子物品不会影响我们点触事件的判断,

运行项目即可实现,

鼠标滑动效果,

鼠标点击效果,

点击右上角×退出键即可退出面板,

End.

相关文章:

  • HarmonyOS鸿蒙ArkTS证件照生成模板(适合二次开发,全套源码版)
  • 面试复盘6——后端开发
  • 进程控制(Linux)
  • 【蓝桥杯冲冲冲】[NOIP2003 普及组] 栈
  • C++ 语法文件
  • 【Golang】exec.command命令日志输出示例
  • Linux常见面试题汇总
  • Java学习七、类和对象
  • AJAX-URL查询参数
  • 【机器学习】基于K-近邻的车牌号识别
  • spring boot bean的生命周期
  • 【高质量精品】2024美赛B题22页word版高质量半成品论文+多版保奖思路+数据+前四问思路代码等(后续会更新)
  • 杨中科 ASP.NETCORE 高级14 SignalR
  • Python循环语句——while循环的嵌套应用
  • 《Python 网络爬虫简易速速上手小册》第8章:分布式爬虫设计(2024 最新版)
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • java第三方包学习之lombok
  • java取消线程实例
  • java小心机(3)| 浅析finalize()
  • js递归,无限分级树形折叠菜单
  • Linux链接文件
  • Python 反序列化安全问题(二)
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • SOFAMosn配置模型
  • tensorflow学习笔记3——MNIST应用篇
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 基于Android乐音识别(2)
  • ------- 计算机网络基础
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 前端设计模式
  • 嵌入式文件系统
  • 微信小程序--------语音识别(前端自己也能玩)
  • 小程序开发中的那些坑
  • 一道面试题引发的“血案”
  • 在weex里面使用chart图表
  • AI算硅基生命吗,为什么?
  • 如何在招聘中考核.NET架构师
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #pragma 指令
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (C语言)逆序输出字符串
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (力扣)循环队列的实现与详解(C语言)
  • .net 获取url的方法
  • .NET 使用 XPath 来读写 XML 文件
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET是什么
  • .NET学习全景图
  • /*在DataTable中更新、删除数据*/