Trying to rotate an asteroid

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Asteroid_1 : MonoBehaviour
{
    Rigidbody2D AsteroidRB;
    public float speed = 10f;

    public float degreesPerSec = 360f;

    // Start is called before the first frame update
    void Start()
    {
       AsteroidRB = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        float rotAmount = degreesPerSec * Time.deltaTime;
        float curRot = transform.localRotation.eulerAngles.z;
    
    
        transform.LocalRotation = Quaternion.Euler(new Vector3(0,0,curRot + rotAmount));
        AsteroidRB.velocity =- transform.right * speed;
     
        if (transform.position.magnitude > 1000.0f)
        {
            Destroy(gameObject);

        }
    }
    void OnCollisionEnter2D(Collision2D other)
    {
        Destroy(gameObject);
    }
}

Cant you just change the pivot point to be the center of the asteroid?

1 Like

Thanks but I have the pivot point for asteroid prefab set to centre
The video below shows the problem I am having

https://www.youtube.com/watch?v=T2ix7zyHZ8I

So how is the sprite coming from the Sprite Editor? Is it a good fit? See my image as an example:

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.

6941705--816029--Screenshot (4)_LI.jpg

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

@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 //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 AsteroidRB.velocity =- transform.right * speed;I get the effect to seen in the video

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.

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.

Change what direction the force is being applied:

rb.AddForce(-transform.right * cometSpeed);

Or something like that. Unity - Scripting API: Rigidbody2D.AddForce

Thats what I have But they are moving towards the bottom of the screen

    void Update()
    {

        float rotAmount = degreesPerSec * Time.deltaTime;
        float curRot = transform.localRotation.eulerAngles.z;
        transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));
        AsteroidRB.AddForce(transform.right * -speed);

        if (transform.position.magnitude > 500.0f)
        {
            Destroy(gameObject);

        }
    }

https://www.youtube.com/watch?v=WHNYNAskMhU

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.

void Update()
    {
        float rotAmount = degreesPerSec * Time.deltaTime;
        float curRot = transform.localRotation.eulerAngles.z;
        transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));
        AsteroidRB.AddForce(transform.right * -speed);
        if (transform.position.magnitude > 500.0f)
        {
            Destroy(gameObject);
        }
    }

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.

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.

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.

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.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Asteroid_1 : MonoBehaviour
{
    Rigidbody2D AsteroidRB;
    public float speed;

    // Start is called before the first frame update
    void Start()
    {
       AsteroidRB = GetComponent<Rigidbody2D>();
    }
    // Update is called once per frame
    void Update()
    {
        //AsteroidRB.velocity = -transform.right * speed;
        // AsteroidRB.AddForce( transform.position * -speed);
        //float rotAmount = degreesPerSec * Time.deltaTime;
        //float curRot = transform.localRotation.eulerAngles.z;
        //Debug.Log(rotAmount);
        //transform.rotation = Quaternion.Euler(new Vector3(0, 0, curRot + rotAmount));

    }


    void FixedUpdate()
    {

        AsteroidRB.AddForce(-transform.right * speed);
        AsteroidRB.angularVelocity = 50.0f;
    }
    void OnCollisionEnter2D(Collision2D other)
    {
        Destroy(gameObject);
    }
}

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:

  • Create a new project
  • Create a GameObject
  • Add a Rigidbody2D
  • Add a BoxCollider2D
  • Add a script which sets the AngularVelocity
  • 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.

1 Like

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.

1 Like

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