【问题标题】:How to improve UI Selection logic?如何改进 UI 选择逻辑?
【发布时间】:2022-12-18 08:14:39
【问题描述】:

所以我有这段代码悬停时选择 UI 中的对象,并将当前悬停的元素存储在类范围内hoveredAction.

我觉得会有一个更优雅的方法这个逻辑。我知道如果光线投射对象与存储的对象相同,我可以再添加一项检查以避免一些计算,但“样板”else if (hoveredAction != null) 会持续存在。

这不是我第一次遇到这种逻辑,但这次很简单,我可以总结一下,任何想法都会有所帮助。

    void Update()
    {
        pointerEventData = new PointerEventData(eventSystem)
        {
            position = Input.mousePosition
        };
        List<RaycastResult> results = new();
        raycaster.Raycast(pointerEventData, results);
        if (results.Count > 0)
        {
            var result = results[0];
            var obj = allowedActions.Where(a => result.gameObject == a.UiObject.gameObject);
            if (obj.Count() > 0)
            {
                hoveredAction = obj.First();
                hoveredAction.UiObject.GetComponent<Image>().color = shown;
            }
            else if(hoveredAction != null)
            {
                hoveredAction.UiObject.GetComponent<Image>().color = hidden;
                hoveredAction = null;
            }
        }
        else if (hoveredAction != null) 
        {
            hoveredAction.UiObject.GetComponent<Image>().color = hidden;
            hoveredAction = null;
        }
    }

【问题讨论】:

    标签: c# unity3d logic


    【解决方案1】:

    请注意,您的这也不完整:在 if (obj.Count() &gt; 0) 的情况下,您还需要将任何先前的命中设置为 hidden ... 或者如果 previous hit == current 则跳过两者

    我会把它分开,只跟踪 newCurrent hit 和 do 例如

    void Update()
    {
        pointerEventData = new PointerEventData(eventSystem)
        {
            position = Input.mousePosition
        };
    
        List<RaycastResult> results = new();
    
        raycaster.Raycast(pointerEventData, results);
    
        // whenever you deal with linq make sure to iterate only once!
        Gamebject currentHoveredAction = results.Count == 0 ? null : allowedActions.Where(a => result.gameObject == a.UiObject.gameObject).FirstOrDefault();
    
        // This is 
        // - either you hit a different object than before
        // - you didn't hit anything before but do now
        // - or you did hit something before but nothing now
        if(hoveredAction != currentHoveredAction)
        {
            // if there is a previous hit reset it
            if (hoveredAction != null) 
            {
                hoveredAction.UiObject.GetComponent<Image>().color = hidden;
            }
    
            // if there is a current hit set it
            if(currentHoveredAction != null)
            {
                currentHoveredAction.UiObject.GetComponent<Image>().color = show; 
            }
    
            // either way store the new result
            hoveredAction = currentHoveredAction;
        }
    }
    

    【讨论】:

    • 正是我所要求的,完美无缺。也感谢 Linq 提醒。
    猜你喜欢
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多