使用Unity实现VR中在黑板上写字(升级篇)(二)----- 加入黑板擦

摘要:
黑板擦的功能其实和画笔是一样的,只是黑板擦设置的颜色是画板最原始的颜色,而笔设置的是其他的颜色。TheLab中的实现是,当黑板檫的中心点与画板的距离是黑板擦长边的0.5的时候,就开始插值,什么时候结束呢?

黑板擦的功能其实和画笔是一样的,只是黑板擦设置的颜色是画板最原始的颜色,而笔设置的是其他的颜色。

所以最大的不同时,当手柄握住黑板擦时和握住笔时的函数实现是不一样的;实现这个功能之后,黑板擦的擦掉功能将在后续的篇章中和画笔一起完成;

使用Unity实现VR中在黑板上写字(升级篇)(二)----- 加入黑板擦第1张

可以看到不管黑板擦以什么角度开始靠近画板,最终这个黑板擦一定是和画板平行的;

先看看画板的坐标系:

使用Unity实现VR中在黑板上写字(升级篇)(二)----- 加入黑板擦第2张

再看看黑板擦的坐标系:

使用Unity实现VR中在黑板上写字(升级篇)(二)----- 加入黑板擦第3张

也就是说不管黑板擦以何种旋转角度(Rotation)靠近黑板最终的结果就是:黑板擦的transform.up指向画板的 -transform.forward方向;而在靠近的过程中,根据靠近的距离,我们把这个Rotation进行插值就可以了;

现在的问题就是什么时候开始插值呢?The Lab中的实现是,当黑板檫的中心点与画板的距离是黑板擦长边的0.5的时候,就开始插值,什么时候结束呢?最简单的就是0的时候,但是因为我的黑板擦底部有个0.02m的黑色擦布,所以我的是0.02m时结束;

因此首先需要写一个映射函数:

public static classHelper
{
    /// <summary>
    ///用于比较两个Color32类型是不是一样
    /// </summary>
    /// <param name="origin"></param>
    /// <param name="compare"></param>
    /// <returns></returns>
    public static bool IsEqual(thisColor32 origin, Color32 compare)
    {
        if (origin.g == compare.g && origin.r ==compare.r)
        {
            if (origin.a == compare.a && origin.b ==compare.b)
            {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    ///把num在low1 ~ high1之间的位置,重新映射到low2 ~ high2之间,并限制返回值是low2 ~ high2之间的值;
    /// </summary>
    /// <param name="num"></param>
    /// <param name="low1"></param>
    /// <param name="high1"></param>
    /// <param name="low2"></param>
    /// <param name="high2"></param>
    /// <returns></returns>
    public static float RemapNumberClamped(float num, float low1, float high1, float low2, floathigh2)
    {
        returnMathf.Clamp(RemapNumber(num, low1, high1, low2, high2), Mathf.Min(low2, high2), Mathf.Max(low2, high2));
    }
    /// <summary>
    ///把num在low1 ~ high1之间时代表的值,映射到low2 ~ high2 之间所代表的值
    /// </summary>
    /// <param name="num"></param>
    /// <param name="low1"></param>
    /// <param name="high1"></param>
    /// <param name="low2"></param>
    /// <param name="high2"></param>
    /// <returns></returns>
    public static float RemapNumber(float num, float low1, float high1, float low2, floathigh2)
    {
        return low2 + (num - low1) * (high2 - low2) / (high1 -low1);
    }
}

当我们把num限制在0 ~1 的时候,我们就得到了插值系数;当从0.096开始插值,从0.02结束插值,黑板檫距离画板的距离时0.047,重新映射后,结果为0.5;

现在可以写黑板檫的Grab Attach 机制了:

升级篇(一)中已经完成了Painter的Grab Attach机制,只要直接重写它的ProcessFixedUpdate函数就可以了;

usingUnityEngine;
public classEraserGrabAttach : PainterGrabAttach
{
    public override voidProcessFixedUpdate()
    {
        if (grabbedObject)//只有抓住物体后,grabbedObject才不会
{
            grabbedObject.transform.rotation = controllerAttachPoint.transform.rotation *Quaternion.Euler(grabbedSnapHandle.transform.localEulerAngles);
            grabbedObject.transform.position = controllerAttachPoint.transform.position - (grabbedSnapHandle.transform.position -grabbedObject.transform.position);
            float distance = board.GetDistanceFromBoardPlane(transform.position);//黑板檫距离画板的距离
            if (distance > -0.096f)//当黑板檫离画板足够近的时候
{
                float percentOfDistance = Helper.RemapNumberClamped(distance, -0.096f, -0.02f, 0f, 1f);//映射后,得到插值系数
                Quaternion q = Quaternion.FromToRotation(grabbedObject.transform.up, -board.transform.forward);//最终的目的是:黑板擦的transform.up指向-transform.forward
                q *= grabbedObject.transform.rotation;//得到黑板檫达到最终目的时的旋转
                grabbedObject.transform.rotation = Quaternion.Slerp(grabbedObject.transform.rotation, q, percentOfDistance);//通过插值,得到当前黑板檫的旋转
                if (distance > 0.01f)//如果黑板檫穿透了画板,需要进行矫正
{
                    Vector3 pos =board.ProjectPointOnBoardPlane(grabbedObject.transform.position);
                    grabbedObject.transform.position = pos - board.transform.forward * 0.01f;
                }
            }                     
        }
    }
}

其实也可以用Quaternion.LookRotation但是这个函数的限制要比Quaternion.FromToRotation要大,效果没有后者好;

在下一篇中将完善所有的初级篇中不足的地方;

免责声明:文章转载自《使用Unity实现VR中在黑板上写字(升级篇)(二)----- 加入黑板擦》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇DNS域传送漏洞jdk7与jdk8环境共存与切换下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用Unity实现VR中在黑板上写字(升级篇)(一)-----解决画笔穿透画板的问题

一、概述: 在使用Unity实现VR中在黑板上写字(初级篇)中的最后留下了一些有待完善的地方,首先完善画笔穿透画板的问题; 在之前使用画笔会出现这种情况: 可以看到画笔是穿透了画板,这样在VR中会给用户很差的体验,而且因为代码的原因会造成画的过程中中断,所以这个问题必须解决; 解决后的使用情况: 可以看到现在不会穿透了,而且画起来不会有中断,其实我的手...

使用Unity实现VR中在黑板上写字(初级篇)

一、工具 1.开发用的是Unity 5.6.2版本 2.VR中的物理交互用的是VRTK插件,这个插件集成了比较好的物理交互功能; 3.HTC Vive 二、概述 实现的功能: 在一个白板上,用不同颜色的笔,在白板画出任何想要的图形; 因为只是一个初级篇所以只是用两个脚本简单的实现,而且并没有黑板擦等功能 ,也不能两个笔同时画画,这些功能将会在未来的升级篇...

VR电脑模拟实现

一、概述 1.实现的基本操作是: 1)用手柄抓住黄色的方块代表手抓住鼠标。 2)通过移动手柄模拟鼠标移动,电脑屏幕上的光标跟着移动。 3)当光标移动到一个Button上时,Button高亮,离开时Button取消高亮,点击Button触发点击事件。 4)当点击Button之后,打开一个画图程序,可以用光标在颜色选择区选择一种颜色,然后在画图区根据光标的...

[转]VR原理讲解及开发入门

本文转自:http://www.52vr.com/article-661-1.html 本文是作者obuil根据多年心得专门为想要入门的VR开发者所写,由52VR网站提供支持。   1. VR沉浸感和交互作用产生的原理:   在之前,我们观看一个虚拟的创造内容是通过平面显示器的,52VR上次发布过一篇文章《一张图让你认识VR》,在其中,你会看到很多10年...

《图说VR入门》——googleVR 他山之玉

本文章由cartzhang编写,转载请注明出处。 所有权利保留。 文章链接:http://blog.csdn.net/cartzhang/article/details/53125482 作者:cartzhang 《图说VR入门》——googleVR 他山之玉 之前分析了一些GoogleVR的代码,画了一些图。 常言:他山之石,可以攻玉。个人觉得...

[UE4]从零开始构建VR角色

一个工程是不是VR,并没有什么特别的地方,原则上任何工程都可以在VR设备下展示 一、新建一个名为“VRPawnBase”的Pawn. 二、在VRPawnBase中添加组件“Steam VRChaperone”,VRChaperone代表的是头显,头显在动,VRChaperone也会跟着在动    三、在VRPawnBase中添加一个Camera 四、把VR...