playMaker

Author Topic: Get signed angle between two gameObjects  (Read 6077 times)

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 12351
  • Official Playmaker Support
    • View Profile
Get signed angle between two gameObjects
« on: January 19, 2012, 04:56:47 AM »
Hi,

 Here is a quite usefull little action to retrieve the angle between two gameObjects. The twist is that it retrieves not just the shortest angle, but the signed angles two, which means you can then animate your gameObject to rotate to that other gameObject either clock wise or counter clock wise. Combined with "iTween rotate add", you end up with a very flexible system to rotate gameObject the direction you want.

 It currently return the y angle, if you need more flexibility and have the action let you decide around what axis you want the angles, just shout, and I'll work it out.

Code: [Select]
// (c) copyright Hutong Games, LLC 2010-2011. All rights reserved.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Transform)]
[Tooltip("Get the signed angle around the y axis between the gameObject and a target gameObject. Allow you to retrieve both positive and negative angle. Usefull for example if you want to get the delta angle always clockwise ( positive)")]
public class GetEulerDeltaAngle : FsmStateAction
{
[RequiredField]
public FsmOwnerDefault gameObject;

public FsmGameObject target;

[UIHint(UIHint.Variable)]
[Tooltip("The shortest Angle. unsigned.")]
public FsmFloat angle;

[UIHint(UIHint.Variable)]
[Tooltip("The signed Angle. This is also the shortest distance.")]
public FsmFloat signedAngle;

[UIHint(UIHint.Variable)]
[Tooltip("The positive delta angle. This means the ClockWise travel to reach the target")]
public FsmFloat resultPositiveAngle;

[UIHint(UIHint.Variable)]
[Tooltip("The negative delta angle. This means the Counter ClockWise travel to reach the target")]
public FsmFloat resultNegativeAngle;


[Tooltip("Repeat this action every frame.")]
public bool everyFrame;


public override void Reset()
{
gameObject = null;
target = null;
signedAngle = null;
resultPositiveAngle = null;
resultNegativeAngle = null;
}

public override void OnEnter()
{
DoGetSignedAngle();

if (!everyFrame)
{
Finish();
}
}

public override void OnUpdate()
{
DoGetSignedAngle();
}


void DoGetSignedAngle()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);

if (go == null)
{
return;
}

GameObject goTarget = target.Value;
if (goTarget == null)
{
return;
}

angle.Value = Quaternion.Angle(go.transform.rotation, goTarget.transform.rotation);

// get a "forward vector" for each rotation
Vector3 forwardA = go.transform.rotation * Vector3.forward;
Vector3 forwardB = goTarget.transform.rotation * Vector3.forward;

// get a numeric angle for each vector, on the X-Z plane (relative to world forward)
float angleA = Mathf.Atan2(forwardA.x, forwardA.z) * Mathf.Rad2Deg;
float angleB = Mathf.Atan2(forwardB.x, forwardB.z) * Mathf.Rad2Deg;

// get the signed difference in these angles
float _signedAngle = Mathf.DeltaAngle( angleA, angleB );

signedAngle.Value = _signedAngle;
if (_signedAngle <0){
resultNegativeAngle.Value = _signedAngle;
resultPositiveAngle.Value = 360f +_signedAngle;
}else{
resultNegativeAngle.Value = -360f+_signedAngle;
resultPositiveAngle.Value = _signedAngle;
}

}
}
}

 Bye,

 Jean

markinjapan

  • Full Member
  • ***
  • Posts: 103
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #1 on: January 29, 2012, 06:12:26 PM »
Hi,

Just wanted to say that this is extremely useful for what I am doing right now. Y is perfect for me right now but I can see the other axis being useful as well.

Wish I'd found this earlier, I wouldn't have been scratching my head so much this week :)

Thanks

Mark

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 12351
  • Official Playmaker Support
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #2 on: January 29, 2012, 10:52:55 PM »
Hi,

 Yes, This is the kind of things that should be built in transform and quaternion api really... this is so important in many to reach an angle CW or CCW. And by default this is very hard to achieve indeed. It took me a while and many painful iterations to to reach a good technic for this.

 Bye,

 Jean

4s4

  • Playmaker Newbie
  • *
  • Posts: 34
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #3 on: February 04, 2013, 08:20:12 AM »
Sorry to dig this up from the grave, but any luck getting a version of this with x/z axis?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 12351
  • Official Playmaker Support
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #4 on: February 08, 2013, 12:00:40 AM »
Hi,

 To get this without any mods, you can create an empty gameObject that is the parent of your real model, and orient the y axis of the empty gameObject to the x or y axis of your real model ( and then parent the model to that dummy), then with this action you would get in fact the x or z axis angle of your model

 Does that make sense? trying to avoid doing the math here...  :P

bye,

 Jean

Nog

  • Playmaker Newbie
  • *
  • Posts: 47
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #5 on: October 18, 2015, 01:57:50 PM »
Thank you jeanfabre! I was wondering why this action is not in the Ecosystem? It is very useful to detect positive and negative angles for itween and other actions.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 12351
  • Official Playmaker Support
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #6 on: October 29, 2015, 10:53:39 PM »
Hi,

 there is a "GetSignedAngleToTarget" on the ecosystem, which I think is this one, only renamed.

Let me know if that one works for you.

 Bye,

 Jean

gregacuna

  • Junior Playmaker
  • **
  • Posts: 83
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #7 on: November 25, 2016, 10:30:13 AM »
I've tried Importing this CS file, but it doesn't show up in the Action Browser. I've read several posts and tried it in the Playmaker/Actions folder and in a custom_script folder, but it isn't there.

I'll try to other one with tangent in it from the Ecosystem, but would like to figure this out so I can do it in the future.

Thanks, Greg

Pandur

  • Junior Playmaker
  • **
  • Posts: 82
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #8 on: July 28, 2017, 05:25:02 AM »
same Problem here i see no the action on browser...

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 2280
    • View Profile
    • jinxtergames
Re: Get signed angle between two gameObjects
« Reply #9 on: July 30, 2017, 01:02:18 AM »
Hi.
You can rename the file to GetEulerDeltaAngle.cs
And search for that name.

GetEulerDeltaAngle is the actual class and you can find it without renaming, but it is better to change the name from the file.

Pandur

  • Junior Playmaker
  • **
  • Posts: 82
    • View Profile
Re: Get signed angle between two gameObjects
« Reply #10 on: July 30, 2017, 01:53:55 PM »
Thx, yes right i have found it :D