deltavr multiplayer 2.0
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59b8da3d55e3cb74c91ad743d542a9a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to implement for objects that hold a set of <c>Key</c>s
|
||||
/// </summary>
|
||||
public interface IKeychain
|
||||
{
|
||||
/// <summary>
|
||||
/// This callback is used to check if this keychain has a specific <c>Key</c>
|
||||
/// <see cref="Lock"/>
|
||||
/// </summary>
|
||||
/// <param name="key">the key to be checked</param>
|
||||
/// <returns>True if this keychain has the supplied key; false otherwise</returns>
|
||||
bool Contains(Key key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3273498567e6fc4b944c2985269269d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// An asset that represents a key. Used to check if an object can perform some action
|
||||
/// (<see cref="XRLockSocketInteractor"/> and <see cref="Keychain"/>)
|
||||
/// </summary>
|
||||
[CreateAssetMenuAttribute(menuName = "XR/Key Lock System/Key")]
|
||||
public class Key : ScriptableObject
|
||||
{ }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e629f4cfca91134e86ae027aaa5d4eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// A generic Keychain component that holds the <see cref="Key"/>s to open a <see cref="Lock"/>.
|
||||
/// Attach a Keychain component to an Interactable and assign to it the same Keys of an <see cref="XRLockSocketInteractor"/>
|
||||
/// or an <see cref="XRLockGridSocketInteractor"/> to open (or interact with) them.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class Keychain : MonoBehaviour, IKeychain
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("The keys on this keychain" +
|
||||
"Create new keys by selecting \"Assets/Create/XR/Key Lock System/Key\"")]
|
||||
List<Key> m_Keys;
|
||||
|
||||
HashSet<int> m_KeysHashSet = new HashSet<int>();
|
||||
|
||||
void Awake()
|
||||
{
|
||||
RepopulateHashSet();
|
||||
}
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
// A key was added through the inspector while the game was running?
|
||||
if (Application.isPlaying && m_Keys.Count != m_KeysHashSet.Count)
|
||||
RepopulateHashSet();
|
||||
}
|
||||
|
||||
void RepopulateHashSet()
|
||||
{
|
||||
m_KeysHashSet.Clear();
|
||||
foreach (var key in m_Keys)
|
||||
{
|
||||
if (key != null)
|
||||
m_KeysHashSet.Add(key.GetInstanceID());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied key to this keychain
|
||||
/// </summary>
|
||||
/// <param name="key">The key to be added to the keychain</param>
|
||||
public void AddKey(Key key)
|
||||
{
|
||||
if (key == null || Contains(key))
|
||||
return;
|
||||
|
||||
m_Keys.Add(key);
|
||||
m_KeysHashSet.Add(key.GetInstanceID());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the supplied key from this keychain
|
||||
/// </summary>
|
||||
/// <param name="key">The key to be removed from the keychain</param>
|
||||
public void RemoveKey(Key key)
|
||||
{
|
||||
m_Keys.Remove(key);
|
||||
|
||||
if (key != null)
|
||||
m_KeysHashSet.Remove(key.GetInstanceID());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Contains(Key key)
|
||||
{
|
||||
return key != null && m_KeysHashSet.Contains(key.GetInstanceID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 505599121cd7c2d4d87a596056b0142b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this object as a generic way to validate if an object can perform some action.
|
||||
/// The check is done in the <see cref="CanUnlock"/> method.
|
||||
/// This class is used in combination with a <see cref="Keychain"/> component.
|
||||
/// </summary>
|
||||
/// <seealso cref="XRLockSocketInteractor"/>
|
||||
/// <seealso cref="XRLockGridSocketInteractor"/>
|
||||
[Serializable]
|
||||
public class Lock
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("The required keys to unlock this lock" +
|
||||
"Create new keys by selecting \"Assets/Create/XR/Key Lock System/Key\"")]
|
||||
List<Key> m_RequiredKeys;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the required keys to unlock this lock.
|
||||
/// </summary>
|
||||
public List<Key> requiredKeys => m_RequiredKeys;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the supplied keychain has all the required keys to open this lock.
|
||||
/// </summary>
|
||||
/// <param name="keychain">The keychain to be checked.</param>
|
||||
/// <returns>True if the supplied keychain has all the required keys; false otherwise.</returns>
|
||||
public bool CanUnlock(IKeychain keychain)
|
||||
{
|
||||
if (keychain == null)
|
||||
return m_RequiredKeys.Count == 0;
|
||||
|
||||
foreach (var requiredKey in m_RequiredKeys)
|
||||
{
|
||||
if (requiredKey == null)
|
||||
continue;
|
||||
|
||||
if (!keychain.Contains(requiredKey))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d479cceb8cf26842888dcaf56f46717
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45a1a51ca296a83468444b59fa20a20e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is responsible for creating the perler sockets grid and turning on/off the machine.
|
||||
/// </summary>
|
||||
public class PerlerMachineController : MonoBehaviour
|
||||
{
|
||||
static readonly string k_EmissionKeyword = "_EMISSION";
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The emissive materials that will change state whenever the machine is turned on/off")]
|
||||
Material[] m_EmissiveMaterials;
|
||||
|
||||
bool m_MachineActive;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
DisableEmissiveMaterials();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnDestroy()
|
||||
{
|
||||
EnableEmissiveMaterials();
|
||||
}
|
||||
#endif
|
||||
|
||||
void DisableEmissiveMaterials()
|
||||
{
|
||||
foreach (var material in m_EmissiveMaterials)
|
||||
material.DisableKeyword(k_EmissionKeyword);
|
||||
}
|
||||
|
||||
void EnableEmissiveMaterials()
|
||||
{
|
||||
foreach (var material in m_EmissiveMaterials)
|
||||
material.EnableKeyword(k_EmissionKeyword);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this method to activate or deactivate the machine. This will also turn on/off its lights.
|
||||
/// Used by the BatterySlot GameObject socket.
|
||||
/// </summary>
|
||||
/// <param name="active">Value of <see langword="true"/> to activate the machine; <see langword="false"/> otherwise.</param>
|
||||
public void SetMachineActive(bool active)
|
||||
{
|
||||
// It's the same state?
|
||||
if (active == m_MachineActive)
|
||||
return;
|
||||
|
||||
// Change the machine light state
|
||||
m_MachineActive = active;
|
||||
if (m_MachineActive)
|
||||
EnableEmissiveMaterials();
|
||||
else
|
||||
DisableEmissiveMaterials();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cc7fa0773a606e42930df5c728731e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,176 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Socket Interactor for holding a group of Interactables in a 2D grid.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The grid starts at the position of the Attach Transform.
|
||||
/// During Awake, a Grid Socket instantiates one GameObject (as child of its Attach Transform) for each grid cell.
|
||||
/// The Transform component of these instantiated objects are used as the actual attach point for the Interactables.
|
||||
/// </remarks>
|
||||
public class XRGridSocketInteractor : XRSocketInteractor
|
||||
{
|
||||
[Space]
|
||||
[SerializeField]
|
||||
[Tooltip("The grid width. The grid width is along the Attach Transform's local X axis.")]
|
||||
int m_GridWidth = 2;
|
||||
|
||||
/// <summary>
|
||||
/// The grid width. The grid width is along the Attach Transform's local X axis.
|
||||
/// </summary>
|
||||
public int gridWidth
|
||||
{
|
||||
get => m_GridWidth;
|
||||
set => m_GridWidth = Mathf.Max(1, value);
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The grid height. The grid height is along the Attach Transform's local Y axis.")]
|
||||
int m_GridHeight = 2;
|
||||
|
||||
/// <summary>
|
||||
/// The grid height. The grid height is along the Attach Transform's local Y axis.
|
||||
/// </summary>
|
||||
public int gridHeight
|
||||
{
|
||||
get => m_GridHeight;
|
||||
set => m_GridHeight = Mathf.Max(1, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (Read Only) The grid size. The maximum number of Interactables that this Interactor can hold.
|
||||
/// </summary>
|
||||
public int gridSize => m_GridWidth * m_GridHeight;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The distance (in local space) between cells in the grid.")]
|
||||
Vector2 m_CellOffset = new Vector2(0.1f, 0.1f);
|
||||
|
||||
/// <summary>
|
||||
/// The distance (in local space) between cells in the grid.
|
||||
/// </summary>
|
||||
public Vector2 cellOffset
|
||||
{
|
||||
get => m_CellOffset;
|
||||
set => m_CellOffset = value;
|
||||
}
|
||||
|
||||
readonly HashSet<Transform> m_UnorderedUsedAttachedTransform = new HashSet<Transform>();
|
||||
readonly Dictionary<IXRInteractable, Transform> m_UsedAttachTransformByInteractable =
|
||||
new Dictionary<IXRInteractable, Transform>();
|
||||
|
||||
Transform[,] m_Grid;
|
||||
|
||||
bool hasEmptyAttachTransform => m_UnorderedUsedAttachedTransform.Count < gridSize;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the grid.
|
||||
/// </summary>
|
||||
void CreateGrid()
|
||||
{
|
||||
m_Grid = new Transform[m_GridHeight, m_GridWidth];
|
||||
|
||||
for (var i = 0; i < m_GridHeight; i++)
|
||||
{
|
||||
for (var j = 0; j < m_GridWidth; j++)
|
||||
{
|
||||
var attachTransformInstance = new GameObject($"[{gameObject.name}] Attach ({i},{j})").transform;
|
||||
attachTransformInstance.SetParent(attachTransform, false);
|
||||
|
||||
var offset = new Vector3(j * m_CellOffset.x, i * m_CellOffset.y, 0f);
|
||||
attachTransformInstance.localPosition = offset;
|
||||
|
||||
m_Grid[i, j] = attachTransformInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
CreateGrid();
|
||||
|
||||
// The same material is used on both situations
|
||||
interactableCantHoverMeshMaterial = interactableHoverMeshMaterial;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected virtual void OnValidate()
|
||||
{
|
||||
m_GridWidth = Mathf.Max(1, m_GridWidth);
|
||||
m_GridHeight = Mathf.Max(1, m_GridHeight);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="MonoBehaviour"/>.
|
||||
/// </summary>
|
||||
protected virtual void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.green;
|
||||
Gizmos.matrix = attachTransform != null ? attachTransform.localToWorldMatrix : transform.localToWorldMatrix;
|
||||
for (var i = 0; i < m_GridHeight; i++)
|
||||
{
|
||||
for (var j = 0; j < m_GridWidth; j++)
|
||||
{
|
||||
var currentPosition = new Vector3(j * m_CellOffset.x, i * m_CellOffset.y, 0f);
|
||||
Gizmos.DrawLine(currentPosition + (Vector3.left * m_CellOffset.x * 0.5f), currentPosition + (Vector3.right * m_CellOffset.y * 0.5f));
|
||||
Gizmos.DrawLine(currentPosition + (Vector3.down * m_CellOffset.x * 0.5f), currentPosition + (Vector3.up * m_CellOffset.y * 0.5f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnSelectEntering(SelectEnterEventArgs args)
|
||||
{
|
||||
base.OnSelectEntering(args);
|
||||
|
||||
var closestAttachTransform = GetAttachTransform(args.interactableObject);
|
||||
m_UnorderedUsedAttachedTransform.Add(closestAttachTransform);
|
||||
m_UsedAttachTransformByInteractable.Add(args.interactableObject, closestAttachTransform);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnSelectExiting(SelectExitEventArgs args)
|
||||
{
|
||||
var closestAttachTransform = m_UsedAttachTransformByInteractable[args.interactableObject];
|
||||
m_UnorderedUsedAttachedTransform.Remove(closestAttachTransform);
|
||||
m_UsedAttachTransformByInteractable.Remove(args.interactableObject);
|
||||
|
||||
base.OnSelectExiting(args);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSelect(IXRSelectInteractable interactable)
|
||||
{
|
||||
return IsSelecting(interactable)
|
||||
|| (hasEmptyAttachTransform && !interactable.isSelected && !m_UnorderedUsedAttachedTransform.Contains(GetAttachTransform(interactable)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanHover(IXRHoverInteractable interactable)
|
||||
{
|
||||
return base.CanHover(interactable)
|
||||
&& !m_UnorderedUsedAttachedTransform.Contains(GetAttachTransform(interactable));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Transform GetAttachTransform(IXRInteractable interactable)
|
||||
{
|
||||
if (m_UsedAttachTransformByInteractable.TryGetValue(interactable, out var interactableAttachTransform))
|
||||
return interactableAttachTransform;
|
||||
|
||||
var interactableLocalPosition = attachTransform.InverseTransformPoint(interactable.GetAttachTransform(this).position);
|
||||
var i = Mathf.RoundToInt(interactableLocalPosition.y / m_CellOffset.y);
|
||||
var j = Mathf.RoundToInt(interactableLocalPosition.x / m_CellOffset.x);
|
||||
i = Mathf.Clamp(i, 0, m_GridHeight - 1);
|
||||
j = Mathf.Clamp(j, 0, m_GridWidth - 1);
|
||||
return m_Grid[i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c33df1315ff25f44b42c17af3fe1008
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// This component makes sure that the attached <c>Interactor</c> always have an interactable selected.
|
||||
/// This is accomplished by forcing the <c>Interactor</c> to select a new <c>Interactable Prefab</c> instance whenever
|
||||
/// it loses the current selected interactable.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
[RequireComponent(typeof(XRBaseInteractor))]
|
||||
public class XRInfiniteInteractable : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
[Tooltip("Whether infinite spawning is active.")]
|
||||
bool m_Active = true;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("If true then during Awake the Interactor \"Starting Selected Interactable\" will be overriden by an " +
|
||||
"instance of the \"Interactable Prefab\".")]
|
||||
bool m_OverrideStartingSelectedInteractable;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("The Prefab or GameObject to be instantiated and selected.")]
|
||||
XRBaseInteractable m_InteractablePrefab;
|
||||
|
||||
XRBaseInteractor m_Interactor;
|
||||
|
||||
/// <summary>
|
||||
/// Whether infinite spawning is enabled.
|
||||
/// </summary>
|
||||
public bool active
|
||||
{
|
||||
get => m_Active;
|
||||
|
||||
set
|
||||
{
|
||||
m_Active = value;
|
||||
if (enabled && value && !m_Interactor.hasSelection)
|
||||
InstantiateAndSelectInteractable();
|
||||
}
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_Interactor = GetComponent<XRBaseInteractor>();
|
||||
|
||||
if (m_OverrideStartingSelectedInteractable)
|
||||
OverrideStartingSelectedInteractable();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
if (m_InteractablePrefab == null)
|
||||
{
|
||||
Debug.LogWarning("No interactable prefab set - nothing to spawn!");
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
m_Interactor.selectExited.AddListener(OnSelectExited);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
m_Interactor.selectExited.RemoveListener(OnSelectExited);
|
||||
}
|
||||
|
||||
void OnSelectExited(SelectExitEventArgs selectExitEventArgs)
|
||||
{
|
||||
if (selectExitEventArgs.isCanceled || !active)
|
||||
return;
|
||||
|
||||
InstantiateAndSelectInteractable();
|
||||
}
|
||||
|
||||
XRBaseInteractable InstantiateInteractable()
|
||||
{
|
||||
var socketTransform = m_Interactor.transform;
|
||||
return Instantiate(m_InteractablePrefab, socketTransform.position, socketTransform.rotation);
|
||||
}
|
||||
|
||||
void OverrideStartingSelectedInteractable()
|
||||
{
|
||||
m_Interactor.startingSelectedInteractable = InstantiateInteractable();
|
||||
}
|
||||
|
||||
void InstantiateAndSelectInteractable()
|
||||
{
|
||||
if (!gameObject.activeInHierarchy || m_Interactor.interactionManager == null)
|
||||
return;
|
||||
|
||||
m_Interactor.interactionManager.SelectEnter((IXRSelectInteractor)m_Interactor, InstantiateInteractable());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6333ea004bd36114bacc94bf07346f73
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Grid Socket interactor that only selects and hovers interactables with a <see cref="Keychain"/> component containing specific keys.
|
||||
/// </summary>
|
||||
public class XRLockGridSocketInteractor : XRGridSocketInteractor
|
||||
{
|
||||
[Space]
|
||||
[SerializeField]
|
||||
[Tooltip("The required keys to interact with this socket.")]
|
||||
Lock m_Lock;
|
||||
|
||||
/// <summary>
|
||||
/// The required keys to interact with this socket.
|
||||
/// </summary>
|
||||
public Lock keychainLock
|
||||
{
|
||||
get => m_Lock;
|
||||
set => m_Lock = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanHover(IXRHoverInteractable interactable)
|
||||
{
|
||||
if (!base.CanHover(interactable))
|
||||
return false;
|
||||
|
||||
var keyChain = interactable.transform.GetComponent<IKeychain>();
|
||||
return m_Lock.CanUnlock(keyChain);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSelect(IXRSelectInteractable interactable)
|
||||
{
|
||||
if (!base.CanSelect(interactable))
|
||||
return false;
|
||||
|
||||
var keyChain = interactable.transform.GetComponent<IKeychain>();
|
||||
return m_Lock.CanUnlock(keyChain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8349f6fd95eb89e40bbdfc16e4f63146
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine.XR.Interaction.Toolkit;
|
||||
|
||||
namespace UnityEngine.XR.Content.Interaction
|
||||
{
|
||||
/// <summary>
|
||||
/// Socket interactor that only selects and hovers interactables with a keychain component containing specific keys.
|
||||
/// </summary>
|
||||
public class XRLockSocketInteractor : XRSocketInteractor
|
||||
{
|
||||
[Space]
|
||||
[SerializeField]
|
||||
[Tooltip("The required keys to interact with this socket.")]
|
||||
Lock m_Lock;
|
||||
|
||||
/// <summary>
|
||||
/// The required keys to interact with this socket.
|
||||
/// </summary>
|
||||
public Lock keychainLock
|
||||
{
|
||||
get => m_Lock;
|
||||
set => m_Lock = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanHover(IXRHoverInteractable interactable)
|
||||
{
|
||||
if (!base.CanHover(interactable))
|
||||
return false;
|
||||
|
||||
var keyChain = interactable.transform.GetComponent<IKeychain>();
|
||||
return m_Lock.CanUnlock(keyChain);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanSelect(IXRSelectInteractable interactable)
|
||||
{
|
||||
if (!base.CanSelect(interactable))
|
||||
return false;
|
||||
|
||||
var keyChain = interactable.transform.GetComponent<IKeychain>();
|
||||
return m_Lock.CanUnlock(keyChain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eecc085bf63270540b2d9a418fb5f149
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user