はじめに
これは毎回自分のPCの中をたどりながらVR開発をするのがめんどくさくなったがための開発覚書です。後々書き足す可能性有り。
-追記
タイトルにURP下でのと入れていますがコントローラーのシェーダーを変えることしかやってません、ごめんなさい
本題
- もろもろのアセットを入れたらCameraRigを設置する。CameraRigの子のmodelのシェーダーはURP対応ではないので手動でLitシェーダーに変える。
- SteamVR Inputからdefaultのjsonファイルを作る。コントローラーの割り当てを変えたい場合はOpen binding UI。
自分だけのコントローラーの設定を行いたい場合
-
自分だけのコントローラーの設定を行いたい場合SteamVR Inputで設定を作ってあげる
-
そのあとOpen Binding UIからbindの設定を行う
こんな感じ(アクションポーズ、Haptic、スケルトンも下から設定する。)
-
デフォルトバインドの置換を押す(必要かはわからないけど押したところで支障はない。)
-
デフォルトであるコンポーネントのBehaviour_PoseのPose Actionを自分で作った設定に適用する。
-
またスクリプトでコントローラーにイベントを登録する際も自分で作った設定にすること。
注意事項 -
Poseの設定は必須なのでアクションポーズの設定から左手未加工にPoseを割り当てる。
-
Skeltonの設定は一回ミラーを外してからスケルトンの設定で割り当てる。
- これでPlayすると移動できないがコントローラーが見えるようになる。
- Input系列のコードを書く
以下使用例
using Valve.VR;
//押すボタン、Inspectorから選ぶ
public SteamVR_Action_Boolean actionButton;
//handtypeはInspectorから右か左かで選ぶ
public SteamVR_Input_Sources handtype;
//判定
if(actionButton.GetStateDown(handtype)){}
//コントローラーの動きをとる場合
SteamVR_Behaviour_Pose controllerPose;
//角度、方向
Vector3 vec3 = controllerPose.GetAngularVelocity();
//振っている力
Vector3 power = controllerPose.GetVelocity();
コードの例
Teleport
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
public class Teleport : MonoBehaviour
{
public SteamVR_Input_Sources handtype;
public SteamVR_Behaviour_Pose controllerPose;
public SteamVR_Action_Boolean teleportAction, triggerAction;
public GameObject laserPrefab;
private GameObject laser;
private Transform laserTransform;
private Vector3 hitPoint;
public Transform cameraRigTransform;
public GameObject teleportReticlePrefab;
private GameObject reticle;
private Transform teleportReticleTransform;
public Transform headTransform;
public Vector3 teleportReticleOffset;
public LayerMask layerMask;
private bool shouldTeleport;
// Start is called before the first frame update
void Start()
{
laser = Instantiate(laserPrefab);
laserTransform = laser.transform;
reticle = Instantiate(teleportReticlePrefab);
teleportReticleTransform = reticle.transform;
}
// Update is called once per frame
void Update()
{
if (teleportAction.GetState(handtype))
{
RaycastHit hit;
if (Physics.Raycast(controllerPose.transform.position, transform.forward, out hit, 100, layerMask))
{
hitPoint = hit.point;
ShowLaser(hit);
reticle.SetActive(true);
teleportReticleTransform.position = hitPoint + teleportReticleOffset;
shouldTeleport = true;
if (triggerAction.GetStateDown(handtype) && shouldTeleport)
{
TeleportPlayer();
}
}
}
else
{
laser.SetActive(false);
reticle.SetActive(false);
}
}
private void ShowLaser(RaycastHit hit)
{
laser.SetActive(true);
laserTransform.position = Vector3.Lerp(controllerPose.transform.position, hitPoint, 0.5f);
laserTransform.LookAt(hitPoint);
laserTransform.localScale = new Vector3(laserTransform.localScale.x, laserTransform.localScale.y, hit.distance);
}
private void TeleportPlayer()
{
shouldTeleport = false;
reticle.SetActive(false);
Vector3 difference = cameraRigTransform.position - headTransform.position;
difference.y = 0;
cameraRigTransform.position = hitPoint + difference;
}
}
物をつかむGrabObject
- この場合掴みたい物に対して投げた時に力を加えたい&&FixedJointで掴むものとをくっつけたいので、Rigidbodyを付与しておく
- 掴むものにもRigidbodyを付けておく。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
public class GrabObject : MonoBehaviour
{
public SteamVR_Input_Sources handtype;
public SteamVR_Behaviour_Pose contollerPose;
public SteamVR_Action_Boolean grabAction;
private GameObject collidingObject;
private GameObject objectInHand;
// Update is called once per frame
void Update()
{
if (grabAction.GetStateDown(handtype))
{
if (collidingObject)
{
Grab();
}
}
if (grabAction.GetStateUp(handtype))
{
if (objectInHand)
{
ReleaseObject();
}
}
}
void OnTriggerEnter(Collider other)
{
SetCollidingObject(other);
}
void OnTriggerStay(Collider other)
{
SetCollidingObject(other);
}
void OnTriggerExit(Collider other)
{
if (!collidingObject)
{
return;
}
collidingObject = null;
}
private void Grab()
{
objectInHand = collidingObject;
collidingObject = null;
var joint = AddFixedJoint();
joint.connectedBody = objectInHand.GetComponent<Rigidbody>();
}
private void ReleaseObject()
{
if (GetComponent<FixedJoint>())
{
GetComponent<FixedJoint>().connectedBody = null;
Destroy(GetComponent<FixedJoint>());
objectInHand.GetComponent<Rigidbody>().velocity = contollerPose.GetVelocity();
objectInHand.GetComponent<Rigidbody>().angularVelocity = contollerPose.GetAngularVelocity();
}
objectInHand = null;
}
private FixedJoint AddFixedJoint()
{
FixedJoint fixedJoint = this.gameObject.AddComponent<FixedJoint>();
fixedJoint.breakForce = 20000;
fixedJoint.breakTorque = 20000;
return fixedJoint;
}
private void SetCollidingObject(Collider col)
{
if (collidingObject || !col.GetComponent<Rigidbody>())
{
return;
}
collidingObject = col.gameObject;
}
}