using UnityEngine;
using Zinnia.Action;
using VRTK.Prefabs.Interactions.Interactables;
public class SwapClimbGrabFunctions : MonoBehaviour
{
public GameObject climbLogic, grabLogic;
public Transform graphicalRepresentation;
public bool isGrab = true;
private BooleanAction grabAction;
private bool isSwapping = false;
private void Update()
{
// This can probably be handled better by listening for a change in position/rotation
if(isGrab)
{
graphicalRepresentation.position = grabLogic.transform.position;
graphicalRepresentation.rotation = grabLogic.transform.rotation;
climbLogic.transform.position = grabLogic.transform.position;
climbLogic.transform.rotation = grabLogic.transform.rotation;
} else
{
graphicalRepresentation.position = climbLogic.transform.position;
graphicalRepresentation.rotation = climbLogic.transform.rotation;
grabLogic.transform.position = climbLogic.transform.position;
grabLogic.transform.rotation = climbLogic.transform.rotation;
}
}
public void SwapFunctionality()
{
// Needs to know not to lose grabAction reference
isSwapping = true;
if (grabAction != null)
{
//Ungrab
grabAction.Receive(false);
//Swap
grabLogic.SetActive(!isGrab);
climbLogic.SetActive(isGrab);
//Regrab
grabAction.Receive(true);
}
else
{
//Swap
grabLogic.SetActive(!isGrab);
climbLogic.SetActive(isGrab);
}
isGrab = !isGrab;
// Script is now free to forget the grabAction
isSwapping = false;
}
public void SetGrabAction(InteractableFacade interactable)
{
if (!isSwapping)
{
if (interactable != null)
{
grabAction = interactable.GrabbingInteractors[0].GrabAction;
}
else
{
grabAction = null;
}
}
}
public void RemoveGrabAction()
{
SetGrabAction(null);
}
}
climbLogic and grabLogic need to be set to the two prefabs you're swapping between. isGrab should be set to true if it starts out grabbable and false if it starts out climbable. graphicalRepresentation needs to be set to the purely graphical object that is following these interactable objects.
SwapFunctionality() is currently called in my scene by pressing right trigger, but it can be called by anything to swap between grabbing and climbing. SetGrabAction and RemoveGrabAction need to be called by the grabbed and ungrabbed Grab Events in the Interactable Facade of both objects you're swapping between. For the climbing object, the component is found in Climbable-Internal-Interactable. For the grabbing object, the component is found in the base object.
This doesn't play nice with changing the object between hands. I'm not sure why this is, but due to the nature of the grapple gun I'm going after, it doesn't matter for my implementation.