Well that was pretty damn helpful! I couldn't figure out how to build that out of actions so I just made an action out of the script, see the attachment for the Action and Sample Scene.
I dunno how to translate the last bit of his code to PM actions, he does AddTorque with the vector3, the angle float and float multiplier for torque which confuses me.. I didn't even know you could do that and it seems to 'just work'. Makes perfect sense, but (to me) only in code.
Either way, really it was a great and fun learning experience making the action so thanks a bunch for the link! I might add a keep vertical option, or make a new action for keeping vertical with choice of direction and add an oscillation tolerance float with an if statement to return if the result is too small.
// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.
// original script here: http://wiki.unity3d.com/index.php/TorqueLookRotation
using UnityEngine;
using System.Collections;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Physics)]
[Tooltip("Order a game object to look at a target by using Torque on its axi")]
public class TorqueLookRotation : FsmStateAction
{
[RequiredField]
[CheckForComponent(typeof(Rigidbody))]
[Tooltip("The object to effect.")]
public FsmOwnerDefault gameObject;
[RequiredField]
[Tooltip("The target it should be looking at")]
public FsmGameObject targetObject;
[RequiredField]
[Tooltip("The multiplier of torque to apply.")]
public float forceMultiplier;
[Tooltip("Repeat every frame.")]
public bool everyFrame = true;
public override void Reset()
{
gameObject = null;
targetObject = null;
forceMultiplier = 0.1f;
everyFrame = true;
}
public override void OnEnter()
{
DoLookAt();
if (!everyFrame)
{
Finish();
}
}
public override void OnFixedUpdate()
{
DoLookAt();
}
void DoLookAt() {
var go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null)
{
LogWarning("Missing GameObject to manipulate!");
return;
}
if (go.rigidbody == null)
{
LogWarning("Missing rigid body: " + go.name);
return;
}
var target = targetObject.Value;
if (target == null)
{
LogWarning("Missing target object to look at!");
return;
}
Vector3 targetDelta = target.transform.position - go.transform.position;
//get the angle between transform.forward and target delta
float angleDiff = Vector3.Angle(go.transform.forward, targetDelta);
// get its cross product, which is the axis of rotation to
// get from one vector to the other
Vector3 cross = Vector3.Cross(go.transform.forward, targetDelta);
// apply torque along that axis according to the magnitude of the angle.
go.rigidbody.AddTorque(cross * angleDiff * forceMultiplier);
}
}
}
*edit for code