【unity】将技能拖入快捷栏

依旧是拖拽UI的功能。
这次是将UI拖入指定的位置。
主要实现的实际释放拖拽后的操作。
要实现的功能如下,以流程图形式展现:
请添加图片描述
——汉字写的不美观,就不拿出来献丑了。索性用英语写

该脚本挂载在技能Icon上面。

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

public class SkillItemIcon : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    /// <summary>
    /// 用于拖拽的预设体,创建被拖拽的副本
    /// </summary>
    public GameObject dragPrefab;
    /// <summary>
    /// 是否为副本,如果是原本,则创建副本,如果是副本,则直接拖拽,而不创建副本
    /// </summary>
    public bool isCopyRight = true;
    /// <summary>
    /// 是否曾经放入过快捷栏。如果放入过,则为true,此时将该物体拖出来则会放回原位而不是销毁。
    /// </summary>
    public bool didPutCutGrid = false;
    /// <summary>
    /// 当前正在被拖拽的对象
    /// </summary>
    private GameObject draggingItem;

    /// <summary>
    /// 物体的目前父物体
    /// </summary>
    private Transform nowParent;
    /// <summary>
    /// 图标的RectTransform组件
    /// </summary>
    private RectTransform rectTransform;
    /// <summary>
    /// Canvas组件,用于确定拖拽的缩放因子
    /// </summary>
    private Canvas canvas;
    private void Start()
    {
        rectTransform = GetComponent<RectTransform>(); // 获取图标的RectTransform组件
        canvas = GetComponentInParent<Canvas>(); // 获取父级Canvas组件

        //originalPosition = rectTransform.anchoredPosition; // 记录图标的初始位置
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (isCopyRight)
        {
            draggingItem = Instantiate(dragPrefab, transform.parent);
            draggingItem.GetComponent<SkillItemIcon>().isCopyRight = false;
        }
        else
        {
            draggingItem = gameObject;
        }

        if (draggingItem.transform.GetComponent<Image>().raycastTarget)
        {
            //让被拖拽的物体屏蔽射线检测,这样就能获得鼠标悬停下的UI对象
            draggingItem.transform.GetComponent<Image>().raycastTarget = false;
        }
        nowParent = draggingItem.transform.parent;  //nowparent为被拖拽物体的当前父物体        

        draggingItem.transform.SetParent(canvas.transform);//将当前拖拽的物体放在canvas下
                                                           //isRaycastPass = false;//设置ui可穿透

    }

    public void OnDrag(PointerEventData eventData)
    {
        draggingItem.transform.GetComponent<RectTransform>().anchoredPosition += eventData.delta / canvas.scaleFactor; // 根据鼠标移动更新图标位置
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        GameObject dropTarget = eventData.pointerCurrentRaycast.gameObject;
        if (dropTarget != null)
        {
            if (dropTarget.CompareTag(S_Tags.shortCutGrid)) // 当拖放到了一个空的格子里面
            {
                draggingItem.transform.SetParent(dropTarget.transform);
                //表示该物品曾经放入格子中过
                draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid = true;
            }
            else if (dropTarget.CompareTag(S_Tags.shortCut)) // 当拖放到了一个有物品的格子里面
            {
                if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
                {
                    //目标格子
                    Transform tmpTrans = dropTarget.transform.parent;
                    dropTarget.transform.SetParent(nowParent);
                    draggingItem.transform.SetParent(tmpTrans);
                    dropTarget.transform.localPosition = Vector3.zero;
                }
                else
                {
                    Destroy(draggingItem);
                    return;
                }
            }
            else
            {
                if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
                {
                    draggingItem.transform.SetParent(nowParent);
                }
                else
                {
                    Destroy(draggingItem);
                    return;
                }
            }
        }
        else
        {
            if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
            {
                draggingItem.transform.SetParent(nowParent);
            }
            else
            {
                Destroy(draggingItem);
                return;
            }
        }
        draggingItem.transform.GetComponent<Image>().raycastTarget = true;
        //isRaycastPass = true;//设置ui不可穿透

        ResetLocalPosition();

    }
    /// <summary>
    /// 被拖拽物体返回原位置
    /// </summary>
    private void ResetLocalPosition()
    {
        draggingItem.transform.localPosition = Vector3.zero;
        draggingItem.transform.SetAsFirstSibling();
    }
}

为了赶进度,目前先用这种方法实现想要的功能。日后将对该部分代码进行重构,消除冗余代码,找到更简便的逻辑思路。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity中的AOE技能是指Area of Effect技能,即范围效果技能。在Unity中,可以通过使用特定的图形或算法来实现AOE技能的范围指示效果。 引用提到了一个Demo,该Demo实现了类似王者荣耀的技能范围指示效果,包括普攻、定向、AOE范围圈、扇形模式和假扇形模式等几种效果。 引用提到了MOBA游戏中每个英雄都有自己的技能攻击范围方式,包括圆形范围、直线范围、扇形方天戟范围和矩形范围等等。这些范围形状可以通过Unity的图形绘制和碰撞检测来实现。 至于具体实现AOE技能的范围指示效果,可以使用Unity的碰撞检测功能结合特定的图形绘制方式来实现。例如,可以使用Unity的Collider组件来检测技能范围内的敌人,然后在场景中绘制出对应的范围效果,如圆形、扇形或矩形。另外,也可以使用Shader来实现特殊的效果,如光照或扭曲。 总之,Unity中的AOE技能的范围指示效果可以通过使用碰撞检测和图形绘制来实现,具体的实现方式可以根据游戏需求和设计来定制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [扇形、箭头、圆形范围AOE技能圈释放、控制模型](https://download.csdn.net/download/qq_23680543/10157976)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Unity 攻击范围检测](https://blog.csdn.net/a592733740/article/details/106291936)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值