You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:将旧NGUI相机旋转事件代码适配Unity新UI(Canvas)

旧NGUI相机旋转UI事件改造为Unity新UI(Canvas)实现

问题描述

我从网上下载了一款控制器,但其UI采用旧版NGUI方法开发。这段代码用于实现相机旋转功能,我无法理解其中的EventListeners逻辑,恳请帮助将Awake函数改造为Unity新UI(Canvas)的写法。

原NGUI代码

private void Awake()
{
    UIEventListener uIEventListener = rotateAreaBtn;
    uIEventListener.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener.onPress, new UIEventListener.BoolDelegate(OnPressArea));
    UIEventListener uIEventListener2 = rotateAreaBtn;
    uIEventListener2.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener2.onDrag, new UIEventListener.VectorDelegate(OnDragCam));
}

public void OnDragCam(GameObject obj, Vector2 deta)
{
    dragDeta = deta;
    isDrag = true;
    PlayerController.instance.fireTarget = null;
    if (PlayerController.instance.curState == PLAYERSTATE.FIGHT)
    {
        PlayerController.instance.ChangeState(PLAYERSTATE.NORMAL);
    }
    else if (PlayerController.instance.curState != PLAYERSTATE.CAR && (PlayerController.instance.animaCtl.isAimFlag || PlayerController.instance.animaCtl.needToAimFlag))
    {
        PlayerController.instance.ChangeState(PlayerController.instance.curState);
    }
}

public void OnPressArea(GameObject obj, bool press)
{
    isPress = press;
    if (!press)
    {
        dragDeta = Vector2.zero;
    }
}

改造为Unity新UI的实现

Unity新UI(UGUI)使用标准事件接口替代NGUI的UIEventListener,以下是改造后的完整代码:

using UnityEngine;
using UnityEngine.EventSystems;

public class CameraRotateController : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    // 若旋转区域是单独的UI对象,可保留此引用;否则直接将脚本挂载到旋转区域UI上即可
    // public GameObject rotateAreaBtn;

    private Vector2 dragDeta;
    private bool isPress;
    private bool isDrag;

    // 按下UI时触发
    public void OnPointerDown(PointerEventData eventData)
    {
        OnPressArea(gameObject, true);
    }

    // 抬起UI时触发
    public void OnPointerUp(PointerEventData eventData)
    {
        OnPressArea(gameObject, false);
    }

    // 拖拽UI时触发
    public void OnDrag(PointerEventData eventData)
    {
        OnDragCam(gameObject, eventData.delta);
    }

    // 原拖拽逻辑保留不变
    public void OnDragCam(GameObject obj, Vector2 deta)
    {
        dragDeta = deta;
        isDrag = true;
        PlayerController.instance.fireTarget = null;
        if (PlayerController.instance.curState == PLAYERSTATE.FIGHT)
        {
            PlayerController.instance.ChangeState(PLAYERSTATE.NORMAL);
        }
        else if (PlayerController.instance.curState != PLAYERSTATE.CAR && (PlayerController.instance.animaCtl.isAimFlag || PlayerController.instance.animaCtl.needToAimFlag))
        {
            PlayerController.instance.ChangeState(PlayerController.instance.curState);
        }
    }

    // 原按下/抬起逻辑保留不变
    public void OnPressArea(GameObject obj, bool press)
    {
        isPress = press;
        if (!press)
        {
            dragDeta = Vector2.zero;
        }
    }
}

关键逻辑说明

  • 原NGUI的UIEventListener.onPress对应新UI的IPointerDownHandler(按下)和IPointerUpHandler(抬起)接口,通过两个方法分别触发按下/抬起状态
  • 原NGUI的UIEventListener.onDrag对应新UI的IDragHandler接口,eventData.delta就是拖拽的增量偏移,和原代码的deta参数功能一致
  • 无需再在Awake中手动绑定事件,只要类实现对应的接口,Unity会自动处理事件监听
  • 确保场景中存在EventSystem对象(创建Canvas时Unity会自动生成,若缺失需手动添加)

内容的提问来源于stack exchange,提问作者Abdul Rehman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:40:19