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

Trying to rotate an asteroid

Discussion in '2D' started by Stew_79, Mar 16, 2021.

Thread Status:
Not open for further replies.
  1. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Hi guys I am trying to rotate an asteroid in a 2d space game that I am making.
    I have an empty gameobject set as the spawn point I then get the screen bounds and take a random number between screen bounds minY and screen bounds maxY and then I instantiate the asteroid prefab.
    This works perfect giving random asteroids along the y axis.

    I then have a script attached to the asteroid prefab to rotate them and move them.
    The problem is that it makes the asteroids spin round in a loop and not at their piviotpoint
    I want the asteroids to travel in a straight line but also to be rotating

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Asteroid_1 : MonoBehaviour
    6. {
    7.     Rigidbody2D AsteroidRB;
    8.     public float speed = 10f;
    9.  
    10.     public float degreesPerSec = 360f;
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.        AsteroidRB = GetComponent<Rigidbody2D>();
    16.     }
    17.  
    18.     // Update is called once per frame
    19.     void Update()
    20.     {
    21.         float rotAmount = degreesPerSec * Time.deltaTime;
    22.         float curRot = transform.localRotation.eulerAngles.z;
    23.    
    24.    
    25.         transform.LocalRotation = Quaternion.Euler(new Vector3(0,0,curRot + rotAmount));
    26.         AsteroidRB.velocity =- transform.right * speed;
    27.      
    28.         if (transform.position.magnitude > 1000.0f)
    29.         {
    30.             Destroy(gameObject);
    31.  
    32.         }
    33.     }
    34.     void OnCollisionEnter2D(Collision2D other)
    35.     {
    36.         Destroy(gameObject);
    37.     }
    38. }
    39.  
     
  2. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    Cant you just change the pivot point to be the center of the asteroid?
     
    Stew_79 likes this.
  3. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Thanks but I have the pivot point for asteroid prefab set to centre
    The video below shows the problem I am having
     
    Last edited: Mar 16, 2021
  4. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    So how is the sprite coming from the Sprite Editor? Is it a good fit? See my image as an example:
    upload_2021-3-16_12-57-4.png
     
  5. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    If you are importing the sprite and not making sure the pivot point is correct and the actual part of the jpg or png file that you want is being processed properly, you can have issues like you are having. If you make sure it is like the left image, it will rotate as you are intending, but if you are doing it in some fashion like the right, it will rotate similar to what you are getting now.
     
  6. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Screenshot (4)_LI.jpg
     
  7. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    Okay, that looks good. Now throw one of your asteroid prefabs into the scene, and just grab the Z rotation and slowly rotate it, does it rotate properly like that? If yes, then it is your code that is causing it to rotate improperly.

    Try something simple like this: transform.eulerAngles = Vector3.forward * speed * Time.deltaTime;

    That should get you a very basic rotation
     
  8. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    @Cornysam I have the pivot point set to the centre. I think my problem is due to me trying to move it after I have added rotation. If I comment out this
    Code (CSharp):
    1.  //AsteroidRB.velocity =- transform.right * speed;
    in the asteroid script, then the asteroids rotate on their pivot point like I want them too. But when I move the asteroids
    Code (CSharp):
    1.  AsteroidRB.velocity =- transform.right * speed;
    I get the effect to seen in the video

     
  9. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    Do you need to use physics for them? Or can you just move them via transform and have a trigger register the impact? If you need physics (bouncing off, slowing down over time, etc.) then i would suggest using Rigidbody2D.AddForce instead of .velocity.
     
  10. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    I have tried rigibody2d.addforce instead of velocity and now they rotate correctly but are now moving towards the bottom of the screen instead of to the left.
     
  11. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
  12. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Thats what I have But they are moving towards the bottom of the screen

    Code (CSharp):
    1.     void Update()
    2.     {
    3.  
    4.         float rotAmount = degreesPerSec * Time.deltaTime;
    5.         float curRot = transform.localRotation.eulerAngles.z;
    6.         transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));
    7.         AsteroidRB.AddForce(transform.right * -speed);
    8.  
    9.         if (transform.position.magnitude > 500.0f)
    10.         {
    11.             Destroy(gameObject);
    12.  
    13.         }
    14.     }
    15.  
     
    Last edited: Mar 16, 2021
  13. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    Sooooo just change the direction then. Try transform.up, try transform.forward or one of the others. If those go the opposite way make it negative.
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Code (CSharp):
    1. void Update()
    2.     {
    3.         float rotAmount = degreesPerSec * Time.deltaTime;
    4.         float curRot = transform.localRotation.eulerAngles.z;
    5.         transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));
    6.         AsteroidRB.AddForce(transform.right * -speed);
    7.         if (transform.position.magnitude > 500.0f)
    8.         {
    9.             Destroy(gameObject);
    10.         }
    11.     }
    12.  
    The problem with the above too is that you're adding a force per-frame so if your frame-rate goes up, it'll result in more force. You're adding forces which will cause accelleration so hopefully you want that. Note that you're correctly updating the position by going through the Rigidbody2D but then you incorrect directly modify the Transform rotation. You can simply set the AsteroidRB.angularVelocity to something and it'll continue to rotate without change.

    Note that physics doesn't run by default per-frame, it runs during the FixedUpdate. If you add a force during a frame, it doesn't mean it's been applied in the next frame. If your frame-rate is 200hz then you'll get 4 frames for every FixedUpdate which by default runs at 50hz.
     
  15. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Okay so if I want to add movement to a gameobject then I should use the rigidbody to do so.
    Also that it should only be done in FixedUpdate()?

    However using the rigidboy2d.AngularVelocity that uyou suggested still produces the same effect as everything else that I have tried.
    The asteroids rotate correctly but move round in a kind of loop.
    I want the asteroids to continually rotate but only move along the X axis. i.e travel in a straight line from the right hand side of the screen to the left hand.
    I even tried making an empty and adding the asteroid prefab as a child. I then put a script on the empty to make it move along the x axis. Then I put a script on the asteroid prefab to rotate it. But this doesn't work either.
    The empty move like expected but failed to move the child with it.
    I think the real problem here is that because I am rotating the asteroid I am also rotating the direction that I want it to move along on.
     
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    That's a rendering thing though, nothing to do with rotating a Rigidbody2D. You can see the angle rotating in the Z axis so that part will be working. This is the correct thing to do. Sort out the rendering offset problem separately.

    You should see the collider (whatever you're using) is rotating correctly with the Rigidbody2D though. You can also go into the Inspector and the Rigidbody2D > Info > World Center Of Mass. This is the point the body rotates.
     
  17. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Hi @MelvMay
    I don't see how its a rendering problem?
    Also I looked at the collider in inspector but I don't see anything about centre of mass.
    I am new to this and I am just trying to learn.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Asteroid_1 : MonoBehaviour
    6. {
    7.     Rigidbody2D AsteroidRB;
    8.     public float speed;
    9.  
    10.     // Start is called before the first frame update
    11.     void Start()
    12.     {
    13.        AsteroidRB = GetComponent<Rigidbody2D>();
    14.     }
    15.     // Update is called once per frame
    16.     void Update()
    17.     {
    18.         //AsteroidRB.velocity = -transform.right * speed;
    19.         // AsteroidRB.AddForce( transform.position * -speed);
    20.         //float rotAmount = degreesPerSec * Time.deltaTime;
    21.         //float curRot = transform.localRotation.eulerAngles.z;
    22.         //Debug.Log(rotAmount);
    23.         //transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));
    24.  
    25.     }
    26.  
    27.  
    28.     void FixedUpdate()
    29.     {
    30.  
    31.         AsteroidRB.AddForce(-transform.right * speed);
    32.         AsteroidRB.angularVelocity = 50.0f;
    33.     }
    34.     void OnCollisionEnter2D(Collision2D other)
    35.     {
    36.         Destroy(gameObject);
    37.     }
    38. }
    39.  
     

    Attached Files:

  18. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    There's two things at play:
    • Physics
    • Rendering
    Physics won't causes odd motion for simple rotation so it's some odd offset in the rendering so sprite stuff etc.

    Read what I said again. I said "Rigidbody2D > Info > World Center Of Mass." so Rigidbody2D component.

    Take a step back:
    1. Create a new project
    2. Create a GameObject
    3. Add a Rigidbody2D
    4. Add a BoxCollider2D
    5. Add a script which sets the AngularVelocity
    6. it'll rotate correctly
    Now try this with a single sprite added onto the same GameObject and it should rotate as expected around the center. Now try adding tn the sprites you're using in the other project and see if you get odd motion.
     
    Stew_79 likes this.
  19. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    BTW: There's no need to continuous set the angular velocity. It'll stay the same unless you apply a rotation force to stop it or it collides resulting in a counter force etc.
     
    Stew_79 likes this.
  20. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    I am so confused now.
    I don't have a problem with the sprite rotating
    I have problem trying to make the spite move whilst its rotating
     
  21. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Well set the linear velocity in the test above too. You'll see it makes no difference to how it rotates.
     
  22. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Send me your project and I'll take a quick look for you. Make sure there are simple instructions to reproduce it. If you can't host it then DM me with your email and I'll set-up a workspace for you to upload.
     
  23. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    This is getting too complicated for a simple function.

    Have a parent gameobject named Asteroid. On the parent, add a circle collider2D and a rigidbody2D. Create a child object of that asteroid called Asteroid Graphics and add a sprite renderer. Drag your asteroid sprite to that sprite renderer field and make sure the child gameobject's transform is at 0,0,0.

    Now, create your move asteroid script and put it on the parent, not the child with the graphics. This will use physics to move the parent gameobject. Make sure your Rigidbody2D has a mass of 0 (it will go to 0.0001 since it has to have a mass, that is fine). Set the gravity scale to 0.

    Put this in your MoveAsteroid script:
    Code (CSharp):
    1. private Rigidbody2D rb;
    2.     public float speed;
    3.     public float rotateSpeed;
    4.     public GameObject graphicsObj;
    5.  
    6.     // Use this for initialization
    7.     void Start () {
    8.         rb = GetComponent<Rigidbody2D>();
    9.         rb.AddForce(transform.right * -speed, ForceMode2D.Impulse);
    10.     }
    11.    
    12.     // Update is called once per frame
    13.     void Update () {
    14.         graphicsObj.transform.Rotate(new Vector3(0, 0, 3 * rotateSpeed));
    15.     }
    upload_2021-3-18_9-50-2.png

    This is working perfectly for me. The object moves to the left in a straight line and the graphics rotate on the Z axis.
     
    MelvMay likes this.
  24. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Agreed.

    I think the crux of the problem is that the velocity direction is using Transform.right which is rotated i.e. local-space. Replacing that with Vector2.right is always right (world-space) no matter what the rotation.
     
    Stew_79 likes this.
  25. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Its ok now I have managed to suss it out :)
    As I have said the problem was trying to make the asteroids move after I added rotation

    AsteroidRB.AddForce(- transform.position * speed);


    The line above was causing the rotating asteroids to move towards the bottom of the screen instead of the left hand side.
    So I decided try something else.

    AsteroidRB.AddForce(new Vector2(-1.0f, 0.0f) * speed);


    This Works :)
    Thanks to @Cornysam and @MelvMay I learnt quite a lot from you Guys Cheers;)

     
    MelvMay likes this.
  26. Stew_79

    Stew_79

    Joined:
    Feb 24, 2021
    Posts:
    36
    Now I'm off to learn how to create animation wish me luck lol
     
  27. Cornysam

    Cornysam

    Joined:
    Feb 8, 2018
    Posts:
    1,343
    Cheers mate, glad you figured it out. Yeah, the Vector2 line is what i use at my game at home but i just quickly googled an AddForce function.

    The newer you are, the longer this threads go usually. Hopefully they get shorter and shorter as your knowledge increases.
     
    MelvMay and Stew_79 like this.
  28. blinkoutatime

    blinkoutatime

    Joined:
    Nov 25, 2020
    Posts:
    10
    I dont see why unity has issues with 3d objects being in a 2d space especially in a top down scenario. I have a 3d asteroid prefab which I want to rotate on top of a 2d backdrop. Apparently this isn't possible and 2d sprite animation is required to achieve this, another thing I have to learn... ugh.
     
  29. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Every part of your post is incorrect, and it is a necro-post.

    You can put 3D objects in 2D space all day long.

    In fact, that's how the Camera itself works: it flattens a 3D object into arbitrary 2D space.

    You can stack 3D objects on top of 2D objects all day long. See below.

    How a sprite animation would have anything at all to do with 3D is also just a complete mystery to me.

    Three (3) primary ways that Unity draws / stacks / sorts / layers / overlays stuff:

    https://forum.unity.com/threads/orthographic-camera-rendering-order.1114078/#post-7167037

    In short, as far as the Standard Rendering Pipeline,

    1. The default 3D Renderers draw stuff according to Z depth - distance from camera.

    2. SpriteRenderers draw according to their Sorting Layer and Sorting Depth properties

    3. UI Canvas Renderers draw in linear transform sequence, like a stack of papers

    If you find that you need to mix and match items using these different ways of rendering, and have them appear in ways they are not initially designed for, you need to:

    - identify what you are using
    - search online for the combination of things you are doing and how to to achieve what you want.

    There may be more than one solution to try.

    For instance, you may even use multiple co-located cameras to more-explicitly control apparent draw ordering.

    Additional reading in the official docs:

    https://docs.unity3d.com/Manual/2DSorting.html

    And SortingGroups can also be extremely helpful in certain circumstances:

    https://docs.unity3d.com/Manual/class-SortingGroup.html

    Other rendering pipelines may have other ways of layering (HDRP and URP). Go see the latest docs for details.

    You really should reconsider your defeatist life strategy. It's not serving you well and in fact may be holding you back professionally.

    Imphenzia: How Did I Learn To Make Games:



    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

    Finally, when you have errors, don't post here... just go fix your errors! Here's how:

    Remember: NOBODY here memorizes error codes. That's not a thing. The error code is absolutely the least useful part of the error. It serves no purpose at all. Forget the error code. Put it out of your mind.

    The complete error message contains everything you need to know to fix the error yourself.

    The important parts of the error message are:

    - the description of the error itself (google this; you are NEVER the first one!)
    - the file it occurred in (critical!)
    - the line number and character position (the two numbers in parentheses)
    - also possibly useful is the stack trace (all the lines of text in the lower console window)

    Always start with the FIRST error in the console window, as sometimes that error causes or compounds some or all of the subsequent errors. Often the error will be immediately prior to the indicated line, so make sure to check there as well.

    Look in the documentation. Every API you attempt to use is probably documented somewhere. Are you using it correctly? Are you spelling it correctly?

    All of that information is in the actual error message and you must pay attention to it. Learn how to identify it instantly so you don't have to stop your progress and fiddle around with the forum.

    In the future when you have a problem, start a fresh post.

    How to report your problem productively in the Unity3D forums:

    http://plbm.com/?p=220

    This is the bare minimum of information to report:

    - what you want
    - what you tried
    - what you expected to happen
    - what actually happened, log output, variable values, and especially any errors you see
    - links to documentation you used to cross-check your work (CRITICAL!!!)

    The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven't put effort into finding the documentation, why should we bother putting effort into replying?

    Do not TALK about code without posting it. Do NOT retype code. Copy/paste and post code properly. ONLY post the relevant code, and then refer to it in your discussion. Do NOT post photographs of code.

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/
     
  30. blinkoutatime

    blinkoutatime

    Joined:
    Nov 25, 2020
    Posts:
    10
    I know the difference between 2d and 3d axis when working with game engines and rendering pipelines, also this has nothing to do with a problem of sorting objects, I don't need your input on how I should be feeling when faced with an obstacle and I am the only one who will fix my own errors as there is no one else working on my project, the fact that I couldn't find what I was looking for while searching means I should be able to re-ask a question and not have a troll say its been said before, that is not helpful in any way. I have read documentation after documentation on this and they certainly could use some work in being more comprehensive, but that is another subject I don't feel like getting into because its just my opinion which I'm not going to push. I have been working with unity since its conception and personally know two of its creators although not relevant it gives you an idea that you aren't simply talking to someone who knows less than you. A lot has changed since then and continues to. I'm not making a tutorial so I'm not sure where you feel like I need to know that information. Also, if I want to post a code snipped I will do so how I please and copy and paste as I want, however I want, and always include any relevant information as I see fit. I am sorry you cannot follow laymen's terms, I am not about being all PC when it comes to developing, as that is a more corporate approach and not about learning on a fundamental level. Your post has an arrogance about it, which should be in check before telling others how to post.
     
  31. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    Please don't necro posts, especially just to complain with incorrect statements. Unity doesn't have problems with rotation at all. It's simple to do; use animation, directly modify the Transform or use Physics to do it for you.

    Please create your own thread and detail what your own problem is.

    Thanks.
     
    Kurt-Dekker likes this.
Thread Status:
Not open for further replies.