Unity拖拽箭头

 目录

目录

一.参考文章:

二.目标

三.贝塞尔曲线

1.箭头优化

2.箭头指向

3.箭头缩放

四.从卡牌中心拖出

五.指向敌人变色

六.完整工程


一.参考文章:

游戏开发教程:如何实现杀戮尖塔中的选择箭头 (这篇讲的很详细了)

从零开始学图形学:10分钟看懂贝塞尔曲线

河流,道路,UI工具,贝塞尔曲线实战应用

二.目标

实现杀戮尖塔的拖拽箭头:

1.贝塞尔曲线

2.从卡牌中心拖出

3.指向敌人变色

最终效果:

演示

三.贝塞尔曲线

看到这个箭头第一反应就是很像钢笔工具,然后搜了一下,就知道了是贝塞尔曲线

具体什么是贝塞尔曲线我就给别人的链接吧,没啥必要在这复制黏贴:

从零开始学图形学:10分钟看懂贝塞尔曲线

河流,道路,UI工具,贝塞尔曲线实战应用
最终代码(三阶):

        /// <summary>
        /// 三阶贝塞尔曲线
        /// </summary>
        /// <param name="t"></param>
        /// <param name="controlP">0:起始点 1:控制点1 2:控制点2 3:重点</param>
        /// <returns></returns>
        private Vector2 ThirdOrderBezierCurve(float t, Vector2[] controlP) {
            Vector2 res = new Vector2();
            if (controlP.Length != 4) {
                Debug.LogWarning("三阶贝塞尔坐标需要4个,ThirdOrderBezierCurve");
                return res;
            }

            float u = 1 - t;

            float partx0 = controlP[0].x * u * u * u;
            float partx1 = 3 * t * u * u * controlP[1].x;
            float partx2 = 3 * t * t * u * controlP[2].x;
            float partx3 = t * t * t * controlP[3].x;
            float x = partx0 + partx1 + partx2 + partx3;
            res.x = x;

            float party0 = controlP[0].y * u * u * u;
            float party1 = 3 * t * u * u * controlP[1].y;
            float party2 = 3 * t * t * u * controlP[2].y;
            float party3 = t * t * t * controlP[3].y;
            float y = party0 + party1 + party2 + party3;
            res.y = y;

            return res;
        }

        /// <summary>
        /// 获取贝塞尔曲线[三阶]
        /// </summary>
        /// <param name="originPoint">0:起始点 1:控制点 2:终点</param>
        /// <param name="stepNum">需要获取的节点数</param>
        /// <returns></returns>
        public List<Vector2> CreateThirdOrderCurve(Vector2[] originPoint, uint stepNum) {
            if (originPoint.Length != 4) {
                Debug.LogWarning("三阶贝塞尔坐标需要4个,请检查CreateThirdOrderCurve");
                return new List<Vector2>();
            }

            List<Vector2> CurvePointList = new List<Vector2>();

            float u = 1;
            float CurveStep = 1 / (float) stepNum;
            while (u > 0) {
                Vector2 Point = ThirdOrderBezierCurve(u, originPoint);
                CurvePointList.Add(Point);
                u = u - CurveStep;
            }

            CurvePointList.Add(originPoint[0]);

            return CurvePointList;
        }

1.箭头优化

主要有几个吧:箭头指向,箭头缩放

2.箭头指向

这个只要后一个指向前一个就行,最后一个就和前一个保持一致就行:

//旋转
if (index > 0) 
{
    Vector3 vec3_angle = m_ArrowStem[index - 1].transform.position - item.transform.position;
    Vector2 vec2_angle = new Vector2(vec3_angle.x, vec3_angle.y);
    var Euler = new Vector3(0, 0, Vector2.SignedAngle(Vector2.up, vec2_angle));
    item.transform.rotation = Quaternion.Euler(Euler);
}

//对大箭头特殊处理
m_ArrowStem[0].transform.rotation = m_ArrowStem[1].transform.rotation;

3.箭头缩放

直接贴代码吧,主要是选函数,手动调:

//缩放
float ScaleDivisor = Mathf.Log((int) CONST_STEP_NUM - index + 1, CONST_LOG_DIVISOR);
item.transform.localScale = new Vector3(ScaleDivisor, ScaleDivisor, ScaleDivisor) * CONST_SCALE_DIVISOR;

四.从卡牌中心拖出

这里主要是卡牌不是按钮,所以需要重写一下IPointerDownHandler,在鼠标按下的时候生成箭头就行。因为只是展示功能不想这么麻烦,所以我没有用生成,直接把场景中的箭头显示出来了。

//CardItem.cs
private void SetArrowStartPoint() {
    var RectTransform = gameObject.GetComponent<RectTransform>();
    Vector3[] Corners = new Vector3[4];
    RectTransform.GetWorldCorners(Corners);
    float x = Corners[0].x + (Corners[3].x - Corners[0].x) / 2;
    float y = Corners[0].y + (Corners[1].y - Corners[0].y) / 2;
    Vector3 StartPosition = new Vector3(x, y, 0);
    m_DragArrowItem.SetStartPoint(StartPosition);
}

private void InitClickEvent() {
    m_ClickCard.PointerDownEvent = () => {
        go_Arrow.SetActive(true);
        SetArrowStartPoint();
    };
}

//ClickCard .cs
public class ClickCard : MonoBehaviour, IPointerDownHandler{
    private Action m_PointerDownEvent;

    public Action PointerDownEvent {
        set => m_PointerDownEvent = value;
    }

    public void OnPointerDown(PointerEventData eventData) {
        m_PointerDownEvent?.Invoke();
    }
}

五.指向敌人变色

这边分情况吧,正常来说敌人是场景物体之类的,那只要发射射线就行。不过杀戮尖塔目测是live2d这种,这种算是UI,平常射线是检测不到的。所以我用的方法是UI射线穿透,通过点击事件向下发射线,找到鼠标下的其他UI,挂在卡牌UI上就行。射线穿透的话可以去看一下雨凇大佬的教程。

//  ClickCard : MonoBehaviour , IDragHandler
public void OnDrag(PointerEventData eventData) {
    List<RaycastResult> raycastResults = new List<RaycastResult>();
    EventSystem.current.RaycastAll(eventData, raycastResults);
    if (raycastResults.Count == 0) {
        m_RecoverEvent?.Invoke();
        return;
    }

    foreach (var rayResult in raycastResults) {
        if (rayResult.gameObject.tag == m_TargetName) {
            m_DragEvent?.Invoke();
            return;
        }
    }

    m_RecoverEvent?.Invoke();
}

六.完整工程

完整的我就贴这边吧,传github了:

完整工程

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity是一个功能强大的游戏引擎,可用于创建各种2D和3D游戏。在Unity中,拖拽旋转物体是一个常见的需求,可以通过以下步骤实现。 首先,通过添加组件将对象转化为可挂接的对象。可以挂接一个刚体组件或是使用物理引擎,也可以使用脚本控制其移动和旋转。 然后,鼠标右键单击对象,选择“3D对象”、“空物体”或“其他”选项。这将创建一个空对象,它将成为控制器。将控制器命名为“旋转控制器”。 接着,将对象拖到旋转控制器上,并将其调整到对象的中心点。这样一来,我们就可以通过拖拽旋转控制器来旋转对象。还可以通过缩放控制器来改变对象的大小,通过移动控制器来移动对象。 最后,在脚本中添加代码来控制旋转控制器。例如,可以编写代码使控制器沿着Y轴旋转,或根据鼠标的拖拽来旋转控制器。还可以使用键盘控制器来旋转控制器。 以上步骤可帮助你在Unity中实现拖拽旋转物体的效果。掌握了这些技能,你将能够创建出更加复杂而精彩的游戏。 ### 回答2: Unity拖拽旋转物体非常简单。首先,我们需要在场景中创建一个物体,比如一个立方体。然后,我们将其选择并拖拽到层次结构视图中。接着,我们点击场景视图中的立方体,从而选择它。 现在,我们可以在场景视图中看到三个箭头。分别是红、绿和蓝色的箭头,代表了物体在空间中的X、Y和Z轴。我们可以通过拖拽这些箭头来移动物体,也可以通过点击物体旁边的圆圈来旋转物体。我们可以按住鼠标左键来旋转物体,也可以按住鼠标右键来平移物体。按住鼠标中键可以放大和缩小物体。 如果需要更精确的控制,我们可以使用GameObject菜单中的旋转和平移选项,或者使用快捷键W(移动)、E(旋转)和R(缩放)。 总之,Unity拖拽旋转物体非常方便,可以通过鼠标和快捷键来进行控制,从而快速创建我们需要的场景。 ### 回答3: Unity引擎是一款非常强大的游戏开发引擎,它支持多种交互功能,其中最基本的是拖拽和旋转物体。 拖拽物体需要用到Unity的Transform组件,它是每个游戏物体上都有的组件。拖拽物体,首先需要确保选中了合适的物体,并且该物体的Transform组件被打开。在场景视图中点击选中该物体,然后可以通过点击并拖拽标识该物体的小圆圈,来将物体移动到新的位置。同时,可以在Inspector面板中手动修改该物体的Position属性值来实现位置的修改。 旋转物体也需要用到Transform组件。在场景视图中选中需要旋转的物体,在该物体的Transform组件中找到Rotation属性。通过手动修改该属性的值或者直接在场景视图中点击并拖动物体上的小圆球来旋转物体。 需要注意的是,旋转的方向会根据圆球的位置而不同,例如,在圆球上方旋转时,物体会围绕X轴旋转;在圆球左边旋转时,物体会围绕Y轴旋转;在圆球前方旋转时,物体会围绕Z轴旋转。 以上就是Unity拖拽旋转物体的基本操作方法。通过这些方法,可以轻松实现游戏物体的移动和旋转功能,为游戏开发带来更多的交互性和用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值