mirror of
https://github.com/nothke/quality-control.git
synced 2025-08-29 15:13:42 +00:00
Added interaction, hand, rigidbody dragging, picking up hammer
This commit is contained in:
196
Assets/Plugins/Interaction/Runtime/Items/Slot.cs
Normal file
196
Assets/Plugins/Interaction/Runtime/Items/Slot.cs
Normal file
@@ -0,0 +1,196 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
using Nothke.Interaction.Items;
|
||||
using Nothke.Interaction.UI;
|
||||
|
||||
namespace Nothke.Interaction
|
||||
{
|
||||
public class Slot : Interactable, IItemReceivable, IItemInHandsInteractionDependable
|
||||
{
|
||||
public Transform slotPivot;
|
||||
|
||||
public string slotTag;
|
||||
public virtual string SlotTag => slotTag;
|
||||
|
||||
public ISlottable itemInSlot;
|
||||
public bool Occupied => itemInSlot != null;
|
||||
|
||||
public override string Label
|
||||
{
|
||||
get
|
||||
{
|
||||
if (itemInSlot != null)
|
||||
return (itemInSlot as Interactable).Label;
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void Awake()
|
||||
{
|
||||
if (slotPivot.IsNonUniform())
|
||||
Debug.LogError("Slot lossy scale is not uniform, this is not allowed.", slotPivot);
|
||||
}
|
||||
#endif
|
||||
|
||||
public virtual bool IsInteractableIfHolding(Interactable item)
|
||||
{
|
||||
// if occupied and holding an item, not able to interact
|
||||
if (item != null && itemInSlot != null)
|
||||
return false;
|
||||
|
||||
// if occupied and not holding anything, able to take
|
||||
if (item == null && itemInSlot != null)
|
||||
return true;
|
||||
|
||||
var slottable = item as ISlottable;
|
||||
|
||||
if (slottable == null) return false;
|
||||
|
||||
if (!slottable.IsSlottable)
|
||||
return false;
|
||||
|
||||
if (CanReceive(slottable))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool CanReceive(ISlottable slottable)
|
||||
{
|
||||
if (itemInSlot != null) return false;
|
||||
|
||||
Debug.Assert(slottable != null, "CanReceive slottable is null");
|
||||
|
||||
if (slottable.SlotTag == SlotTag)
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
public override void Use(InteractionController im)
|
||||
{
|
||||
manager = im;
|
||||
SlotOrTake(im);
|
||||
}
|
||||
|
||||
public void SlotOrTake(InteractionController im)
|
||||
{
|
||||
var hands = im.hands;
|
||||
|
||||
if (!hands.item && itemInSlot != null)
|
||||
{
|
||||
if (IsTakeable)
|
||||
Take();
|
||||
}
|
||||
else
|
||||
if (hands.item && hands.item is ISlottable)
|
||||
{
|
||||
SlotItemFromHands(hands);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsTakeable => true;
|
||||
|
||||
public void Take()
|
||||
{
|
||||
if (itemInSlot == null)
|
||||
{
|
||||
Debug.LogError("Attempting to take an item from slot but there is none");
|
||||
return;
|
||||
}
|
||||
|
||||
var takeable = itemInSlot as ITakeable;
|
||||
|
||||
Debug.Assert(takeable != null, "Item is slottable but not takeable", this);
|
||||
|
||||
OnBeforeTaken();
|
||||
|
||||
manager.hands.Take(takeable);
|
||||
|
||||
itemInSlot.OnRemovedFromSlot();
|
||||
itemInSlot.SlottedIn = null;
|
||||
itemInSlot = null;
|
||||
|
||||
manager.Recast();
|
||||
}
|
||||
|
||||
public void SlotItemFromHands(IHands hands)
|
||||
{
|
||||
if (CanReceive(hands.item as ISlottable))
|
||||
{
|
||||
manager.hands.Place(Vector3.zero, Quaternion.identity, slotPivot, this);
|
||||
|
||||
var item = hands.item;
|
||||
|
||||
// if not smooth placement:
|
||||
//itemInSlot = item as ISlottable;
|
||||
//itemInSlot.SlottedIn = this;
|
||||
//itemInSlot.OnSlotted();
|
||||
//OnSlot();
|
||||
|
||||
// if smooth placement, hands will callback the slot:
|
||||
(item as ISlottable).OnStartedPlacing(hands);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetItemInSlot(ISlottable item)
|
||||
{
|
||||
Debug.Assert(item != null, "ISlottable passed is null");
|
||||
//Debug.Log("Slotted " + (item as Component).gameObject.name + " into " + gameObject.name, this);
|
||||
|
||||
if (CanReceive(item))
|
||||
{
|
||||
var itemT = (item as Component).transform;
|
||||
itemT.parent = slotPivot;
|
||||
itemT.localPosition = Vector3.zero;
|
||||
itemT.localRotation = Quaternion.identity;
|
||||
|
||||
itemInSlot = item;
|
||||
item.SlottedIn = this;
|
||||
|
||||
item.OnSlotted();
|
||||
OnSlot();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Slot can't receive this item, tags don't match OR already holding item", item as Component);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (manager)
|
||||
manager.Recast();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ISlottable RemoveItemFromSlot()
|
||||
{
|
||||
var takeable = itemInSlot as ITakeable;
|
||||
|
||||
OnBeforeTaken();
|
||||
|
||||
var _item = itemInSlot;
|
||||
itemInSlot = null;
|
||||
|
||||
(_item as Component).transform.SetParent(null);
|
||||
_item.OnRemovedFromSlot();
|
||||
_item.SlottedIn = null;
|
||||
|
||||
return _item;
|
||||
}
|
||||
|
||||
public virtual void OnBeforeTaken() { }
|
||||
public virtual void OnSlot() { }
|
||||
|
||||
public ReticleUI.State GetCustomReticle()
|
||||
{
|
||||
if (itemInSlot != null)
|
||||
return ReticleUI.State.Take;
|
||||
else
|
||||
return ReticleUI.State.Slot;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user