There is a texture, runs in a certain radius, knocking on the walls - gets a new direction.

Vector2 dir; void Start() { InvokeRepeating("Move", 1 / 24f, 1 / 24f); dir = Vector2.right; } void Update() { } void Move() { transform.Translate(dir); } void OnTriggerEnter2D(Collider2D coll) { if (coll.name.StartsWith("bright")) { dir = -Vector2.right; } if (coll.name.StartsWith("bleft")) { dir = Vector2.right; } if (coll.name.StartsWith("btop")) { dir = Vector2.down; } } 

I want the texture to run not (up \ bottom \ left \ right) but at a certain angle I tried it

 dir = Vector(0, 1); 

But emphasizes red. How can we turn on 45 *?

And the corresponding question - how to turn at a random angle? On random, except let's say, 0?

  • Just turn? Or that the movement was in the random direction? You do an arcane game?) - Aleksey Shimansky
  • @ Alexey Shimansky So that after hitting the wall it flew to the other random side, but not through the wall (i.e. not full random but with exceptions) And the rotation of the texture is also of interest, so that there is a transform to the same degrees as it flies away. I make Tipo Arkanoid, but it's easier, while I study Unity. - Dmitrii

1 answer 1

1) Construction of the form dir = Vector(0, 1); does not work because you need to write Vector2/Vector3 , and not just Vector . And since you do not access the property like here

 Vector2.down; 

it means that you need to refer to the class instance need to write

 dir = new Vector2(0, 1); 

2) Even if you write new Vector2(0, 1) in theory, it should fly strictly upwards, but not at an angle. To do this, you need to either rotate the object or specify new Vector2(1, 1) , i.e. fly up and to the right, i.e. at an angle

3) When bouncing off the sides at the same angle, it’s enough to remember that when one reaches one side, the speed changes to the opposite (without taking into account friction forces, rebound forces and so on). A la the angle of incidence equals the angle of reflection. So, when reaching the right or left side (i.e., the X axis), it is enough to change the direction of the movement to the opposite for the given axis: X = -X; . And since he (object) vertically, so will move in a given direction, you get a rebound angle. With a vertical rebound, everything is exactly the same.

From the above follows:

 Vector2 dir; Transform myTransform; public float vx = 1f; public float vy = 1f; public float speed = 1f; void Start() { //InvokeRepeating("Move", 0.07f, 0.07f); myTransform =transform; dir = new Vector2(vx, vy); } void Update() { myTransform.Translate(dir * speed * Time.deltaTime); } // void Move() { transform.Translate(dir * speed * Time.deltaTime); } void OnCollisionEnter2D(Collision2D coll) { if (coll.gameObject.name.StartsWith("bright") || coll.gameObject.name.StartsWith("bleft")) { vx = -vx; } if (coll.gameObject.name.StartsWith("btop") || coll.gameObject.name.StartsWith("bbottom")) { vy = -vy; } dir = new Vector2(vx, vy); } 

4) About the randomness. You can use two things.

For example instead

 vx = -vx; 

can write

 var sign = Mathf.Sign(vx); var random = Random.Range(1f, 2f); vx = random * sign * -1; 

vx will take a value in the range from 1 to 2. sign - you need it here to set the correct value of vx , because we don’t know at this time that it has a value: positive or negative. And so we take a sign, we generate a number, we assign it with the opposite sign.

5) Regarding the angles of rotation, Unity has many different options and it is easier to deduct everything yourself. Someone makes different X and Y parameters and as a result, an angle is reached, someone uses transform.localRotation , someone uses the transform.Rotate () method. There is even an example:

  public class FollowPath: MonoBehaviour { public float speed; public float rotationSpeed; //transform Transform myTrans; //object position Vector3 myPos; //object rotation Vector3 myRot; //object rotation float angle; // Use this for initialization void Start() { myTrans = transform; myPos = myTrans.position; myRot = myTrans.rotation.eulerAngles; } // Update is called once per frame void FixedUpdate() { //converting the object euler angle's magnitude from to Radians angle = myTrans.eulerAngles.magnitude * Mathf.Deg2Rad; //rotate object Right & Left if (Input.GetKey(KeyCode.RightArrow)) { myRot.z -= rotationSpeed; } if (Input.GetKey(KeyCode.LeftArrow)) { myRot.z += rotationSpeed; } //move object Forward & Backward if (Input.GetKey(KeyCode.UpArrow)) { myPos.x += (Mathf.Cos(angle) * speed) * Time.deltaTime; myPos.y += (Mathf.Sin(angle) * speed) * Time.deltaTime; } if (Input.GetKey(KeyCode.DownArrow)) { myPos.x += Mathf.Cos(angle) * Time.deltaTime; myPos.y += Mathf.Sin(angle) * Time.deltaTime; } //Apply myTrans.position = myPos; myTrans.rotation = Quaternion.Euler(myRot); } } 

Where the movement itself is built on the calculation of the angle and substitution in the transform.position

  myPos.x += (Mathf.Cos (angle) * speed) * Time.deltaTime; myPos.y += (Mathf.Sin (angle) * speed) * Time.deltaTime; 

For your example, you can try something like this:

 private Vector2 dir; private Transform myTransform; public float speed; public float angle; public float vx = 1; public float vy = 1; void Start() { myTransform = transform; InvokeRepeating("Move", 0.05f, 0.05f); dir = Vector2.right; angle = Vector2.Angle(Vector2.right, new Vector2(vx, vy)); myTransform.localRotation = Quaternion.Euler(0, 0, angle); } void Move() { myTransform.Translate(dir * speed * Time.deltaTime); } void OnCollisionEnter2D(Collision2D coll) { if (coll.gameObject.name.StartsWith ("bright") || coll.gameObject.name.StartsWith("bleft")) { vx = -vx; } if (coll.gameObject.name.StartsWith ("btop") || coll.gameObject.name.StartsWith("bbottom")) { vy = -vy; } angle = Vector2.Angle(Vector2.right, new Vector2(vx, vy)); if (coll.gameObject.name.StartsWith ("bleft") && vy < 0 || coll.gameObject.name.StartsWith ("bright") && vy < 0 || coll.gameObject.name.StartsWith("btop")) { angle = -angle; } myTransform.localRotation = Quaternion.Euler(0, 0, angle); } 

enter image description here

But it is better to read more about the rotation and how to optimize them and apply to yourself.

  • Thank you, everything is clear. When you try to run your code, the object moves very very slowly, and editing the speed variable gives nothing. But, if you replace Time.deltatime with that 0.5f (speed is also 1f at the same time, although even at 500f nothing changes), then the speed will become normal. Why at all Time.deltatime? I understand that this is the time between frames, but why is it here? - Dmitrii
  • one
    @Dmitrii Depends on object size and scale. for my scale, everything is fine. So here you have to play ... maybe something else is a problem ........ deltaTime is the time it took for the last frame to pass. It should be used only to determine the value in one frame that needs to be changed, for example, to smoothly move the object. If you do not do this, then depending on the performance of the computer or other device, someone will move quickly, someone will slowly ... Therefore, at least for the movement, it must be present. - Alexey Shimansky
  • Thanks again! But the question is - sometimes when you turn the direction of the cursor does not coincide with the right one. And sometimes - the same. Could this be due to a minus value between Vector2.right; and new Vector2 (vx, vy). And how to treat it. - Dmitrii
  • one
    Frankly speaking, @Dmitrii did not understand what the cursor was. X axis of the object? Well, it seems logical that if an object rotates, then its direction rotates with it. This is how to draw a coordinate system on a piece of paper and rotate the piece. All arrows will also begin to shift. Or you look ahead, and if you do a roll, you will be a quick movement of the picture. During the tumbling, the eyes will not constantly see the picture, as before in the standing position)) .... But the global coordinate system remains unchanged. In this case, the window Unity - Alexey Shimansky
  • 2
    @Dmitrii Well, except to do this: create a GameObject empty. Hang a controller on it. And this object will make a child another object, which will have SpriteRender() and other attributes of the sprite (as they do in character management games SpriteRender() is SpriteRender() a wrapper object). Here is just how the code will look like right off the bat. - Alexey Shimansky