Saya memutuskan berlibur untuk belajar pengembangan untuk Vive di Unity3D. Cari beberapa contoh di Google dan mulai mencoba, tetapi untuk beberapa alasan itu tidak berhasil. Setelah mulai memahami lebih detail dan mendapati bahwa Valve baru-baru ini meluncurkan pembaruan plugin untuk Unity3D - versi baru yang diulang kembali. Beberapa inovasi mendasar muncul di dalamnya yang membuat tutorial lama tidak relevan. Saya memutuskan untuk menulis yang baru

Kita akan membutuhkan Unity> = 5.4.0 dan plugin Plugin SteamVR baru ( GitHub )
Dalam plugin itu sendiri ada tiga pdf yang berguna untuk pengenalan
\ Aset \ SteamVR \ SteamVR Unity Plugin.pdf
\ Aset \ SteamVR \ SteamVR Unity Plugin - Input System.pdf
\ Aset \ SteamVR \ InteractionSystem \ InteractionSystem.pdf
Dan dua contoh:
\ Aset \ SteamVR \ Sampel Sederhana.unity
\ Aset \ SteamVR \ InteractionSystem \ Samples \ Interactions_Example.unity
Plugin mendukung mode simulasi - ini akan menyala jika helm tidak dihidupkan
Nah, sekarang selangkah demi selangkah;
Buat proyek template 3D baru dengan plugin SteamVR Plugin
Kami setuju dengan pengaturan

Sekarang titik kuncinya adalah Anda perlu mengkonfigurasi manajemen. Pilih item menu Window \ SteamVR Imput

Unity akan bertanya tentang tindakan yang hilang.json dan menawarkan untuk menyalin file contoh (terletak di \ Aset \ SteamVR \ Input \ ExampleJSON) - Saya menyarankan Anda untuk setuju.

File json menunjukkan bahwa plugin dirancang tidak hanya untuk Vive, tetapi juga untuk Oculus dan Windows MR, serta pengontrol buku jari baru. Perubahan besar terkait dengan ini.
Di jendela yang terbuka, cukup klik "Simpan dan hasilkan"

Sekarang Anda perlu menambahkan Player (Player dari \ Assets \ SteamVR \ InteractionSystem \ Core \ Prefabs) ke Scene dan menghapus Kamera Utama

agar mode simulasi berfungsi - itu harus diaktifkan di properti Player

Juga berguna untuk menyalin folder \ Assets \ SteamVR \ InteractionSystem \ Core \ Icons ke \ Assets dan ganti namanya menjadi Gizmos
Anda dapat mengklik Mainkan - tetapi hanya tangan palsu dalam simulasi tidak akan bekerja, Anda perlu menyalin skrip dari sini dan menggantungnya di Player-> NoSteamVRFallbackObjects-> FallbackHand
Kode skrip tangan palsuusing System.Collections.Generic; using UnityEngine; using Valve.VR; public class VrSimulatorHandFixer156 : SteamVR_Behaviour_Pose { Valve.VR.InteractionSystem.Hand _hand; protected override void Start() { base.Start(); _hand = this.gameObject.GetComponent<Valve.VR.InteractionSystem.Hand>(); _hand.handType = SteamVR_Input_Sources.RightHand; GameObject broHand = GameObject.Instantiate(_hand.gameObject); Destroy(broHand.GetComponent<VrSimulatorHandFixer156>()); broHand.SetActive(false); _hand.otherHand = broHand.GetComponent<Valve.VR.InteractionSystem.Hand>(); _hand.otherHand.handType = SteamVR_Input_Sources.LeftHand; var spoofMouse = new SpoofMouseAction(); _hand.grabGripAction = spoofMouse; spoofMouse.InitializeDictionariesExposed(_hand.handType); this.poseAction = new Poser_SteamVR_Action_Pose(); } protected override void OnEnable() { } protected override void Update() { _hand.grabGripAction.UpdateValue(SteamVR_Input_Sources.RightHand); } protected override void OnDisable() { } protected override void CheckDeviceIndex() { }
Dalam mode VR dengan pengendali dihidupkan - mereka akan terlihat

Kami menambahkan VR, tetapi kami bahkan tidak bisa bergerak. Plugin ini memiliki implementasi teleportasi
untuk mengaktifkannya, Anda perlu menambahkan adegan Teleporting dari \ Assets \ SteamVR \ InteractionSystem \ Teleport \ Prefabs
dan juga mengatur TeleportPoint dari sana

Anda juga dapat berteleportasi dengan menggunakan tombol T.
Anda dapat membuat permukaan teleportasi - Membuat pesawat dan menggantung skrip TeleportArea.cs dari \ Assets \ SteamVR \ InteractionSystem \ Teleport \ Script di atasnya

Mari kita coba berinteraksi dengan objek - buat Cube dan gantungkan skrip Interactable.cs dari \ Assets \ SteamVR \ InteractionSystem \ Core \ Scripts di atasnya
sekarang disorot, tetapi tidak ada yang terjadi padanya

Kami perlu mendaftar interaksi - kami akan membuat skrip baru untuk Cube
Kode untuk interaksi using System.Collections; using System.Collections.Generic; using UnityEngine; using Valve.VR.InteractionSystem; public class NewBehaviourScript : MonoBehaviour { private Hand.AttachmentFlags attachmentFlags = Hand.defaultAttachmentFlags & (~Hand.AttachmentFlags.SnapOnAttach) & (~Hand.AttachmentFlags.DetachOthers) & (~Hand.AttachmentFlags.VelocityMovement); private Interactable interactable; // Use this for initialization void Start () { interactable = this.GetComponent<Interactable>(); } private void HandHoverUpdate(Hand hand) { GrabTypes startingGrabType = hand.GetGrabStarting(); bool isGrabEnding = hand.IsGrabEnding(this.gameObject); if (startingGrabType != GrabTypes.None) { // Call this to continue receiving HandHoverUpdate messages, // and prevent the hand from hovering over anything else hand.HoverLock(interactable); // Attach this object to the hand hand.AttachObject(gameObject, startingGrabType, attachmentFlags); } else if (isGrabEnding) { // Detach this object from the hand hand.DetachObject(gameObject); // Call this to undo HoverLock hand.HoverUnlock(interactable); } } }
Rincian lebih lanjut tentang interaksi dapat ditemukan dalam contoh untuk plugin, khususnya di \ Assets \ SteamVR \ InteractionSystem \ Samples \ Scripts \ InteractableExample.cs
Dan kemudian kita akan mencoba melakukan apa yang tidak ada dalam contoh - tambahkan tindakan baru
Buka skrip Player.cs dan tambahkan bidang
[SteamVR_DefaultAction("PlayerMove", "default")] public SteamVR_Action_Vector2 a_move; [SteamVR_DefaultAction("PlayerRotate", "default")] public SteamVR_Action_Vector2 a_rotate; [SteamVR_DefaultAction("MenuClick", "default")] public SteamVR_Action_Boolean a_menu;
Jenis pengembalian yang valid dapat ditemukan di \ Aset \ SteamVR \ Input
Dan metode Pembaruan:
private void Update() { bool st = a_menu.GetStateDown(SteamVR_Input_Sources.Any); if (st) { this.transform.position = new Vector3(0, 0, 0); } else { Camera camera = this.GetComponentInChildren<Camera>(); Quaternion cr = Quaternion.Euler(0, 0, 0); if (camera != null) { Vector2 r = a_rotate.GetAxis(SteamVR_Input_Sources.RightHand); Quaternion qp = this.transform.rotation; qp.eulerAngles += new Vector3(0, rx, 0); this.transform.rotation = qp; cr = camera.transform.rotation; } Vector2 m = a_move.GetAxis(SteamVR_Input_Sources.LeftHand); m = Quaternion.Euler(0, 0, -cr.eulerAngles.y) * m; this.transform.position += new Vector3(mx / 10, 0, my / 10); } }
Kode Player.cs Lengkap //======= Copyright (c) Valve Corporation, All rights reserved. =============== // // Purpose: Player interface used to query HMD transforms and VR hands // //============================================================================= using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Valve.VR.InteractionSystem { //------------------------------------------------------------------------- // Singleton representing the local VR player/user, with methods for getting // the player's hands, head, tracking origin, and guesses for various properties. //------------------------------------------------------------------------- public class Player : MonoBehaviour { [Tooltip( "Virtual transform corresponding to the meatspace tracking origin. Devices are tracked relative to this." )] public Transform trackingOriginTransform; [Tooltip( "List of possible transforms for the head/HMD, including the no-SteamVR fallback camera." )] public Transform[] hmdTransforms; [Tooltip( "List of possible Hands, including no-SteamVR fallback Hands." )] public Hand[] hands; [Tooltip( "Reference to the physics collider that follows the player's HMD position." )] public Collider headCollider; [Tooltip( "These objects are enabled when SteamVR is available" )] public GameObject rigSteamVR; [Tooltip( "These objects are enabled when SteamVR is not available, or when the user toggles out of VR" )] public GameObject rig2DFallback; [Tooltip( "The audio listener for this player" )] public Transform audioListener; public bool allowToggleTo2D = true; [SteamVR_DefaultAction("PlayerMove", "default")] public SteamVR_Action_Vector2 a_move; [SteamVR_DefaultAction("PlayerRotate", "default")] public SteamVR_Action_Vector2 a_rotate; [SteamVR_DefaultAction("MenuClick", "default")] public SteamVR_Action_Boolean a_menu; //------------------------------------------------- // Singleton instance of the Player. Only one can exist at a time. //------------------------------------------------- private static Player _instance; public static Player instance { get { if ( _instance == null ) { _instance = FindObjectOfType<Player>(); } return _instance; } } //------------------------------------------------- // Get the number of active Hands. //------------------------------------------------- public int handCount { get { int count = 0; for ( int i = 0; i < hands.Length; i++ ) { if ( hands[i].gameObject.activeInHierarchy ) { count++; } } return count; } } //------------------------------------------------- // Get the i-th active Hand. // // i - Zero-based index of the active Hand to get //------------------------------------------------- public Hand GetHand( int i ) { for ( int j = 0; j < hands.Length; j++ ) { if ( !hands[j].gameObject.activeInHierarchy ) { continue; } if ( i > 0 ) { i--; continue; } return hands[j]; } return null; } //------------------------------------------------- public Hand leftHand { get { for ( int j = 0; j < hands.Length; j++ ) { if ( !hands[j].gameObject.activeInHierarchy ) { continue; } if ( hands[j].handType != SteamVR_Input_Sources.LeftHand) { continue; } return hands[j]; } return null; } } //------------------------------------------------- public Hand rightHand { get { for ( int j = 0; j < hands.Length; j++ ) { if ( !hands[j].gameObject.activeInHierarchy ) { continue; } if ( hands[j].handType != SteamVR_Input_Sources.RightHand) { continue; } return hands[j]; } return null; } } //------------------------------------------------- // Get Player scale. Assumes it is scaled equally on all axes. //------------------------------------------------- public float scale { get { return transform.lossyScale.x; } } //------------------------------------------------- // Get the HMD transform. This might return the fallback camera transform if SteamVR is unavailable or disabled. //------------------------------------------------- public Transform hmdTransform { get { if (hmdTransforms != null) { for (int i = 0; i < hmdTransforms.Length; i++) { if (hmdTransforms[i].gameObject.activeInHierarchy) return hmdTransforms[i]; } } return null; } } //------------------------------------------------- // Height of the eyes above the ground - useful for estimating player height. //------------------------------------------------- public float eyeHeight { get { Transform hmd = hmdTransform; if ( hmd ) { Vector3 eyeOffset = Vector3.Project( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up ); return eyeOffset.magnitude / trackingOriginTransform.lossyScale.x; } return 0.0f; } } //------------------------------------------------- // Guess for the world-space position of the player's feet, directly beneath the HMD. //------------------------------------------------- public Vector3 feetPositionGuess { get { Transform hmd = hmdTransform; if ( hmd ) { return trackingOriginTransform.position + Vector3.ProjectOnPlane( hmd.position - trackingOriginTransform.position, trackingOriginTransform.up ); } return trackingOriginTransform.position; } } //------------------------------------------------- // Guess for the world-space direction of the player's hips/torso. This is effectively just the gaze direction projected onto the floor plane. //------------------------------------------------- public Vector3 bodyDirectionGuess { get { Transform hmd = hmdTransform; if ( hmd ) { Vector3 direction = Vector3.ProjectOnPlane( hmd.forward, trackingOriginTransform.up ); if ( Vector3.Dot( hmd.up, trackingOriginTransform.up ) < 0.0f ) { // The HMD is upside-down. Either // -The player is bending over backwards // -The player is bent over looking through their legs direction = -direction; } return direction; } return trackingOriginTransform.forward; } } //------------------------------------------------- void Awake() { SteamVR.Initialize(true); //force openvr if ( trackingOriginTransform == null ) { trackingOriginTransform = this.transform; } } //------------------------------------------------- private IEnumerator Start() { _instance = this; while (SteamVR_Behaviour.instance.forcingInitialization) yield return null; if ( SteamVR.instance != null ) { ActivateRig( rigSteamVR ); } else {
Jalankan Window \ SteamVR Imput, buat tindakan kami di set default dan simpan, sekarang pilih "Open binding UI" (SteamVR harus dijalankan dan setidaknya satu pengendali dihidupkan)

Tab Binding Pengendali terbuka di browser - di dalamnya Anda perlu mengonfigurasi koneksi tindakan kami dengan pengontrol: kami akan menggantung PlayerMove di TRACKPAD kiri (jangan lupa mematikan Mode Cermin), PlayerRotate di TRACKPAD kanan, dan gantung MenuKlik pada tombol Menu

Tutup Pengikat Mengikat dan simpan perubahan.
Di properti Player, kami mengaitkan tindakan baru

Luncurkan Mainkan
Proyek
Kesimpulan
Beberapa poin harus diperhatikan. Beberapa tindakan dalam SteamVR Imput dapat membuat Unity berpikir untuk waktu yang lama, pada prinsipnya, Anda dapat membuat perubahan ini sendiri dalam kode, dan alih-alih menggunakan Binding Pengendali, Anda dapat langsung mengedit file json, tetapi ada risiko besar kesalahan yang bisa sulit ditangkap.
Untuk studi yang lebih mendalam tentang plugin - penting untuk mempelajari contoh-contoh secara rinci, dan tentu saja - baca dokumentasi.