Game development summary-implementing a selected visual indicator in Unity

Game development summary-implementing a selected visual indicator in Unity

Creating logic to display and indicate whether a game object is focused requires the use of renderer bounds. In my ARPG I want to create an indicator that shows if the target object is focused, like in the Wind Waker game, you can see the result below.
Insert image description here

The above is the final effect

For the shader, I created a new shadergraph in which billboarding was implemented: In a previous article, I talked about how to create billboard in a shadergraph. Then for the texture I used two rotated squares to create a sagittal point and offset the UV positions using a sine function.
I then created a controller to set the visual element itself. It needs to be set on top of the target object, so it's best to use the target object's renderer object and use its bounds to get the target position. To do this, we get the center of the object's bounds (vector 3) and then replace the y element of this vector 3 (the height) with the maximum y value of the object's bounds. Then, since we are rendering on a quad, we need to add half of the quad's local dimensions to float the quad above the target object.
Now you just need to add some logic in your controller to enable the VisualSelectionController and call SetToTarget.
Please note: We use GetComponentInChildren here because the object does not necessarily have its renderer at the top of its hierarchy.

using UnityEngine;

public class VisualSelectionController : MonoBehaviour
{
    
    
    [SerializeField]
    private Renderer _mRenderer = null;

    private void Awake()
    {
    
    
        if (_mRenderer == null)
        {
    
    
            _mRenderer = GetComponent<Renderer>();
            
        }

    }

    private void OnEnable()
    {
    
    
        _mRenderer.enabled = true;

    }

    private void OnDisable()
    {
    
    
        _mRenderer.enabled = false;

    }

    public void SetToTarget(Transform targetObject)
    {
    
    
        transform.parent = targetObject;

        // 尝试获取渲染器并将位置设置为边界的顶部
        Renderer targetRenderer = null;

        targetRenderer = targetObject.GetComponentInChildren<Renderer>(false);
        //mTargetObject.TryGetComponent<Renderer>(out targetRenderer);

        if (targetRenderer == null)
        {
    
    
            Debug.Log("No renderer found");

        } else
        {
    
    
            Vector3 tempPos = targetRenderer.bounds.center;
            tempPos.y = targetRenderer.bounds.max.y + transform.localScale.y * 0.5f;

            transform.position = tempPos;

        }
    }
}

Guess you like

Origin blog.csdn.net/qq_37270421/article/details/130003146