SteamVR2.6在地形上位移的问题

SteamVR2.0以后,玩家想要发生位移就要做几个设置:①Player预制体②Teleporting预制体③在地板上添加TeleportArea脚本,设置地板的layer,在Teleporting的预制体上把Teleport脚本的Trace Layer Mask设置为地板对应的layer。鉴于SteamVR的机制,在按下位移的Action后,脚本会自动给地板的MeshRender中的Mesh更换材质,并且显示出更换材质后的地板。这个机制在用拥有MeshRender的地板来说,没有什么问题,大不了将地板复制一份,然后设置复制后的地板作为Teleport Area 就是了。

今天在开发的时候就遇到了一个问题,地编给了个场景,场景是用Unity的地形系统搭建的。按照之前的做法,要想使用位移,就必须在地形下新建一个Plane,然后把Plane拉到和地形一样大,然后把TeleportArea附加到Plane上。但是这个操作会出现,当地形出现高低起伏的地方的时候,就会出现穿到地形以下的情况。(因为位移根据的碰撞体是我后面加的Plane,不是地形的Terrain Collider)如果给每个位移区域单独弄一块Plane做位移区域就太麻烦了。为了解决这个问题,我就稍微修改了SteamVR的TeleportArea脚本,让它像VRTK一样直接根据Trace Layer Mask对应的层上面的碰撞体来做位移。亲测能用。代码附上:

/****************************************************
    文件:CustomTeleportArea.cs
	作者:Paul   邮箱: 794451358@qq.com
    日期:2020/11/19 11:41:29
	功能:重写位移区域脚本,让其适应地形碰撞体
*****************************************************/


using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using Valve.VR.InteractionSystem;
namespace DaschowStreet
{
    public class CustomTeleportArea : TeleportMarkerBase
    {
        [Tooltip("如果勾选就是使用SteamVR本来的位移机制")]
        public bool IsUseSteamVRTeleport = false;

        //Public properties
        public Bounds meshBounds { get; private set; }

        //Private data
        private MeshRenderer areaMesh;
        private int tintColorId = 0;
        private Color visibleTintColor = Color.clear;
        private Color highlightedTintColor = Color.clear;
        private Color lockedTintColor = Color.clear;
        private bool highlighted = false;


        private void Awake()
        {
           
            if (IsUseSteamVRTeleport)
            {
                areaMesh = GetComponent<MeshRenderer>();
                tintColorId = Shader.PropertyToID("_TintColor");
                CalculateBounds();
            }
        }
        private void Start()
        {
            if (IsUseSteamVRTeleport)
            {
                visibleTintColor = Teleport.instance.areaVisibleMaterial.GetColor(tintColorId);
                highlightedTintColor = Teleport.instance.areaHighlightedMaterial.GetColor(tintColorId);
                lockedTintColor = Teleport.instance.areaLockedMaterial.GetColor(tintColorId);
            }

        }

        public override void Highlight(bool highlight)
        {
            if (IsUseSteamVRTeleport)
            {
                if (!locked)
                {
                    highlighted = highlight;

                    if (highlight)
                    {
                        areaMesh.material = Teleport.instance.areaHighlightedMaterial;
                    }
                    else
                    {
                        areaMesh.material = Teleport.instance.areaVisibleMaterial;
                    }
                }
            }
        }

        public override void SetAlpha(float tintAlpha, float alphaPercent)
        {
            if (IsUseSteamVRTeleport)
            {
                Color tintedColor = GetTintColor();
                tintedColor.a *= alphaPercent;
                areaMesh.material.SetColor(tintColorId, tintedColor);
                
            }
        }

        public override bool ShouldActivate(Vector3 playerPosition)
        {
            return true;
        }

        public override bool ShouldMovePlayer()
        {
            return true;
        }

        public override void UpdateVisuals()
        {
            if (IsUseSteamVRTeleport)
            {
                if (locked)
                {
                    areaMesh.material = Teleport.instance.areaLockedMaterial;
                }
                else
                {
                    areaMesh.material = Teleport.instance.areaVisibleMaterial;
                }
            }
        }

        private bool CalculateBounds()
        {
            MeshFilter meshFilter = GetComponent<MeshFilter>();
            if (meshFilter == null)
            {
                return false;
            }

            Mesh mesh = meshFilter.sharedMesh;
            if (mesh == null)
            {
                return false;
            }

            meshBounds = mesh.bounds;
            return true;
        }

        private Color GetTintColor()
        {
            if (locked)
            {
                return lockedTintColor;
            }
            else
            {
                if (highlighted)
                {
                    return highlightedTintColor;
                }
                else
                {
                    return visibleTintColor;
                }
            }
        }
    }

}

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

int_Paul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值