前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VR开发--HTC Vive基础(2):瞬移功能实现

VR开发--HTC Vive基础(2):瞬移功能实现

作者头像
孙寅
发布2020-06-02 17:01:28
8520
发布2020-06-02 17:01:28
举报
文章被收录于专栏:宜达数字宜达数字
1、瞬移

因为HTC Vive活动范围有限制(3m * 5m),所以我们在实际的使用中,为了更好的浏览场景,查看场景,会使用这种移动的方式,达到游戏中的视野移动。 一般来说就是手柄选取一个位置,通过扳机键确认移动。 移动的方式有两种:一种是水平移动即X,Z轴移动;另一种就是垂直移动,即Y轴移动。

2、如何实现位置选取?

只要能得到目标位置点,我们就可以移动。那这种功能如何做? 使用射线检测! HTC Vive中有类似的脚本实现,所以我们只需要修改相关的脚本就可以办到,但是还是需要一定的编程功底。

脚本实现: 将下面脚本复制就可,

Paste_Image.png

修改类名,添加脚本

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

public class CatchPointer : MonoBehaviour
{
    public bool active = true;
    public Color color;
    public float thickness = 0.002f;
    public GameObject holder;
    public GameObject pointer;
    bool isActive = false;
    public bool addRigidBody = false;
    public Transform reference;
    public event PointerEventHandler PointerIn;
    public event PointerEventHandler PointerOut;
    public Vector3 HitPoint;
    Transform previousContact = null;

    // Use this for initialization
    void Start ()
    {
        holder = new GameObject();
        holder.transform.parent = this.transform;
        holder.transform.localPosition = Vector3.zero;

        pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
        pointer.transform.parent = holder.transform;
        pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
        pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
        BoxCollider collider = pointer.GetComponent<BoxCollider>();
        if (addRigidBody)
        {
            if (collider)
            {
                collider.isTrigger = true;
            }
            Rigidbody rigidBody = pointer.AddComponent<Rigidbody>();
            rigidBody.isKinematic = true;
        }
        else
        {
            if(collider)
            {
                Object.Destroy(collider);
            }
        }
        Material newMaterial = new Material(Shader.Find("Unlit/Color"));
        newMaterial.SetColor("_Color", color);
        pointer.GetComponent<MeshRenderer>().material = newMaterial;
    }

    public virtual void OnPointerIn(PointerEventArgs e)
    {
        if (PointerIn != null)
            PointerIn(this, e);
    }

    public virtual void OnPointerOut(PointerEventArgs e)
    {
        if (PointerOut != null)
            PointerOut(this, e);
    }


    // Update is called once per frame
    void Update ()
    {
        if (!isActive)
        {
            isActive = true;
            this.transform.GetChild(0).gameObject.SetActive(true);
        }

        float dist = 100f;

        SteamVR_TrackedController controller = GetComponent<SteamVR_TrackedController>();

        Ray raycast = new Ray(transform.position, transform.forward);
        RaycastHit hit;
        bool bHit = Physics.Raycast(raycast, out hit);

        if(previousContact && previousContact != hit.transform)
        {
            PointerEventArgs args = new PointerEventArgs();
            if (controller != null)
            {
                args.controllerIndex = controller.controllerIndex;
            }
            args.distance = 0f;
            args.flags = 0;
            args.target = previousContact;
            OnPointerOut(args);
            previousContact = null;
        }
        if(bHit && previousContact != hit.transform)
        {
            PointerEventArgs argsIn = new PointerEventArgs();
            if (controller != null)
            {
                argsIn.controllerIndex = controller.controllerIndex;
            }
            argsIn.distance = hit.distance;
            argsIn.flags = 0;
            argsIn.target = hit.transform;
            OnPointerIn(argsIn);
            previousContact = hit.transform;
        }
        if(!bHit)
        {
            previousContact = null;
        }
        if (bHit && hit.distance < 100f)
        {
            dist = hit.distance;
        }
        if (bHit)
        {
            HitPoint = hit.point;
        }

        if (controller != null && controller.triggerPressed)
        {
            pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist);
        }
        else
        {
            pointer.transform.localScale = new Vector3(thickness, thickness, dist);
        }
        pointer.transform.localPosition = new Vector3(0f, 0f, dist/2f);
    }
}
3、添加脚本查看效果

Paste_Image.png

Paste_Image.png

4、如何传送?

编写脚本进行设置

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

public class Teleport : MonoBehaviour {

    public GameObject LeftController;
    private CatchPointer Pointer;
    private SteamVR_TrackedController LeftSt;
    ClickedEventHandler ce;
    Transform currentTransform;
    PointerEventArgs arg;
    void Start () {
        Pointer = LeftController.GetComponent<CatchPointer>();
        LeftSt = LeftController.GetComponent<SteamVR_TrackedController>();
        Pointer.PointerIn += LeftPointIn;
        Pointer.PointerOut += LeftPointOut;
        LeftSt.TriggerClicked += TriggerClicked;

    }
    
    
    void Update () {
    
    }
    void LeftPointOut(object sender, PointerEventArgs e)
    {
        currentTransform = null;
    }
    void LeftPointIn(object sender, PointerEventArgs e)
    {   // 设置标识
        currentTransform = e.target;
    }
    void TriggerClicked(object sender, ClickedEventArgs e)
    {
        if (currentTransform != null)
        {
            this.gameObject.transform.position = new Vector3(Pointer.HitPoint.x - LeftController.transform.localPosition.x, Pointer.HitPoint.y, Pointer.HitPoint.z - LeftController.transform.localPosition.z);
        }  
    }
}
5、如何实现抛物线功能
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、瞬移
  • 2、如何实现位置选取?
  • 3、添加脚本查看效果
  • 4、如何传送?
  • 5、如何实现抛物线功能
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档