Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question Moving an object in circular orbit

Discussion in 'Scripting' started by S4MA3L, Jul 5, 2020.

  1. S4MA3L

    S4MA3L

    Joined:
    Apr 17, 2020
    Posts:
    38
    Hi, I've been having some trouble with moving my character in a circular path. I have already created a gravity script with newtonian physics equations. But it is not a good idea when the player hits the surface. So I was wondering if I can make the player walk on a circular path around my GameObject which is a planet. I saw a video tutorial on how to move an object around in a circular path here

    But I'm not sure how to implement this to my player character who uses a joystick for movement.
     
  2. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Here's a simple sprite (character) controller that rotates around another target sprite driven by player input. Simply attach the controller to your player sprite and assign the sprite the player should rotate around. You can integrate this code into your own controller, its only an example how to do it. The input of the controller is blocked if the player tries to leave the radius to his target (this is only one way how to handle the player input).

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpriteRotateAroundController : MonoBehaviour
    6. {
    7.     [Tooltip("Assign here the sprite to rotate around.")]
    8.     public Transform RotateAround;
    9.     public float RotationSpeed = 20f;
    10.  
    11.     // Update is called once per frame
    12.     void Update()
    13.     {
    14.         // Read player inputs
    15.         float h = Input.GetAxis("Horizontal");
    16.         float v = Input.GetAxis("Vertical");
    17.         Vector3 directionToTarget = RotateAround.position - transform.position;
    18.         float anglePosition = CalculateAngle(new Vector3(RotateAround.up.x, RotateAround.up.y, 0f), new Vector3(directionToTarget.x, directionToTarget.y, 0f));
    19.  
    20.         // Spin the object around the target
    21.         // Backup the local rotation so the sprite dont rotate around Z
    22.         Quaternion localRot = this.transform.localRotation;
    23.         float playerInput = 0;
    24.         if ((anglePosition <= 180f && anglePosition > 90f)) playerInput = -h + v;
    25.         if ((anglePosition <= 90f && anglePosition >= 0f)) playerInput = h + v;
    26.         if ((anglePosition <= 360f && anglePosition > 270f)) playerInput = h - v;
    27.         if ((anglePosition <= 270f && anglePosition > 180f)) playerInput = -h - v;
    28.  
    29.         playerInput = Mathf.Clamp(playerInput, -1f, 1f);
    30.         this.transform.RotateAround(RotateAround.position, RotateAround.forward, playerInput * RotationSpeed * Time.deltaTime);
    31.  
    32.         // Uncomment this if you only want to drive the player sprite the by horizontal input and comment the 6 lines above
    33.         //this.transform.RotateAround(RotateAround.position, RotateAround.forward, -h * 20f * Time.deltaTime);
    34.         this.transform.localRotation = localRot;
    35.     }
    36.  
    37.     // Calculates the angle between 2 vectors from 0 to 360
    38.     public static float CalculateAngle(Vector3 from, Vector3 to)
    39.     {
    40.         return Quaternion.FromToRotation(from, to).eulerAngles.z;
    41.     }
    42. }
     
    Last edited: Jul 6, 2020
  3. S4MA3L

    S4MA3L

    Joined:
    Apr 17, 2020
    Posts:
    38
    Thanks a lot. I was losing sleep over this.
     
  4. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Here's a even more advanced version because at the transitions the character started to jitter.
    You can decide now if the player should moving clockwise if the direction isnt "clear" by the input.
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. /// <summary>
    7. /// Sprite controller for a circular path by Zer0Cool (forum.unity.com)
    8. /// </summary>
    9.  
    10. public class SpriteRotateAroundController : MonoBehaviour
    11. {
    12.     [Tooltip("Assign here the sprite to rotate around.")]
    13.     public Transform RotateAround;
    14.     public float RotationSpeed = 20f;
    15.  
    16.     [Tooltip("Defines the range where the input will be blocked (in one direction) when the player reaches the maximal radius.")]
    17.     public float deadInputZone = 0.1f;
    18.  
    19.     [Tooltip("Defines if the player should always run clockwise if he reaches the maximal radius.")]
    20.     public bool AlwaysRunClockwise = true;
    21.  
    22.     private Vector3 lastPos;
    23.  
    24.     // Update is called once per frame
    25.     void Update()
    26.     {
    27.         // Read player inputs
    28.         float h = Input.GetAxis("Horizontal");
    29.         float v = Input.GetAxis("Vertical");
    30.         Vector3 directionToTarget = RotateAround.position - transform.position;
    31.         float anglePosition = CalculateAngle(new Vector3(RotateAround.up.x, RotateAround.up.y, 0f), new Vector3(directionToTarget.x, directionToTarget.y, 0f));
    32.  
    33.         // Spin the object around the target
    34.         // Backup the local rotation so the sprite dont rotate around Z
    35.         Quaternion localRot = this.transform.localRotation;
    36.  
    37.         #region advanced control definition
    38.         float playerInput = 0;
    39.  
    40.         if ((anglePosition <= 180f && anglePosition > 90f) || (anglePosition <= 270f && anglePosition > 180f)) h = -h;
    41.         if ((anglePosition <= 360f && anglePosition > 270f) || (anglePosition <= 270f && anglePosition > 180f)) v = -v;
    42.  
    43.         if (anglePosition < (180f + deadInputZone) && anglePosition > (180f - deadInputZone))
    44.         {
    45.             if (!(AlwaysRunClockwise && Mathf.Sign(v) == -1)) v = 0;
    46.         }
    47.  
    48.         if (anglePosition < (90f + deadInputZone) && anglePosition > (90f - deadInputZone))
    49.         {
    50.             if (!(AlwaysRunClockwise && Mathf.Sign(h) == -1)) h = 0;
    51.         }
    52.  
    53.         if (anglePosition < (0f + deadInputZone) || anglePosition > (360f - deadInputZone))
    54.         {
    55.             if (AlwaysRunClockwise)
    56.             {
    57.                 if (Mathf.Sign(Input.GetAxis("Vertical")) == -1) v = 0;
    58.                 else v = -v;
    59.             }
    60.             else v = 0;
    61.         }
    62.  
    63.         if (anglePosition < (270f + deadInputZone) && anglePosition > (270f - deadInputZone))
    64.         {
    65.             if (!(AlwaysRunClockwise && Mathf.Sign(h) == -1)) h = 0;
    66.         }
    67.  
    68.         playerInput = h + v;
    69.  
    70.         playerInput = Mathf.Clamp(playerInput, -1f, 1f);
    71.         this.transform.RotateAround(RotateAround.position, RotateAround.forward, playerInput * RotationSpeed * Time.deltaTime);
    72.         #endregion
    73.  
    74.         // Uncomment this line if you only want to drive the player sprite by the horizontal input and comment out the advanced control code section
    75.         // this.transform.RotateAround(RotateAround.position, RotateAround.forward, -h * RotationSpeed * Time.deltaTime);
    76.         this.transform.localRotation = localRot;
    77.     }
    78.  
    79.     // Calculates the angle between 2 vectors from 0 to 360
    80.     public static float CalculateAngle(Vector3 from, Vector3 to)
    81.     {
    82.         return Quaternion.FromToRotation(from, to).eulerAngles.z;
    83.     }
    84. }
     
    Last edited: Jul 6, 2020
  5. S4MA3L

    S4MA3L

    Joined:
    Apr 17, 2020
    Posts:
    38
    Thank you