playMaker

Author Topic: On Touch Object Left (Touch Object Event improved)  (Read 2094 times)

Geropellicer

  • Playmaker Newbie
  • *
  • Posts: 10
On Touch Object Left (Touch Object Event improved)
« on: January 17, 2018, 02:38:58 PM »
Hi there. I have used the Touch Object Event for many projects and it has always worked ok, since it has so many functions. However for this new particular project I was needing a way to detect when the user's finger LEFT the object that was previously being touched (similar to HTML's and jQuery's onMouseEnter and OnMouseLeft).

After a couple of failed attempts, I think I have found a solution, customizing the Touch Object Event so that the new action includes all the previous functionalities and a new option of firing an event when the object is not touched any more.

As always I'm submitting this action for a) in case you think it's useful, just donwload it and use it and b) if you are a better coder than me, give some feedback about if this is the best way of working this situation around.


UPDATE:

After some tests, I've encountered that on most cases it is more useful to have the onTouchObjectLeft event on its own action, apart from the Touch Object Event action. So I'm uploading "Touch Object Left Simple" action, which only sends an event when the object is no longer being touched, and does not incorporate any other capabilities from the Touch Object Event action.


CODE FOR THE SIMPLE ACTION:
Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.

using System;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Device)]
[ActionTarget(typeof(GameObject), "gameObject")]
[Tooltip("SENDS AN EVENT WHEN A PREVIOSLY TOUCHED OBJECT IS NOT LONGER BEING TOUCHED.  Optionally filter by a fingerID. NOTE: Uses the MainCamera!")]
public class OnTouchObjectLeftSimple : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(Collider))]
[Tooltip("The Game Object to detect touches on.")]
public FsmOwnerDefault gameObject;

[RequiredField]
[Tooltip("How far from the camera is the Game Object pickable.")]
public FsmFloat pickDistance;

[Tooltip("Only detect touches that match this fingerID, or set to None.")]
public FsmInt fingerId;

[ActionSection("Events")]

[Tooltip("Event to send on touch cancel.")]
public FsmEvent touchLeftObject;

[ActionSection("Store Results")]

[UIHint(UIHint.Variable)]
[Tooltip("Store the fingerId of the touch.")]
public FsmInt storeFingerId;

[UIHint(UIHint.Variable)]
[Tooltip("Store the world position where the object was touched.")]
public FsmVector3 storeHitPoint;

[UIHint(UIHint.Variable)]
[Tooltip("Store the surface normal vector where the object was touched.")]
public FsmVector3 storeHitNormal;

public override void Reset()
{
gameObject = null;
pickDistance = 100;
fingerId = new FsmInt { UseVariable = true };

touchLeftObject = null;

storeFingerId = null;
storeHitPoint = null;
storeHitNormal = null;

alreadyTouched = false;
}
bool alreadyTouched = false;
public override void OnUpdate()
{

if (Camera.main == null)
{
LogError("No MainCamera defined!");
Finish();
return;
}

if (Input.touchCount > 0)
{
var go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null)
{
return;
}

foreach (var touch in Input.touches)
{
if (fingerId.IsNone || touch.fingerId == fingerId.Value)
{
var screenPos = touch.position;

RaycastHit hitInfo;
Physics.Raycast(Camera.main.ScreenPointToRay(screenPos), out hitInfo, pickDistance.Value);

// Store hitInfo so it can be accessed by other actions
// E.g., Get Raycast Hit Info
Fsm.RaycastHitInfo = hitInfo;

if (hitInfo.transform != null)
{
if (hitInfo.transform.gameObject == go)
{
storeFingerId.Value = touch.fingerId;
storeHitPoint.Value = hitInfo.point;
storeHitNormal.Value = hitInfo.normal;
Log ("FALSE");
switch (touch.phase)
{
case TouchPhase.Began:
alreadyTouched = true;
return;

case TouchPhase.Moved:
alreadyTouched = true;
return;

case TouchPhase.Stationary:
alreadyTouched = true;
return;
}
}
if (hitInfo.transform.gameObject != go && alreadyTouched) {
Log ("TRUE");
alreadyTouched = false;
Fsm.Event (touchLeftObject);
}
}
if (hitInfo.transform == null && alreadyTouched) {
Log ("TRUE");
alreadyTouched = false;
Fsm.Event (touchLeftObject);
}
}
}
}
}
}
}




CODE FOR THE COMPLETE ACTION:
Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.

using System;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Device)]
[ActionTarget(typeof(GameObject), "gameObject")]
[Tooltip("Sends events when an object is touched. ALSO SENDS AN EVENT WHEN A PREVIOSLY TOUCHED OBJECT IS NOT LONGER BEING TOUCHED.  Optionally filter by a fingerID. NOTE: Uses the MainCamera!")]
public class OnTouchObjectLeft : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(Collider))]
[Tooltip("The Game Object to detect touches on.")]
public FsmOwnerDefault gameObject;

[RequiredField]
[Tooltip("How far from the camera is the Game Object pickable.")]
public FsmFloat pickDistance;

[Tooltip("Only detect touches that match this fingerID, or set to None.")]
public FsmInt fingerId;

[ActionSection("Events")]

[Tooltip("Event to send on touch began.")]
public FsmEvent touchBegan;

[Tooltip("Event to send on touch moved.")]
public FsmEvent touchMoved;

[Tooltip("Event to send on stationary touch.")]
public FsmEvent touchStationary;

[Tooltip("Event to send on touch ended.")]
public FsmEvent touchEnded;

[Tooltip("Event to send on touch cancel.")]
public FsmEvent touchCanceled;

[Tooltip("Event to send on touch cancel.")]
public FsmEvent touchLeftObject;

[ActionSection("Store Results")]

[UIHint(UIHint.Variable)]
[Tooltip("Store the fingerId of the touch.")]
public FsmInt storeFingerId;

[UIHint(UIHint.Variable)]
[Tooltip("Store the world position where the object was touched.")]
public FsmVector3 storeHitPoint;

[UIHint(UIHint.Variable)]
[Tooltip("Store the surface normal vector where the object was touched.")]
public FsmVector3 storeHitNormal;

public override void Reset()
{
gameObject = null;
pickDistance = 100;
fingerId = new FsmInt { UseVariable = true };

touchBegan = null;
touchMoved = null;
touchStationary = null;
touchEnded = null;
touchCanceled = null;
touchLeftObject = null;

storeFingerId = null;
storeHitPoint = null;
storeHitNormal = null;

alreadyTouched = false;
}
bool alreadyTouched = false;
public override void OnUpdate()
{

if (Camera.main == null)
{
LogError("No MainCamera defined!");
Finish();
return;
}

if (Input.touchCount > 0)
{
var go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null)
{
return;
}

foreach (var touch in Input.touches)
{
if (fingerId.IsNone || touch.fingerId == fingerId.Value)
{
var screenPos = touch.position;

RaycastHit hitInfo;
Physics.Raycast(Camera.main.ScreenPointToRay(screenPos), out hitInfo, pickDistance.Value);

// Store hitInfo so it can be accessed by other actions
// E.g., Get Raycast Hit Info
Fsm.RaycastHitInfo = hitInfo;

if (hitInfo.transform != null)
{
if (hitInfo.transform.gameObject == go)
{
storeFingerId.Value = touch.fingerId;
storeHitPoint.Value = hitInfo.point;
storeHitNormal.Value = hitInfo.normal;
Log ("FALSE");
switch (touch.phase)
{
case TouchPhase.Began:
alreadyTouched = true;
Fsm.Event(touchBegan);
return;

case TouchPhase.Moved:
alreadyTouched = true;
Fsm.Event(touchMoved);
return;

case TouchPhase.Stationary:
alreadyTouched = true;
Fsm.Event(touchStationary);
return;

case TouchPhase.Ended:
Fsm.Event(touchEnded);
return;

case TouchPhase.Canceled:
Fsm.Event(touchCanceled);
return;
}
}
if (hitInfo.transform.gameObject != go && alreadyTouched) {
Log ("TRUE");
alreadyTouched = false;
Fsm.Event (touchLeftObject);
}
}
if (hitInfo.transform == null && alreadyTouched) {
Log ("TRUE");
alreadyTouched = false;
Fsm.Event (touchLeftObject);
}
}
}
}
}
}
}
« Last Edit: January 17, 2018, 03:22:09 PM by Geropellicer »