Unity实现物件选中效果

发布时间 2023-03-30 21:23:08作者: dewxin


首先制作两个显示效果,一个是未被选中时的物件(Visual),一个是被选中时的物件(Focused)。
然后将这两个gameObject挂载到父节点上。创建C#代码CounterFocused添加为父节点的组件。

public class CounterFocused : MonoBehaviour
{
    [SerializeField]
    private GameObject NormalVisual;

    [SerializeField]
    private GameObject FocusedVisual;

    private void Start()
    {
        Debug.Assert(NormalVisual!= null);
        Debug.Assert(FocusedVisual!= null);

        DeFocus();
    }

    public void Focus()
    {
        NormalVisual.SetActive(false);
        FocusedVisual.SetActive(true);
    }

    public void DeFocus()
    {
        NormalVisual.SetActive(true);
        FocusedVisual.SetActive(false);
    }

}


然后将两个子节点拖入两个变量中。

在Player脚本中每帧检测角色对面是否有可以选中的物件。

    private void Update()
    {
        HandleMovement();

        TryFocusObj();
    }

    private void TryFocusObj()
    {
        if(IsFocusedObjSameAsOldOne(out CounterFocused counterFocused))
            return;

        ResetCounterFocused();

        if(counterFocused!= null)
        {
            this._counterFocused = counterFocused;
            this._counterFocused.Focus();
        }
    }

    private bool IsFocusedObjSameAsOldOne(out CounterFocused counterFocusedOut)
    {
        if (!Physics.Raycast(transform.position, transform.forward, out RaycastHit raycastHit, 2f))
        {
            counterFocusedOut = null;
            return false;
        }

        if (!raycastHit.transform.TryGetComponent(out CounterFocused counterFocused))
        {
            counterFocusedOut = null;
            return false;
        }

        counterFocusedOut = counterFocused;

        if (_counterFocused == null)
            return false;

        if (!_counterFocused.Equals(counterFocused))
            return false;

        return true;
    }

    private void ResetCounterFocused()
    {
        if(_counterFocused != null) 
            this._counterFocused.DeFocus();

        this._counterFocused = null;
    }