场景搭建
搭建如图的效果,需要实现的效果:将圆球拿到Cube范围内时,Cube范围高亮,如松下Grab键,圆球自动吸附到Cube所在位置。
吸附效果制作
- 在Project面板中,搜索SnapDropZone,将预制体拖动到Hierarchy面板中;
- 点击SnapDropZone,将场景中的黄绿色Cube拖动到SnapDropZone下的VRTK_SnapDropZone组件下的HightlightObjectPrefab上,如图
注释:场景中黄绿色的Cube只是用于检测"放过去高亮的形状",SnapDropZone作用是当检测到指定物体在该范围内,SnapDropZone高亮;
- 调整SnapDropZone位置,去掉黄绿色Cube的显示;
- 点击SnapDropZone,添加VRTK_PolicyList组件,将VRTK_PolicyList组件拖动到VRTK_SnapDropZone组件下的ValidObjectListPolicy上。
- 在SnapDropZone下的VRTK_PolicyList下添加Element0值(这里的值作用是只允许指定的Tag放在这个范围时候高亮)。
- 将场景中圆球添加Tag,testcube001
- 修改VRTK_PolicyList的Operation选项为Include
- 添加BoxCollider,通过调整Size,来控制需要放进来的范围具体大小;并勾选IsTrigger
- 调整VRTK_SnapDropZone下HighlightColor颜色,控制放过去后高亮的颜色
给圆球添加抓取
点击圆球,添加以下两个组件,并将VRTK_InteractableObject组件下的IsGrabbable选项勾选上
测试
对吸附事件做检测
以本案例为例,如需获取圆球是否进入到指定区域/离开指定区域/放置在指定位置/拿开在指定位置,可以通过在SnapDropZone预制体上添加"VRTK_SnapDroopZone_UnityEvents"组件,它下面的On Object Entered Snap Drop Zone等四个监控事件分别对应上述提到的四种触发动作。
注:以上的四种检测事件仅当物体进入/离开指定区域或指定位置时生效,默认情况下不会生效(即:当物体在默认位置还未进入到指定区域时,不会执行检测事件)
下面以两个案例进行讲解:
检测物体进入到指定区域
给SnapDropZone预制体添加VRTK_SnapDroopZone_UnityEvents组件,在SnapDropZone添加脚本TestSnap,程序片段如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestSnap : MonoBehaviour
{
public void TestSnapone()
{
Debug.Log("qqqqqqqqqqqqqqqqqqqqqqqqq");
}
}
在On Object Entered Snap Drop Zone添加检测事件,将SnapDropZone赋值给Object位置,脚本选择为新添加的TestSnap.TestSnapone,如下:
运行后,当物体在指定区域内,也就是说一旦高亮,就会输出qqqqqqqqqqqqqqqqqqqqqqqqq,达到预期效果。
检测多个物体放置在指定区域,触发其他事件
先说明一下逻辑:
(在每个物体上创建一个第三方脚本,存放一个bool类型值) -> 当物体进入到指定位置后,让该bool值为true -> 最后获取多个物体上的第三方脚本中的bool类型值 -> 如均为true -> 则触发指定事件
制作部分:
- 将之前创建的圆球复制一个出来,更改一下材质球便于区分;
- 复制SnapDropZone,修改VRTK_PolicyList中的Element0值,使指定圆球只能放在指定区域;
- 修改第二个圆球的tag;
- 在原SnapDropZone上添加脚本ControllerRedQiuBool,在类中写
publi
-
c bool a;
在另一SnapDropZone上添加脚本ControllerBlueQiuBool,添加同样的内容; - 在ControllerRedQiuBool脚本中,添加后的事件,ControllerBlueQiuBool脚本同理;
public void Snap()
{
a = true;
}
- 添加当物体放置在指定区域后的触发动作
- 在场景中添加一个空物体,添加PanDuan组件,用于判断当两物体指定脚本中的bool值均为true时,进行下一步触发动作,整体代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PanDuan : MonoBehaviour
{
public GameObject red;
public GameObject blue;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
bool _redBool = red.GetComponent<ControllerRedQiuBool>().a;
bool _blueBool = blue.GetComponent<ControllerBlueQiuBool>().a;
if (_redBool==false && _blueBool==false)
{
Debug.Log("NNNNNNNNNNNNNN");
}
if (_redBool==true && _blueBool==true)
{
Debug.Log("YYYYYYYYY");
}
}
}
- 运行调试,默认情况下,由于两物体指定的bool值为false,则默认输入NNNN并持续输出;当两物体其中一个bool值为true,则NNN停止输出;当两物体bool值均为true,则输出YYYYY;