简体   繁体   中英

Rotate then move object in Random direction in Unity

I am trying to create a script in Unity that when another object touches it, it grabs the object, rotates it in a random direction, and launches it, but I only want to rotate and launch the other object on the z axis.

Here is my script:

public BallController ballController;
private GameObject ball;
private Rigidbody2D ballRb;

 void OnTriggerEnter2D(Collider2D other)
{
    ball = other.gameObject;
    ballRb = ball.GetComponent<Rigidbody2D>();
    ball.transform.position = this.transform.position;
    // Freeze the ball
    ballRb.velocity = Vector2.zero;
    // Rotate the ball
    ball.transform.rotation = Quaternion.Euler(0, 0, Random.Range(0, 360));
    // Start moving the ball again
    ballRb.velocity = ballRb.velocity * ballController.bulletSpeed * Time.deltatime;

}

The other script (The ball) is has a Ridgidbody and is launched by another object into this one, the script gets the ball to rotate how I want to, but it won't get the ball moving again.

The ballController is set in the editor and the bulletSpeed is just an int that I want the ball to travel at (currently set to 6).

When dealing with Rigidbody2D you shouldn't use the transform for setting the rotation but rather use ballRb.rotation .

Later you are using

ballRb.velocity = ballRb.velocity * ballController.bulletSpeed * Time.deltatime;

but right before you have set

ballRb = Vector2.zero;

So the multiplication results in Vector2.zero . Also adding Time.deltaTime (typo btw) in this one-time assignment makes no sense.

Also if you remove this line you are not taking the new rotation into account when assigning a new velocity.

The velocity is in global space. You also can't use eg transform.right as new direction since the transform isn't updated .. the Rigidbody2D is .. so you can use GetRelativeVector in order to set the new local direction after rotating

private void OnTriggerEnter2D(Collider2D ball)
{
    // The assignment of the GameObject
    // was kind of redundant except
    // you need the reference for something else later

    var ballRb = ball.GetComponent<Rigidbody2D>();

    // set position through RigidBody component
    ballRb.position = this.transform.position;

    // Rotate the ball using the Rigidbody component
    // Was the int overload intented here? Returning int values 0-359
    // otherwise rather use the float overload by passing float values as parameters
    ballRb.rotation = Random.Range(0f, 360f);

    // Start moving the ball again
    // with a Vector different to Vector2.zero 
    // depending on your setup e.g.
    ballRb.velocity = ballRb.GetRelativeVector(Vector2.right * ballController.bulletSpeed);
}

little demo

在此处输入图片说明

for the walls btw I used something very similar:

var ballRb = ball.GetComponent<Rigidbody2D>();
var newDirection = Vector2.Reflect(ballRb.velocity, transform.up);
ballRb.rotation = ballRb.rotation + Vector2.SignedAngle(ballRb.velocity, newDirection);
ballRb.velocity = newDirection.normalized * ballController.bulletSpeed;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM