Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Moving Position Overrides RotateAround() ?

Discussion in 'Scripting' started by attikitten, Jul 24, 2023.

  1. attikitten

    attikitten

    Joined:
    Jul 23, 2018
    Posts:
    4
    When I use these together at the same time, the position overwrites the rotation from happening and the objects stand still statically.

    They both work separately as intended but when combining them, the rotation stops working.
    This shows that what each line does, rotates or moves it.


    It should rotate in a circle while moving towards the center or away from the center at the same time.

    Code (CSharp):
    1.  
    2. /* Rotate */
    3. BodyParts[i].transform.RotateAround
    4. (playerObject.transform.position, rotation, speed * Time.deltaTime);
    5.  
    6. /* Move */
    7. BodyParts[i].transform.position += moveDirection * currentSpeed * Time.deltaTime;
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,718
    Don't use RotateAround. Just make these objects children of a central empty pivot object and rotate it. RotateAround is going to accumulate error over time which will become significant eventually.
    So:
    • for rotation, simply rotate the parent.
    • For the in and out motion, simply change the object's local positon.
     
    Last edited: Jul 24, 2023
    Bunny83 likes this.
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    They don't override but you do have to keep updating the moveDirection as the direction of the center constantly changes. Although from the video I'm guessing that your moveDirection or currentSpeed is set to zero before the rotating starts.

    You should show the full Update().
     
    Last edited: Jul 24, 2023
    Bunny83 likes this.
  4. attikitten

    attikitten

    Joined:
    Jul 23, 2018
    Posts:
    4
    Spawn is just invisible marker points around the circle where the objects should move depending on radius.


    Code (CSharp):
    1.   private void CircleAround()
    2.     {
    3.         for (int i = 0; i < BodyParts.Count; i++)
    4.         {
    5.             /* Distance around the circle */
    6.             var radians = 2 * Mathf.PI / BodyParts.Count * i;
    7.  
    8.             /* Get the vector direction */
    9.             var vertical = Mathf.Sin(radians);
    10.             var horizontal = Mathf.Cos(radians);
    11.  
    12.             var spawnDir = new Vector3(horizontal, 0, vertical);
    13.  
    14.             /* Get the spawn position */
    15.             var spawnPos = playerObject.transform.position + spawnDir * circleRadius; // Radius is just the distance away from the point
    16.  
    17.             Vector3 moveDirection = spawnPos - BodyParts[i].transform.position;
    18.  
    19.             /* Rotate */
    20.             BodyParts[i].transform.RotateAround(playerObject.transform.position, rotation, speed * Time.deltaTime);
    21.  
    22.             /* Move */
    23.             BodyParts[i].transform.position += moveDirection * lerpSpeedCircle * Time.deltaTime;
    24.  
    25.             /* Rotate the objects to face towards player */
    26.             BodyParts[i].transform.LookAt(playerObject.transform.position);
    27.         }
    28.     }
     
    Last edited: Jul 24, 2023
  5. attikitten

    attikitten

    Joined:
    Jul 23, 2018
    Posts:
    4
    Added the empty parent and it rotates fine but it still doesn't mix well with the movement code.
     
  6. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Your script looks a little overly complicated for what it seems to be trying to do.

    Create a new scene and add the script below to a sphere. It may give you some ideas on how to simplify things.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class RotateAround : MonoBehaviour
    6. {
    7.     public GameObject playerObject;
    8.     public List<GameObject> BodyParts=new List<GameObject>();
    9.     float lerpSpeedCircle=2; // positive value for move inwards, negative for outwards
    10.     float speed=100;
    11.  
    12.     void Start()
    13.     {
    14.         playerObject=this.gameObject;
    15.         int count=8;
    16.         int radius=10;
    17.         Vector3 offset=Vector3.forward*radius;
    18.         for (int i=0;i<count;i++)
    19.         {
    20.             GameObject obj=GameObject.CreatePrimitive(PrimitiveType.Cube);
    21.             obj.transform.position=playerObject.transform.position+offset;
    22.             obj.transform.LookAt(playerObject.transform.position);
    23.             offset=Quaternion.Euler(0,360/count,0)*offset;
    24.             BodyParts.Add(obj);
    25.         }
    26.     }
    27.  
    28.     void Update()
    29.     {
    30.         CircleAround();
    31.     }
    32.  
    33.     private void CircleAround()
    34.     {
    35.         for (int i = 0; i < BodyParts.Count; i++)
    36.         {
    37.             /* Rotate */
    38.             BodyParts[i].transform.RotateAround(playerObject.transform.position, Vector3.up, speed * Time.deltaTime);
    39.  
    40.             /* Move */
    41.             Vector3 moveDirection = (playerObject.transform.position - BodyParts[i].transform.position).normalized;
    42.             BodyParts[i].transform.position += moveDirection * lerpSpeedCircle * Time.deltaTime;
    43.         }
    44.     }
    45.  
    46. }
     
    Bunny83 likes this.
  7. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,718
    It will if you use localPosition.
     
    Bunny83 likes this.