Search Unity

Limit movement to portion of .RotateAround()'s path, w/ Input.gyro.attitude.x to control game piece?

Discussion in 'Scripting' started by BerniceChua, Jun 26, 2017.

  1. BerniceChua

    BerniceChua

    Joined:
    Nov 30, 2016
    Posts:
    32
    Hello everyone,

    If this is posted in the wrong place, I apologize in advance and please feel free to move it to the correct section.

    I am posting the question here as a last resort. I've been trying to solve this for almost 2 weeks already. I tried Googling how to solve this problem before, and I tried all the suggested solutions but none of the results were relevant to what I want to do. Either that, or there are 2 possibilities here: I am using the wrong keywords to search, or the methods/functions don't do what I need them to do so I am supposed to use something else.

    Basically, I made a game on an Android phone where the speed of the transform of the game piece is controlled by
    Code (CSharp):
    1. Input.gyro.attitude.x
    I am using
    Code (CSharp):
    1. transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards + GetSpeed());
    to determine the path of the game piece's orbit around the camera.
    Wherein
    Code (CSharp):
    1. -m_slideBackwards
    is the movement that will always happen no matter what, and
    Code (csharp):
    1. GetSpeed()
    is the opposing movement where the speed comes from, through
    Code (csharp):
    1. Input.gyro.attitude.x
    .
    But I want to limit the movement to only a portion of the orbit. Please see the diagram below, in case I am using the wrong words to explain. The diagram might be clearer in explaining what I want. The code is posted below the diagram.
    diagram.png
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Orbit : MonoBehaviour {
    7.  
    8.     public Transform target;
    9.  
    10.     [SerializeField] float m_speedMultiplier = 2.0f;
    11.     [SerializeField] float m_slideBackwards = 1.0f;
    12.     [SerializeField]  Camera m_camera;
    13.  
    14.     Vector3 m_screenPosition;
    15.     float m_previousGyroValue = 0;
    16.     float m_currentGyroValue = 0;
    17.  
    18.     float m_thrust = 5.0f;
    19.     Rigidbody m_rigidbody { get { return GetComponent<Rigidbody>(); } set { m_rigidbody = value; } }
    20.  
    21.     [SerializeField] float m_angularSpeed;
    22.     [SerializeField] float m_targetRotationalAngle = 90;
    23.     float m_currentRotationalAngle = 0; // degrees
    24.     Vector3 m_rotationAxis;
    25.  
    26.     // Use this for initialization
    27.     void Start() {
    28.  
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void FixedUpdate() {
    33.         m_screenPosition = m_camera.WorldToViewportPoint(this.transform.position);
    34.         //speed = GetSpeed();
    35.  
    36.         //transform.RotateAround(target.position, target.up, speed * Time.deltaTime);
    37.  
    38.         if (this.enabled) {
    39.             //float speedOfGamePiece = GetSpeed();
    40.  
    41.             Vector3 targetDir = target.position - transform.position;
    42.  
    43.             float angle = Vector3.Angle(targetDir, transform.forward);
    44.  
    45.             //m_currentGyroValue = (Input.gyro.attitude.x - m_previousGyroValue) * 100;
    46.  
    47.             //if (m_screenPosition.x < 1.0f) {
    48.             //if (angle <= 45 && angle >= -45) {
    49.             //transform.RotateAround(target.position, target.up, speedOfGamePiece);
    50.             //transform.RotateAround(target.position, Vector3.up, -m_slideBackwards + speedOfGamePiece);
    51.             //transform.RotateAround(target.position, Vector3.right, -m_slideBackwards + speedOfGamePiece);
    52.  
    53.             //transform.RotateAround(m_camera.transform.position, Vector3.up, ClampMovements());
    54.  
    55.             //}
    56.  
    57.             //Waiting(1);
    58.             //m_previousGyroValue = Input.gyro.attitude.x * 100;
    59.  
    60.             //if (m_screenPosition.x > 1.1f) {
    61.             //    transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards * 3.0f);
    62.             //} else if (m_screenPosition.x < 1.1f && m_screenPosition.x > 0.9f) {
    63.             //    //transform.RotateAround(m_camera.transform.position, Vector3.up, Mathf.Lerp());
    64.             //} else {
    65.             //    transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards + GetSpeed());
    66.             //}
    67.  
    68.             //float targette = 110.0f;
    69.             //float moveTowardsThisAngle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, targette, GetSpeed());
    70.             //transform.eulerAngles = new Vector3(0, moveTowardsThisAngle, 0);
    71.             //transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards + GetSpeed());
    72.  
    73.             //float deltaAngle = m_angularSpeed * Time.deltaTime;
    74.             //float deltaAngle = GetSpeed()/* * Time.deltaTime*/;
    75.             //if (m_currentRotationalAngle + deltaAngle > m_targetRotationalAngle) {
    76.             //    deltaAngle = m_targetRotationalAngle - m_currentRotationalAngle;
    77.             //    enabled = false;
    78.             //}
    79.             //transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards + deltaAngle);
    80.  
    81.             if (m_screenPosition.x > 1.1f) {
    82.                 transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards * 3.0f);
    83.             } else if (m_screenPosition.x < 1.1f && m_screenPosition.x > 0.9f) {
    84.                 while (m_screenPosition.x > 0.6f) {
    85.                     transform.RotateAround(m_camera.transform.position, Vector3.up, Mathf.Lerp(m_screenPosition.x, m_screenPosition.x - 0.7f, 0.01f));
    86.                     Waiting(1);
    87.                 }
    88.                 //Mathf.Lerp(m_screenPosition.x, m_screenPosition.x - 0.7f, 0.01f);
    89.             } else {
    90.                 transform.RotateAround(m_camera.transform.position, Vector3.up, -m_slideBackwards + GetSpeed());
    91.             }
    92.  
    93.         }
    94.     }
    95.  
    96.     public float GetSpeed() {
    97.         //float speed = Mathf.Clamp(Mathf.Abs(Input.gyro.attitude.x) * m_speedMultiplier, 0.0f, 1.5f);
    98.  
    99.         //float speed;
    100.         ////m_previousGyroValue = Input.gyro.attitude.x * 100;
    101.         //Waiting(1);
    102.         ////float currentGyroValue = (Input.gyro.attitude.x - m_previousGyroValue) * 100;
    103.  
    104.         //if (Mathf.Round(Mathf.Abs(currentGyroValue)) == Mathf.Round(Mathf.Abs(m_previousGyroValue)))
    105.         //    speed = 0;
    106.         //else
    107.         //    speed = 1;
    108.  
    109.         float speed;
    110.         //float currentGyroValue = Mathf.Lerp(m_previousGyroValue, Input.gyro.attitude.x, 0.2f) * 100;
    111.         m_currentGyroValue = Mathf.Lerp(m_currentGyroValue, Input.gyro.attitude.x, 0.75f) * 100;
    112.         m_previousGyroValue = Input.gyro.attitude.x * 100;
    113.         //Waiting(1);
    114.  
    115.         if (Mathf.Round(Mathf.Abs(m_currentGyroValue)) - Mathf.Round(Mathf.Abs(m_previousGyroValue)) == 0)
    116.             speed = 0;
    117.         else
    118.             speed = Mathf.Abs(m_currentGyroValue - m_previousGyroValue);
    119.  
    120.         return speed;
    121.     }
    122.  
    123.     public float ClampMovements() {
    124.         //return Mathf.Clamp(m_screenPosition.x, 0.0f, 1.1f);
    125.  
    126.         if (m_screenPosition.x > 1.1f) {
    127.             return -m_slideBackwards * 3.0f;
    128.         } else if (m_screenPosition.x < 1.1f && m_screenPosition.x > 0.9f) {
    129.             return -m_slideBackwards * 2.0f;
    130.             //return m_rigidbody.AddForce(-transform.forward * m_thrust);
    131.         } else {
    132.             return -m_slideBackwards + GetSpeed();
    133.         }
    134.  
    135.         //if (m_screenPosition.x >= 1.1f) {
    136.         //    return -m_slideBackwards * 2.0f;
    137.         //} else {
    138.         //    return -m_slideBackwards + GetSpeed();
    139.         //}
    140.     }
    141.  
    142.     IEnumerator Waiting(float time) {
    143.         yield return new WaitForSeconds(time);
    144.     }
    145. }
    146.  
    As you can see with the commented-out words, I tried those things already, but they didn't work. Previously, I tried Mathf.Clamp(...) also. I have a feeling that it's because in those other examples that I found in Google, they are using keyboard & mouse/controller as the input instead of a mobile phone's gyroscope. Or maybe I'm doing something wrong.

    In all those versions, the little game piece gets stuck on the right side of the screen. (I don't really care about the left side of the screen because if the game piece goes there, it reaches the game over state that's handled by another class/component on the game object.)

    Other things I've tried:
    Unless I'm using this wrong, https://docs.unity3d.com/ScriptReference/Mathf.MoveTowardsAngle.html did not work for me. It doesn't move the game piece along the orbit. It merely spins the game object.

    When I used Mathf.Clamp(), when the game piece reaches the right side of the screen, it just stays stuck there and doesn't move anymore. Using Mathf.Clamp was actually the first solution that I thought of. I learned that in the space shooter tutorial. It seems that the reason that it's different is because I'm not using keyboard-&-mouse/controller/touchscreen as my input, but I'm using Input.gyro.attitude.x. In the space shooter tutorial, it is also different because it is clamping the transform.position based on the game's world space. The game that I'm making is in AR, though, so a lot of the things don't apply.

    In this latest iteration, I thought of using
    Code (CSharp):
    1. .WorldToViewportPoint(...)
    to find out where the edges of the screen are, and to use the transform.position of the game piece (determined through if-else statements) to change the behavior of the movements.

    The problem with all of those is that I've tried is that the same, the game piece gets stuck on the right side of the screen once it reaches there. I may be wrong, but think what is happening is that the backwards movements are conflicting with the forwards movement of GetSpeed().

    So maybe I should be using a different way? What are good ways to limit the section of a circle that is an allowed movable path of a game object that uses transform.RotateAround()?

    I am also open to suggestions if there is a better way to program the game piece's path other than .RotateAround().

    If something is unclear, you are more than welcome to ask me to clarify it.

    Thanks in advance. I really appreciate any help, since I've been stuck at this for so long.
     
    Last edited: Jun 28, 2017
  2. BerniceChua

    BerniceChua

    Joined:
    Nov 30, 2016
    Posts:
    32
    Update: I found this thing called Vector3.RotateTowards() (https://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html)!

    I tried this one out, but unfortunately it does not make the game piece orbit around the camera. What it does is it spins the game piece so that its front will face the thing that is assigned as the target, in this case, the camera.