Unity SKFramework框架(十)、AimableObject 物体交互系统

2022-08-29 17:12:53 浏览数 (1)

一、Aimable Object

为场景中需要进行交互的物体挂载AimableObject组件:

Description属性表示该物体的描述信息,AimableDistance属性表示该物体可被瞄准检测到的距离,通过OnEnter、OnExit、OnStay分别为该交互物体设置瞄准进入事件、瞄准退出事件、瞄准停留事件,也可以通过继承AimableObject类,来重写这些事件,如下所示:

代码语言:javascript复制
using UnityEngine;
using SK.Framework;

public class Example : AimableObject
{
    protected override void OnEnter()
    {
        //TODO
    }
    protected override void OnStay()
    {
        //TODO
    }
    protected override void OnExit()
    {
        //TODO
    }
}

二、Aim System

瞄准交互系统的核心,需要在场景中挂载该组件:

Toggle表示整个系统的开关,将其设为false后,系统将不再进行瞄准检测,MainCamera是用于瞄准检测的相机,AimLayer表示检测的层级,AimMaxDistance表示检测的最大距离,AimMode表示瞄准的方式,包含两种,一种是Mouse,使用鼠标的位置发出射线进行瞄准检测,当我们的相机是自由视角、上帝视角时,通常使用这种方式;另一种则是View Centre,通过屏幕的中心点发出射线进行瞄准检测,当我们的相机是第一人称或第三人称视角时,通常使用这种方式。需要注意,当AimMode为ViewCentre模式时,AimMaxDistance属性才起作用。

除此之外,AimSystem中的核心属性还包括CurrentAimableObject,它记录了当前所瞄准的物体:

代码语言:javascript复制
/// <summary>
/// 当前瞄准的物体
/// </summary>
public IAimableObject CurrentAimableObject { get; private set; }

三、示例

上例中,我们在物体的瞄准进入事件里添加了一个物体高亮的效果,并且通过一个Text文本来显示该物体的描述信息,在瞄准退出事件里隐藏物体的高亮效果,并将Text文本清空。实现过程如下:

代码语言:javascript复制
using UnityEngine;
using SK.Framework;

public class Example : AimableObject
{
    [SerializeField] AimView view;

    protected override void OnEnter()
    {
        //显示物体高亮效果
        GetComponent<HighlightOutline>().enabled = true;
        //显示描述信息
        view.OnEnter(description, transform.position);
    }
    protected override void OnExit()
    {
        //隐藏物体高亮效果
        GetComponent<HighlightOutline>().enabled = false;
        //清空描述信息
        view.OnExit();
    }
}

将Example挂载于各个可交互物体,并填写各自的Description描述信息

代码语言:javascript复制
using UnityEngine;
using UnityEngine.UI;

public class AimView : MonoBehaviour
{
    //用于显示描述信息的文本
    [SerializeField] Text descriptionText;

    public void OnEnter(string description, Vector3 worldPos)
    {
        //描述信息
        descriptionText.text = description;
        //世界坐标转屏幕坐标 更新文本位置
        Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
        descriptionText.rectTransform.anchoredPosition3D = screenPos;
    }
    public void OnExit()
    {
        descriptionText.text = null;
    }
}

注意Text文本的锚点和轴心点的设置:

AimMode使用的是Mouse模式:

0 人点赞