playMaker

Author Topic: In need of simple Global Touch Object Event  (Read 3305 times)

GuyKil

  • Playmaker Newbie
  • *
  • Posts: 2
In need of simple Global Touch Object Event
« on: July 12, 2012, 11:10:24 AM »
Hello! I am in need of a Touch Object Event that I can attach to a game object that will trigger an event when any object is touched.

It will need to be able to store the game object that was touched and maybe even have a filter by tag / layer option.

At the moment I need to apply Touch Object Event to every object I need to have the listener, so this would speed things up a lot!

Thanks!

GuyKil

  • Playmaker Newbie
  • *
  • Posts: 2
Re: In need of simple Global Touch Object Event
« Reply #1 on: July 12, 2012, 11:31:25 AM »
I ended up making this myself as I figured it only needed a slight edit of the current Touch Object Event.

All I had to do was add a storage variable for the Hit Object

I was unsure how to add the filtering part though, so I simply called a Compare Object Tag afterwards which worked fine :)

Here it is!
Code: [Select]
using System;
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Device)]
[Tooltip("Sends events when any object is touched. Optionally filter by a fingerID. NOTE: Uses the MainCamera!")]
public class TouchAnyObjectEvent : FsmStateAction
{

[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;

[ActionSection("Store Results")]

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

[UIHint(UIHint.Variable)]
[Tooltip("Store the object that was hit.")]
public FsmGameObject storeHitObject;

[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()
{
pickDistance = 100;
fingerId = new FsmInt { UseVariable = true };

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

storeHitObject = null;
storeFingerId = null;
storeHitPoint = null;
storeHitNormal = null;
}

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

if (Input.touchCount > 0)
{

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) {
return;
}
if (hitInfo.transform.gameObject == null) {
return;
}
storeHitObject.Value = hitInfo.transform.gameObject;
storeFingerId.Value = touch.fingerId;
storeHitPoint.Value = hitInfo.point;
storeHitNormal.Value = hitInfo.normal;

switch (touch.phase)
{
case TouchPhase.Began:
Fsm.Event(touchBegan);
return;

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

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

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

case TouchPhase.Canceled:
Fsm.Event(touchCanceled);
return;
}
}
}
}
}
}
}


Update: There is one small bug with this, if you are trying to have this script listen for multiple fingers, it will not work. It will track the first finger placed on the screen and not any after that if they are touching at the same time. This is because if the first finger is still touching, the Touch Stationary or Touch Moved event is called and the checks are ended before any future fingers are checked.
I got around this by removing the stationary and moved event call on my script, but i'm sure there is a better way. I'll leave it in in the above code
Another work around would be to have the Touch Any Object action added twice (or more if more fingers) and set the finger ID to 0 on the first one and 1 on the second etc.
« Last Edit: July 12, 2012, 12:26:57 PM by GuyKil »