Skip to content

Commit

Permalink
feat(behaviours): add grabable (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xenira committed Mar 6, 2024
1 parent 3e6de5c commit 7721250
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 0 deletions.
83 changes: 83 additions & 0 deletions plugin/src/objects/behaviours/Grabable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Linq;
using PiUtils.Util;
using UnityEngine;

namespace PiUtils.Objects.Behaviours;
public class Grabable : MonoBehaviour
{
private static readonly PluginLogger Logger = PluginLogger.GetLogger<Grabable>();

public bool IsGrabbed { get; private set; } = false;
public bool IsHovered { get; private set; } = false;

public float grabDistance = 0.2f;

public bool snapToHand = false;
public Option<Vector3> grabOffset = Option<Vector3>.None();
public Option<Quaternion> grabRotation = Option<Quaternion>.None();

public Transform originalParent { get; private set; }

public Grabable() { }

public Grabable(float? grabDistance, bool snapToHand, Option<Vector3> grabOffset, Option<Quaternion> grabRotation)
{
this.grabDistance = grabDistance ?? this.grabDistance;
this.snapToHand = snapToHand;
this.grabOffset = grabOffset;
this.grabRotation = grabRotation;
}

public bool TryGrab(Transform grabbingTransform)
{
if (IsGrabbed)
{
Logger.LogDebug("Object already grabbed: " + gameObject.name);
return false;
}

var distance = Vector3.Distance(transform.position, grabbingTransform.position);
if (grabDistance >= 0 && distance >= grabDistance)
{
Logger.LogDebug($"Object too far to grab: {gameObject.name} ({distance} > {grabDistance})");
return false;
}

Grab(grabbingTransform);
return IsGrabbed;
}

public void Grab(Transform grabbingTransform)
{
if (IsGrabbed)
{
return;
}

Logger.LogDebug("Grabbing object: " + gameObject.name);

IsGrabbed = true;
originalParent = transform.parent;

if (snapToHand)
{
transform.position = grabbingTransform.position + grabOffset.FirstOrDefault();
transform.rotation = grabbingTransform.rotation * grabRotation.FirstOrDefault();
}

transform.SetParent(grabbingTransform, true);
}

public void Release()
{
if (!IsGrabbed)
{
return;
}

IsGrabbed = false;
transform.SetParent(originalParent, true);

originalParent = null;
}
}
15 changes: 15 additions & 0 deletions plugin/src/util/Option.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ private Option(T[] data)
this.data = data;
}

public static Option<T> New(T value)
{
if (value == null)
{
return None();
}

return Some(value);
}

public static Option<T> Some(T value)
{
return new Option<T>([value]);
Expand All @@ -21,6 +31,11 @@ public static Option<T> None()
return new Option<T>([]);
}

public bool IsSome()
{
return data.Length > 0;
}

public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)data).GetEnumerator();
Expand Down

0 comments on commit 7721250

Please sign in to comment.