Unity 项目 HTCvive虚拟物理实验室 模拟失重环境

在物理实验室模块中,设计加一个模拟失重环境的房间,使用户能够体验到虚拟的失重的状态。

在htc vive的运行中,摄像机元素绑定在camerarig的head子物体中的eye上,使用者自身也就是camerarig,在运行时,会被添加一个rigidbody刚体组件以及一个胶囊体的碰撞体。为了更好的模拟人在环境中的交互。

为了更好的体验,我们需要设置camerarig所在的rigidbody的属性。虽然在失重的环境下,一个很小的力,也会造成很大的位移,但第一人称视角的情况下,位移的幅度太大,会产生眩晕感;这是需要调整所在的刚体的质量mass,或者增大位移阻力和旋转阻力,虽然在失重情况下,并不现实,但模拟体验效果会比较好。

我是采用增大drag和angular drag。

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

public class changeRigidbody : MonoBehaviour {

	private Rigidbody rrd;

	// Use this for initialization
	void Start () {
		rrd = GetComponent<Rigidbody> ();

		rrd.drag = 100.0f;
		rrd.angularDrag = 100.0f;
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}
在其他的物体上添加摩擦力,质量等属性,不施加重力;设置物理属性。并添加VRTK_Interactable和 VRTK_InteractableObject为了使手柄可以抓取。(详见《基于VRTK的Unity HTC Vive模型拼接(组件的抓取交互) 》)

除此之外,我加了一个“黑洞”的功能,扣动左手扳机的时候;物体都被吸引到左手扳机的位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK;
using VRTK.Highlighters;

public class suction : MonoBehaviour {

	public float distance;
	public Vector3 sucPos;

	public bool isAddForce = false;

	private GameObject LeftController;

	public SteamVR_TrackedObject trackedObjec;

	// Use this for initialization
	void Start () {
		sucPos = this.transform.position;

		LeftController = VRTK_DeviceFinder.GetControllerLeftHand ();
	}
	
	// Update is called once per frame
	void Update () {
		sucPos = LeftController.transform.position;

		var device = SteamVR_Controller.Input((int)trackedObjec.index);

		if(device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger) && !isAddForce){
			isAddForce = true;
		}

		if(device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger) && isAddForce){
			isAddForce = false;
		}
	}
}

左手手柄绑定的脚本,首先通过VRTK_DeviceFinder获取左手手柄的位置,记录位置并设置为public属性的变量,方便其他物体的调用。

检测到当手柄按下时,设置一个布尔值,isAddForce至为true。

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

public class forced : MonoBehaviour {

	public float gravity = 1.0f;
	public float distance;
	public suction suct;

	private Rigidbody rg;

	public float julicanshu;

	// Use this for initialization
	void Start () {
		rg = GetComponent<Rigidbody> ();
	}
	
	// Update is called once per frame
	void Update () {
		if(suct.isAddForce){
			distance = System.Math.Abs((suct.sucPos - transform.position).magnitude);

			julicanshu = (System.Math.Abs (100.0f - distance))/100.0f;

			rg.AddForce (((suct.sucPos - transform.position).normalized)*(2.0f-gravity)*julicanshu);
		}
	}
}

其他物体上的force脚本,获取到脚本的rigidbody,为了下面执行addforce方法,施力。

当前面监听到手柄按下时,执行吸引的方法。

首先计算与手柄的距离,计算绝对值,通过距离计算距离参数,方便下面施加力的时候调用。距离参数与距离成反比。施力的时候,通过两者间的位置计算出方向,并归一化。除了方向外,施加的力还受到质量,距离的影响。距离越近受力越大,质量越小受力越大。

猜你喜欢

转载自blog.csdn.net/qq_34272906/article/details/80473610