Unity 获取点的法线方向实现吸附效果

通过HTCVive手柄发射射线控制物体的吸附效果,类似于帖在墙壁上的画框。

1.首先编写手柄上的控制类:SteamVRControllerBase。通过手柄射线获得碰撞点的位置和法线方向

using UnityEngine;
using System.Collections;

public class SteamVRControllerBase : MonoBehaviour {

    public static SteamVRControllerBase getInstance;
    private Transform sphere;          //点的位置,使用一个小球
    private Vector3 sphereNormal = Vector3.zero;      //点的法线方向

    private void Awake()
    {
        getInstance = this;
        sphere = transform.Find("Sphere");
    }

    RaycastHit hitInfo;
    private void FixedUpdate()
    {
        Ray ray = new Ray(transform.position, transform.forward);
        if (Physics.Raycast(ray, out hitInfo, 1000f))
        {
            sphere.position = hitInfo.point;         //复制位置
            sphereNormal = hitInfo.normal;           //获得法线方向
        }
    }
    //获取位置来控制画框的位置
    public Transform GetSphereTrans()
    {
        return sphere.transform;
    }
    //获取法线方向
    public Vector3 GetSphereNormal()
    {
        return sphereNormal;
    }
}

2.给画框添加吸附的控制类:AdsorbController。这样画框就能根据碰撞点的位置及时的吸附在墙壁上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MoveController))]
public class AdsorbController : MonoBehaviour {

    private Collider col;                 //通过碰撞体获得大小
    private Vector3 Velocity=Vector3.zero;
    private float smoothTime =0.1f;

    private Vector3 length;                 //物体长宽高

    private void Start()
    {
        col = GetComponent();
        length = col.bounds.size;
    }
    private void Update()
    {
        Vector3 targetPos = SteamVRControllerBase.getInstance.GetSphereTrans().position;
        //法线的起点需要向前移动半个物体宽度的距离,因为画框中心点在中间位置,否则会嵌入一半墙体
        targetPos = new Vector3(targetPos.x- (length.x * transform.lossyScale.x)/2, targetPos.y, targetPos.z);
        //使用阻尼函数平滑移动效果
        transform.position = Vector3.SmoothDamp(transform.position, targetPos,ref Velocity, smoothTime);         
        Vector3 direction = SteamVRControllerBase.getInstance.GetSphereNormal();         //获取法线方向
        Debug.DrawRay(transform.position, direction);       //画出法线,用来测试
        transform.forward = direction;               //让画框前方与法线方向一致
    }
}


你可能感兴趣的:(Unity3D)