123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- //======= Copyright (c) Valve Corporation, All rights reserved. ===============
- //
- // Purpose: Handles the spawning and returning of the ItemPackage
- //
- //=============================================================================
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using UnityEngine.Events;
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- namespace Valve.VR.InteractionSystem
- {
- //-------------------------------------------------------------------------
- [RequireComponent( typeof( Interactable ) )]
- public class ItemPackageSpawner : MonoBehaviour
- {
- public ItemPackage itemPackage
- {
- get
- {
- return _itemPackage;
- }
- set
- {
- CreatePreviewObject();
- }
- }
- public ItemPackage _itemPackage;
- public bool useItemPackagePreview = true;
- private bool useFadedPreview = false;
- private GameObject previewObject;
- public bool requireGrabActionToTake = false;
- public bool requireReleaseActionToReturn = false;
- public bool showTriggerHint = false;
- [EnumFlags]
- public Hand.AttachmentFlags attachmentFlags = Hand.defaultAttachmentFlags;
- public bool takeBackItem = false; // if a hand enters this trigger and has the item this spawner dispenses at the top of the stack, remove it from the stack
- public bool acceptDifferentItems = false;
- private GameObject spawnedItem;
- private bool itemIsSpawned = false;
- public UnityEvent pickupEvent;
- public UnityEvent dropEvent;
- public bool justPickedUpItem = false;
- //-------------------------------------------------
- private void CreatePreviewObject()
- {
- if ( !useItemPackagePreview )
- {
- return;
- }
- ClearPreview();
- if ( useItemPackagePreview )
- {
- if ( itemPackage == null )
- {
- return;
- }
- if ( useFadedPreview == false ) // if we don't have a spawned item out there, use the regular preview
- {
- if ( itemPackage.previewPrefab != null )
- {
- previewObject = Instantiate( itemPackage.previewPrefab, transform.position, Quaternion.identity ) as GameObject;
- previewObject.transform.parent = transform;
- previewObject.transform.localRotation = Quaternion.identity;
- }
- }
- else // there's a spawned item out there. Use the faded preview
- {
- if ( itemPackage.fadedPreviewPrefab != null )
- {
- previewObject = Instantiate( itemPackage.fadedPreviewPrefab, transform.position, Quaternion.identity ) as GameObject;
- previewObject.transform.parent = transform;
- previewObject.transform.localRotation = Quaternion.identity;
- }
- }
- }
- }
- //-------------------------------------------------
- void Start()
- {
- VerifyItemPackage();
- }
- //-------------------------------------------------
- private void VerifyItemPackage()
- {
- if ( itemPackage == null )
- {
- ItemPackageNotValid();
- }
- if ( itemPackage.itemPrefab == null )
- {
- ItemPackageNotValid();
- }
- }
- //-------------------------------------------------
- private void ItemPackageNotValid()
- {
- Debug.LogError("<b>[SteamVR Interaction]</b> ItemPackage assigned to " + gameObject.name + " is not valid. Destroying this game object.", this);
- Destroy( gameObject );
- }
- //-------------------------------------------------
- private void ClearPreview()
- {
- foreach ( Transform child in transform )
- {
- if ( Time.time > 0 )
- {
- GameObject.Destroy( child.gameObject );
- }
- else
- {
- GameObject.DestroyImmediate( child.gameObject );
- }
- }
- }
- //-------------------------------------------------
- void Update()
- {
- if ( ( itemIsSpawned == true ) && ( spawnedItem == null ) )
- {
- itemIsSpawned = false;
- useFadedPreview = false;
- dropEvent.Invoke();
- CreatePreviewObject();
- }
- }
- //-------------------------------------------------
- private void OnHandHoverBegin( Hand hand )
- {
- ItemPackage currentAttachedItemPackage = GetAttachedItemPackage( hand );
- if ( currentAttachedItemPackage == itemPackage ) // the item at the top of the hand's stack has an associated ItemPackage
- {
- if ( takeBackItem && !requireReleaseActionToReturn ) // if we want to take back matching items and aren't waiting for a trigger press
- {
- TakeBackItem( hand );
- }
- }
- if (!requireGrabActionToTake) // we don't require trigger press for pickup. Spawn and attach object.
- {
- SpawnAndAttachObject( hand, GrabTypes.Scripted );
- }
- if (requireGrabActionToTake && showTriggerHint )
- {
- hand.ShowGrabHint("PickUp");
- }
- }
- //-------------------------------------------------
- private void TakeBackItem( Hand hand )
- {
- RemoveMatchingItemsFromHandStack( itemPackage, hand );
- if ( itemPackage.packageType == ItemPackage.ItemPackageType.TwoHanded )
- {
- RemoveMatchingItemsFromHandStack( itemPackage, hand.otherHand );
- }
- }
- //-------------------------------------------------
- private ItemPackage GetAttachedItemPackage( Hand hand )
- {
- GameObject currentAttachedObject = hand.currentAttachedObject;
- if ( currentAttachedObject == null ) // verify the hand is holding something
- {
- return null;
- }
- ItemPackageReference packageReference = hand.currentAttachedObject.GetComponent<ItemPackageReference>();
- if ( packageReference == null ) // verify the item in the hand is matchable
- {
- return null;
- }
- ItemPackage attachedItemPackage = packageReference.itemPackage; // return the ItemPackage reference we find.
- return attachedItemPackage;
- }
- //-------------------------------------------------
- private void HandHoverUpdate( Hand hand )
- {
- if ( takeBackItem && requireReleaseActionToReturn )
- {
- if (hand.isActive)
- {
- ItemPackage currentAttachedItemPackage = GetAttachedItemPackage( hand );
- if (currentAttachedItemPackage == itemPackage && hand.IsGrabEnding(currentAttachedItemPackage.gameObject))
- {
- TakeBackItem( hand );
- return; // So that we don't pick up an ItemPackage the same frame that we return it
- }
- }
- }
- if ( requireGrabActionToTake )
- {
- GrabTypes startingGrab = hand.GetGrabStarting();
- if (startingGrab != GrabTypes.None)
- {
- SpawnAndAttachObject( hand, GrabTypes.Scripted);
- }
- }
- }
- //-------------------------------------------------
- private void OnHandHoverEnd( Hand hand )
- {
- if ( !justPickedUpItem && requireGrabActionToTake && showTriggerHint )
- {
- hand.HideGrabHint();
- }
- justPickedUpItem = false;
- }
- //-------------------------------------------------
- private void RemoveMatchingItemsFromHandStack( ItemPackage package, Hand hand )
- {
- if (hand == null)
- return;
- for ( int i = 0; i < hand.AttachedObjects.Count; i++ )
- {
- ItemPackageReference packageReference = hand.AttachedObjects[i].attachedObject.GetComponent<ItemPackageReference>();
- if ( packageReference != null )
- {
- ItemPackage attachedObjectItemPackage = packageReference.itemPackage;
- if ( ( attachedObjectItemPackage != null ) && ( attachedObjectItemPackage == package ) )
- {
- GameObject detachedItem = hand.AttachedObjects[i].attachedObject;
- hand.DetachObject( detachedItem );
- }
- }
- }
- }
- //-------------------------------------------------
- private void RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType packageType, Hand hand )
- {
- for ( int i = 0; i < hand.AttachedObjects.Count; i++ )
- {
- ItemPackageReference packageReference = hand.AttachedObjects[i].attachedObject.GetComponent<ItemPackageReference>();
- if ( packageReference != null )
- {
- if ( packageReference.itemPackage.packageType == packageType )
- {
- GameObject detachedItem = hand.AttachedObjects[i].attachedObject;
- hand.DetachObject( detachedItem );
- }
- }
- }
- }
- //-------------------------------------------------
- private void SpawnAndAttachObject( Hand hand, GrabTypes grabType )
- {
- if ( hand.otherHand != null )
- {
- //If the other hand has this item package, take it back from the other hand
- ItemPackage otherHandItemPackage = GetAttachedItemPackage( hand.otherHand );
- if ( otherHandItemPackage == itemPackage )
- {
- TakeBackItem( hand.otherHand );
- }
- }
- if ( showTriggerHint )
- {
- hand.HideGrabHint();
- }
- if ( itemPackage.otherHandItemPrefab != null )
- {
- if ( hand.otherHand.hoverLocked )
- {
- Debug.Log( "<b>[SteamVR Interaction]</b> Not attaching objects because other hand is hoverlocked and we can't deliver both items." );
- return;
- }
- }
- // if we're trying to spawn a one-handed item, remove one and two-handed items from this hand and two-handed items from both hands
- if ( itemPackage.packageType == ItemPackage.ItemPackageType.OneHanded )
- {
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand );
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand );
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand.otherHand );
- }
- // if we're trying to spawn a two-handed item, remove one and two-handed items from both hands
- if ( itemPackage.packageType == ItemPackage.ItemPackageType.TwoHanded )
- {
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand );
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.OneHanded, hand.otherHand );
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand );
- RemoveMatchingItemTypesFromHand( ItemPackage.ItemPackageType.TwoHanded, hand.otherHand );
- }
- spawnedItem = GameObject.Instantiate( itemPackage.itemPrefab );
- spawnedItem.SetActive( true );
- hand.AttachObject( spawnedItem, grabType, attachmentFlags );
- if ( ( itemPackage.otherHandItemPrefab != null ) && ( hand.otherHand.isActive ) )
- {
- GameObject otherHandObjectToAttach = GameObject.Instantiate( itemPackage.otherHandItemPrefab );
- otherHandObjectToAttach.SetActive( true );
- hand.otherHand.AttachObject( otherHandObjectToAttach, grabType, attachmentFlags );
- }
- itemIsSpawned = true;
- justPickedUpItem = true;
- if ( takeBackItem )
- {
- useFadedPreview = true;
- pickupEvent.Invoke();
- CreatePreviewObject();
- }
- }
- }
- }
|