playMaker

Author Topic: Maximum degrees for a smooth look at like script?[SOLVED]  (Read 3218 times)

Stuard

  • Playmaker Newbie
  • *
  • Posts: 15
Maximum degrees for a smooth look at like script?[SOLVED]
« on: August 05, 2017, 08:41:44 AM »
Does anyone have an idea how to rebuild this script https://forum.unity3d.com/threads/gradual-rotation-change.60793/ ( or the one i posted right down here) as an SFM?
it functions like smooth look at but with a cap when it reaches a ceartan amount of degrees per second and then the object cant rotate faster. I tried to add this to the smooth look at function but my knowledge is limited :)
http://hutonggames.com/playmakerforum/index.php?topic=15536.0

Code: [Select]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Turret_XRotation : MonoBehaviour

{

public Transform target;
public float maxDegreesPerSecond = 13.1f;
public float rotationSpeed = 10f;


void Update ()
{
Vector3 targetDirection = (target.position - transform.position).normalized;
Vector3 currentForward = transform.forward;
Vector3 newForward = Vector3.Slerp (currentForward, targetDirection, Time.deltaTime * rotationSpeed);

float angle = Vector3.Angle (currentForward, newForward);
float maxAngle = maxDegreesPerSecond * Time.deltaTime;
if (angle > maxAngle) {
newForward = Vector3.Slerp (currentForward, newForward, maxAngle / angle);
}

transform.forward = newForward;


}

}

The reason for me to have it as an FMS its mainly because the script jitters my camara setup and i like continuity. It sits in a Tank turret and even with lateupdate my camara jitters and it grinds my gears because i like that it is "just" one script that does what i want. Right now i try to (when i have time) rebuild it in a FSM but i cant get the direction right and it feels "wrong" because there is already one function that does at least one half :P

Some Preview https://youtu.be/vsdqHIgPjQI
« Last Edit: August 10, 2017, 03:01:03 AM by jeanfabre »

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7614
    • jinxtergames
Re: Maximum degrees for a smooth look at like script?
« Reply #1 on: August 09, 2017, 03:58:18 AM »
Hi,
I made an action according your script with some extra options like smooth look at.

You can find the attachment below.

Stuard

  • Playmaker Newbie
  • *
  • Posts: 15
Re: Maximum degrees for a smooth look at like script?
« Reply #2 on: August 09, 2017, 10:36:57 AM »
Gracias, djaydino!
//i will try it out today :)

hehe i fixed one "bug"  ;D
Code: [Select]
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{

[ActionCategory(ActionCategory.Transform)]
[Tooltip("rotate turret")]
public class Turret_xRotation : FsmStateAction
{
        [RequiredField]
        [Tooltip("The GameObject to rotate to face a target.")]
        public FsmOwnerDefault gameObject;

        [Tooltip("A target GameObject.")]
        public FsmGameObject targetObject;

        [Tooltip("A target position. If a Target Object is defined, this is used as a local offset.")]
        public FsmVector3 targetPosition;

        [Tooltip("How fast the look at moves.")]
        public FsmFloat RotationSpeed;

        [Tooltip("How fast the look at moves.")]
        public FsmFloat MaxDegreesPerSecond;

        [Tooltip("Force the game object to remain vertical. Useful for characters.")]
        public FsmBool keepVertical;

        [Tooltip("Draw a line in the Scene View to the look at position.")]
        public FsmBool debug;

        [Tooltip("If the angle to the target is less than this, send the Finish Event below. Measured in degrees.")]
        public FsmFloat finishTolerance;

        [Tooltip("Event to send if the angle to target is less than the Finish Tolerance.")]
        public FsmEvent finishEvent;

        private GameObject previousGo; // track game object so we can re-initialize when it changes.
        private Vector3 targetDirection;
        private Vector3 currentForward;
        private Vector3 newForward;
        private Vector3 desiredForward;
        private float angle;
        private float maxAngle;

        public override void Reset()
        {
            gameObject = null;
            targetObject = null;
            targetPosition = new FsmVector3 { UseVariable = true };
            debug = false;
            keepVertical = true;
            RotationSpeed = 5;
            MaxDegreesPerSecond = 5;
            finishTolerance = 1;
            finishEvent = null;
        }

        public override void OnEnter()
        {
            previousGo = null;
        }

        public override void OnLateUpdate()
        {
            DoSmoothLookAt();
        }

        void DoSmoothLookAt()
        {
            var go = Fsm.GetOwnerDefaultTarget(gameObject);
            if (go == null)
            {
                return;
            }

            var goTarget = targetObject.Value;
            if (goTarget == null && targetPosition.IsNone)
            {
                return;
            }

            // re-initialize if game object has changed

   /*        if (previousGo != go)
            {
                currentForward = go.transform.forward;
                desiredForward = currentForward;
                previousGo = go;
            }*/

            // desired look at position

            Vector3 lookAtPos;
            if (goTarget != null)
            {
                lookAtPos = !targetPosition.IsNone ?
                    goTarget.transform.TransformPoint(targetPosition.Value) :
                    goTarget.transform.position;
            }
            else
            {
                lookAtPos = targetPosition.Value;
            }

            if (keepVertical.Value)
            {
                lookAtPos.y = go.transform.position.y;
            }
            // smooth look at

            targetDirection = (lookAtPos - go.transform.position).normalized;
            currentForward = go.transform.forward;
            newForward = Vector3.Slerp(currentForward, targetDirection, Time.deltaTime * RotationSpeed.Value); //where i changed desiredForward to currentForward

angle = Vector3.Angle(currentForward, newForward);
            maxAngle = MaxDegreesPerSecond.Value * Time.deltaTime;
            if (angle > maxAngle)
            {
newForward = Vector3.Slerp(currentForward, newForward, maxAngle / angle);
            }

            go.transform.forward = newForward;

            // debug line to target

            if (debug.Value)
            {
                Debug.DrawLine(go.transform.position, lookAtPos, Color.grey);
            }

            // send finish event?

            if (finishEvent != null)
            {
                var targetDir = lookAtPos - go.transform.position;
                angle = Vector3.Angle(targetDir, go.transform.forward);

                if (Mathf.Abs(angle) <= finishTolerance.Value)
                {
                    Fsm.Event(finishEvent);
                }
            }
        }

    }
}

desiredForward had no value and i changed it to currentForward where newForward gets it value which fixed that the Turret ignored the maxRotation. And then when i use a GameObject it does not update the position (it seems to look at the world 0,0,0 coordinates not even nearly to the position where my LookToObject is in the first place) while the Vector3 "target Position" seems to be halved so it rotates forward when i move my LookToObject exact behind the Turret but seems more accurate than the GameObject test :o

but nontheless Thank You because the Camara Jittery is gone!!  :)
« Last Edit: August 09, 2017, 01:53:27 PM by Stuard »

Stuard

  • Playmaker Newbie
  • *
  • Posts: 15
Re: Maximum degrees for a smooth look at like script?[SOLVED]
« Reply #3 on: August 10, 2017, 07:38:43 PM »
Alllllllllllllllllllllllright,
i removed the targetObject part of the function and now it works with the Vector3 targetPosition only :)
the Vector3 is still used as an offset even when there is no Object set in the first place but now it behaves like i want it to be so far.
Thank you djaydino for your work and i will post the function when everything runns bugless!!  ;D

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7614
    • jinxtergames
Re: Maximum degrees for a smooth look at like script?[SOLVED]
« Reply #4 on: August 10, 2017, 07:56:50 PM »
Hi,
The TargetObject is optional you can leave it in.
If you don't place an object inside and you place a target position it will use that.

Other people might need to use an object :)

thanks for debugging.

i will rename and add it to the Ecosystem when it is ready   ;D

Stuard

  • Playmaker Newbie
  • *
  • Posts: 15
Re: Maximum degrees for a smooth look at like script?[SOLVED]
« Reply #5 on: August 18, 2017, 07:53:38 PM »
Hey djaydino,
sorry i was quite buisy buttt i had the time to debug at least the version without the gameobject which works quite nice so far with my setup. Get a "collider"s world position as vector3 and set it as the target, add rotation speed and the max rotation value and voila my turret (or my desired object) looks at it. I cant get my head around the normal Turret_XRotation action because even without a gameobject as target i have an offset (or im just silly) >:(  but SLAMaximumDegrees is cleaned up and works  :)
This with a combination of clamping to the gunbarrel gets me a nice and realistic turret  ;D

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7614
    • jinxtergames
Re: Maximum degrees for a smooth look at like script?[SOLVED]
« Reply #6 on: August 18, 2017, 11:41:09 PM »
Hi,
indeed i noticed that also and the strange thing it seems like it is not always the same.

i will SLAMaximumDegrees later, i can maybe add it to the ecosystem


Btw. there are a bunch of new actions jean made on the ecosystem to Damp values
they might be useful :)


Stuard

  • Playmaker Newbie
  • *
  • Posts: 15
Re: Maximum degrees for a smooth look at like script?[SOLVED]
« Reply #7 on: August 19, 2017, 09:20:48 AM »
Aaright, i'll look into that and Keep up the nice work ;)