unity打包PC端 右边的按钮点击没有反应

今天打包PC后,运行发现右边的按钮点击一次后就无法再点击了
unity :2021版本
解决方法;
在这里插入图片描述
下面是脚本代码:

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


/// <summary>
/// 修复UnityUGui中Canvas画布在Windows平台宽高比过长(横屏拉很长)导致UI的最右边一部分无法被点击的Buv,现发现与2021.3.x版本 by:黄敏 2022.11.9
/// </summary>
public class GraphicRaycasterBugFixedByHm : GraphicRaycaster
{
    [NonSerialized] private List<Graphic> m_RaycastResults2 = new List<Graphic>();
    private Canvas m_Canvas2;

    private Canvas canvas2
    {
        get
        {
            if (m_Canvas2 != null)
                return m_Canvas2;

            m_Canvas2 = GetComponent<Canvas>();
            return m_Canvas2;
        }
    }
    /// <summary>
    /// Perform the raycast against the list of graphics associated with the Canvas.
    /// </summary>
    /// <param name="eventData">Current event data</param>
    /// <param name="resultAppendList">List of hit objects to append new results to.</param>
    public override void Raycast(PointerEventData eventData, List<RaycastResult> resultAppendList)
    {
        if (canvas2 == null)
            return;

        var canvasGraphics = GraphicRegistry.GetRaycastableGraphicsForCanvas(canvas2);
        if (canvasGraphics == null || canvasGraphics.Count == 0)
            return;

        int displayIndex;
        var currentEventCamera = eventCamera; // Property can call Camera.main, so cache the reference

        if (canvas2.renderMode == RenderMode.ScreenSpaceOverlay || currentEventCamera == null)
            displayIndex = canvas2.targetDisplay;
        else
            displayIndex = currentEventCamera.targetDisplay;

        var eventPosition = Display.RelativeMouseAt(eventData.position);//MultipleDisplayUtilities.RelativeMouseAtScaled(eventData.position);
        if (eventPosition != Vector3.zero)
        {
            // We support multiple display and display identification based on event position.

            int eventDisplayIndex = (int)eventPosition.z;

            // Discard events that are not part of this display so the user does not interact with multiple displays at once.
            if (eventDisplayIndex != displayIndex)
                return;
        }
        else
        {
            // The multiple display system is not supported on all platforms, when it is not supported the returned position
            // will be all zeros so when the returned index is 0 we will default to the event data to be safe.
            eventPosition = eventData.position;

#if UNITY_EDITOR
            if (Display.activeEditorGameViewTarget != displayIndex)
                return;
            eventPosition.z = Display.activeEditorGameViewTarget;
#endif

            // We dont really know in which display the event occured. We will process the event assuming it occured in our display.
        }

        // Convert to view space
        Vector2 pos;
        if (currentEventCamera == null)
        {
            // Multiple display support only when not the main display. For display 0 the reported
            // resolution is always the desktops resolution since its part of the display API,
            // so we use the standard none multiple display method. (case 741751)
            float w = Screen.width;
            float h = Screen.height;
            if (displayIndex > 0 && displayIndex < Display.displays.Length)
            {
                w = Display.displays[displayIndex].systemWidth;
                h = Display.displays[displayIndex].systemHeight;
            }
            pos = new Vector2(eventPosition.x / w, eventPosition.y / h);
        }
        else
            pos = currentEventCamera.ScreenToViewportPoint(eventPosition);

        // If it's outside the camera's viewport, do nothing
        if (pos.x < 0f || pos.x > 1f || pos.y < 0f || pos.y > 1f)
            return;

        float hitDistance = float.MaxValue;

        Ray ray = new Ray();

        if (currentEventCamera != null)
            ray = currentEventCamera.ScreenPointToRay(eventPosition);

        if (canvas2.renderMode != RenderMode.ScreenSpaceOverlay && blockingObjects != BlockingObjects.None)
        {
            float distanceToClipPlane = 100.0f;

            if (currentEventCamera != null)
            {
                float projectionDirection = ray.direction.z;
                distanceToClipPlane = Mathf.Approximately(0.0f, projectionDirection)
                    ? Mathf.Infinity
                    : Mathf.Abs((currentEventCamera.farClipPlane - currentEventCamera.nearClipPlane) / projectionDirection);
            }
#if PACKAGE_PHYSICS
 
            if (blockingObjects == BlockingObjects.ThreeD || blockingObjects == BlockingObjects.All)
            {
                if (ReflectionMethodsCache2.Singleton.raycast3D != null)
                {
                    var hits = ReflectionMethodsCache2.Singleton.raycast3DAll(ray, distanceToClipPlane, (int)m_BlockingMask);
                    if (hits.Length > 0)
                        hitDistance = hits[0].distance;
                }
            }
#endif
#if PACKAGE_PHYSICS2D
 
 
            if (blockingObjects == BlockingObjects.TwoD || blockingObjects == BlockingObjects.All)
            {
                if (ReflectionMethodsCache2.Singleton.raycast2D != null)
                {
                    var hits = ReflectionMethodsCache2.Singleton.getRayIntersectionAll(ray, distanceToClipPlane, (int)m_BlockingMask);
                    if (hits.Length > 0)
                        hitDistance = hits[0].distance;
                }
            }
#endif
        }

        m_RaycastResults2.Clear();

        Raycast2(canvas2, currentEventCamera, eventPosition, canvasGraphics, m_RaycastResults2);

        int totalCount = m_RaycastResults2.Count;
        for (var index = 0; index < totalCount; index++)
        {
            var go = m_RaycastResults2[index].gameObject;
            bool appendGraphic = true;

            if (ignoreReversedGraphics)
            {
                if (currentEventCamera == null)
                {
                    // If we dont have a camera we know that we should always be facing forward
                    var dir = go.transform.rotation * Vector3.forward;
                    appendGraphic = Vector3.Dot(Vector3.forward, dir) > 0;
                }
                else
                {
                    // If we have a camera compare the direction against the cameras forward.
                    var cameraForward = currentEventCamera.transform.rotation * Vector3.forward * currentEventCamera.nearClipPlane;
                    appendGraphic = Vector3.Dot(go.transform.position - currentEventCamera.transform.position - cameraForward, go.transform.forward) >= 0;
                }
            }

            if (appendGraphic)
            {
                float distance = 0;
                Transform trans = go.transform;
                Vector3 transForward = trans.forward;

                if (currentEventCamera == null || canvas2.renderMode == RenderMode.ScreenSpaceOverlay)
                    distance = 0;
                else
                {
                    // http://geomalgorithms.com/a06-_intersect-2.html
                    distance = (Vector3.Dot(transForward, trans.position - ray.origin) / Vector3.Dot(transForward, ray.direction));

                    // Check to see if the go is behind the camera.
                    if (distance < 0)
                        continue;
                }

                if (distance >= hitDistance)
                    continue;

                var castResult = new RaycastResult
                {
                    gameObject = go,
                    module = this,
                    distance = distance,
                    screenPosition = eventPosition,
                    displayIndex = displayIndex,
                    index = resultAppendList.Count,
                    depth = m_RaycastResults2[index].depth,
                    sortingLayer = canvas2.sortingLayerID,
                    sortingOrder = canvas2.sortingOrder,
                    worldPosition = ray.origin + ray.direction * distance,
                    worldNormal = -transForward
                };
                resultAppendList.Add(castResult);
            }
        }
    }
    /// <summary>
    /// Perform a raycast into the screen and collect all graphics underneath it.
    /// </summary>
    [NonSerialized] static readonly List<Graphic> s_SortedGraphics2 = new List<Graphic>();
    private static void Raycast2(Canvas canvas, Camera eventCamera, Vector2 pointerPosition, IList<Graphic> foundGraphics, List<Graphic> results)
    {
        // Necessary for the event system
        int totalCount = foundGraphics.Count;
        for (int i = 0; i < totalCount; ++i)
        {
            Graphic graphic = foundGraphics[i];

            // -1 means it hasn't been processed by the canvas, which means it isn't actually drawn
            if (!graphic.raycastTarget || graphic.canvasRenderer.cull || graphic.depth == -1)
                continue;

            if (!RectTransformUtility.RectangleContainsScreenPoint(graphic.rectTransform, pointerPosition, eventCamera, graphic.raycastPadding))
                continue;

            if (eventCamera != null && eventCamera.WorldToScreenPoint(graphic.rectTransform.position).z > eventCamera.farClipPlane)
                continue;

            if (graphic.Raycast(pointerPosition, eventCamera))
            {
                s_SortedGraphics2.Add(graphic);
            }
        }

        s_SortedGraphics2.Sort((g1, g2) => g2.depth.CompareTo(g1.depth));
        totalCount = s_SortedGraphics2.Count;
        for (int i = 0; i < totalCount; ++i)
            results.Add(s_SortedGraphics2[i]);

        s_SortedGraphics2.Clear();
    }
}


public class ReflectionMethodsCache2
{
#if PACKAGE_PHYSICS
 
    public delegate bool Raycast3DCallback(Ray r, out RaycastHit hit, float f, int i);
    public delegate RaycastHit[] RaycastAllCallback(Ray r, float f, int i);
    public delegate int GetRaycastNonAllocCallback(Ray r, RaycastHit[] results, float f, int i);
 
    public Raycast3DCallback raycast3D = null;
    public RaycastAllCallback raycast3DAll = null;
    public GetRaycastNonAllocCallback getRaycastNonAlloc = null;
#endif

#if PACKAGE_PHYSICS2D
 
    public delegate RaycastHit2D Raycast2DCallback(Vector2 p1, Vector2 p2, float f, int i);
    public delegate RaycastHit2D[] GetRayIntersectionAllCallback(Ray r, float f, int i);
    public delegate int GetRayIntersectionAllNonAllocCallback(Ray r, RaycastHit2D[] results, float f, int i);
 
    public Raycast2DCallback raycast2D = null;
    public GetRayIntersectionAllCallback getRayIntersectionAll = null;
    public GetRayIntersectionAllNonAllocCallback getRayIntersectionAllNonAlloc = null;
#endif
    // We call Physics.Raycast and Physics2D.Raycast through reflection to avoid creating a hard dependency from
    // this class to the Physics/Physics2D modules, which would otherwise make it impossible to make content with UI
    // without force-including both modules.
    //
    // *NOTE* If other methods are required ensure to add [RequiredByNativeCode] to the bindings for that function. It prevents
    //        the function from being stripped if required. See Dynamics.bindings.cs for examples (search for GraphicRaycaster.cs).
    public ReflectionMethodsCache2()
    {
#if PACKAGE_PHYSICS
 
        var raycast3DMethodInfo = typeof(Physics).GetMethod("Raycast", new[] { typeof(Ray), typeof(RaycastHit).MakeByRefType(), typeof(float), typeof(int) });
        if (raycast3DMethodInfo != null)
            raycast3D = (Raycast3DCallback)Delegate.CreateDelegate(typeof(Raycast3DCallback), raycast3DMethodInfo);
 
        var raycastAllMethodInfo = typeof(Physics).GetMethod("RaycastAll", new[] { typeof(Ray), typeof(float), typeof(int) });
        if (raycastAllMethodInfo != null)
            raycast3DAll = (RaycastAllCallback)Delegate.CreateDelegate(typeof(RaycastAllCallback), raycastAllMethodInfo);
 
        var getRaycastAllNonAllocMethodInfo = typeof(Physics).GetMethod("RaycastNonAlloc", new[] { typeof(Ray), typeof(RaycastHit[]), typeof(float), typeof(int) });
        if (getRaycastAllNonAllocMethodInfo != null)
            getRaycastNonAlloc = (GetRaycastNonAllocCallback)Delegate.CreateDelegate(typeof(GetRaycastNonAllocCallback), getRaycastAllNonAllocMethodInfo);
#endif
#if PACKAGE_PHYSICS2D
 
        var raycast2DMethodInfo = typeof(Physics2D).GetMethod("Raycast", new[] { typeof(Vector2), typeof(Vector2), typeof(float), typeof(int) });
        if (raycast2DMethodInfo != null)
            raycast2D = (Raycast2DCallback)Delegate.CreateDelegate(typeof(Raycast2DCallback), raycast2DMethodInfo);
 
        var getRayIntersectionAllMethodInfo = typeof(Physics2D).GetMethod("GetRayIntersectionAll", new[] { typeof(Ray), typeof(float), typeof(int) });
        if (getRayIntersectionAllMethodInfo != null)
            getRayIntersectionAll = (GetRayIntersectionAllCallback)Delegate.CreateDelegate(typeof(GetRayIntersectionAllCallback), getRayIntersectionAllMethodInfo);
 
        var getRayIntersectionAllNonAllocMethodInfo = typeof(Physics2D).GetMethod("GetRayIntersectionNonAlloc", new[] { typeof(Ray), typeof(RaycastHit2D[]), typeof(float), typeof(int) });
        if (getRayIntersectionAllNonAllocMethodInfo != null)
            getRayIntersectionAllNonAlloc = (GetRayIntersectionAllNonAllocCallback)Delegate.CreateDelegate(typeof(GetRayIntersectionAllNonAllocCallback), getRayIntersectionAllNonAllocMethodInfo);
#endif
    }

    private static ReflectionMethodsCache2 s_ReflectionMethodsCache = null;

    public static ReflectionMethodsCache2 Singleton
    {
        get
        {
            if (s_ReflectionMethodsCache == null)
                s_ReflectionMethodsCache = new ReflectionMethodsCache2();
            return s_ReflectionMethodsCache;
        }
    }
}
### Unity 打包 EXE 文件教程 在 Unity 中将项目打包成 `.exe` 文件是一个常见的需求,尤其是在开发 PC 游戏或应用程序时。以下是关于如何完成这一过程的详细介绍: #### 使用 Unity 自带功能进行打包 Unity 提供了内置的功能用于生成 Windows 平台上的 `.exe` 可执行文件。通过 Build Settings 窗口可以轻松实现此目标。 1. **设置平台为目标设备** 在 Unity 编辑器中打开 `File -> Build Settings...`,然后选择 `Standalone` 作为目标平台,并点击 `Switch Platform` 完成切换[^2]。 2. **配置场景列表** 在同一窗口中,确保要包含的所有场景都已添加到构建队列中。如果某些必要场景未被选中,则可以通过点击 `Add Open Scenes` 将当前打开的场景加入其中。 3. **指定输出路径并启动构建** 返回至 `Build Settings` 界面后,点击底部的 `Build` 按钮。此时会弹出对话框提示您输入保存位置与名称;选定合适的目录之后即可正式开始编译工作。 4. **最终产物说明** 成功完成后,在所定义的目标地址处应该能够找到新生成的应用程序主体——即扩展名为`.exe` 的主运行档桉以及若干辅助资料档案(如 DLL 动态链接库 和其他媒体素材),它们共同构成了完整的发布版本。 #### 利用第三方工具增强分发效果 尽管上述方法已经足以满足基本需求,但在实际部署过程中可能还需要额外考虑用户体验优化等问题。因此引入专门设计用来制作安装向导类别的外部插件就显得尤为重要了。 例如采用 Inno Setup 或 NSIS 这样的开源解决方案可以帮助开发者进一步封装原始数据集成为更加友好的单一入口形式 —— 即标准意义上的 “setup.exe”。具体操作如下所示: 1. 首先下载并安装所需的脚本引擎环境; 2. 创建一个新的工程实例并向其导入先前由 Unity 输出的内容集合; 3. 根据个人喜好调整界面样式参数设定诸如图标更换、欢迎词定制等功能选项; 4. 经过充分测试验证无误后再安排上线发行事宜[^3]。 另外值得注意的是还有像 Enigma Virtual Box 这样专注于保护知识产权免受非法篡改侵害的产品可供选用。它允许我们将整个项目压缩加密处理过后再转换为单独的一个可移植型二进制单元以便于携带分享同时也提高了安全性级别[^1]。 ```python import os from pathlib import Path def check_build_directory(path_to_check): """Check if the build directory contains necessary files.""" required_files = ['game.exe', 'data.dll'] path_obj = Path(path_to_check) all_files = [f.name for f in path_obj.iterdir() if f.is_file()] missing = any(file not in all_files for file in required_files) return False if missing else True # Example usage of function to validate a built project folder. result = check_build_directory('C:/path/to/your/build') print(f"Is your build complete? {result}") ``` 以上就是有关怎样利用 Unity 来生产适用于桌面系统的独立执行文档的相关指导信息及其后续改进措施建议。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值