Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by polan31 · Sep 20, 2018 at 06:12 PM · 2d gameobjectreflectionbounce

How to bounce one object correctly?

My object is an arrow.

Arrow should bounce off the walls.

After the collision, the object (sprite) must rotate in the direction of movement.

My problem is that sometimes the arrow instead of bouncing, for example, to the left - it bounces to the right, which makes it look very strange.

Does anyone know how to solve this problem?

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class TestFollow : MonoBehaviour {
 
 
 
         public Sprite sprite1; // Drag your first sprite here
         public Sprite sprite2;
         public float moveSpeed = 10f;
         bool mouseClicked = false;
         private SpriteRenderer spriteRenderer;
         bool rightClicked = false;
         private bool canClick = true;
         public float speed;
         public Rigidbody2D rb;
 
         // stored in fixed update, to be used in OnCollisionEnter (which may have an altered value).
         Vector2 currSpeed;
         // Use this for initialization
 
         void Start () 
         {
 
             spriteRenderer = GetComponent<SpriteRenderer>(); // we are accessing the SpriteRenderer that is attached to the Gameobject
             if (spriteRenderer.sprite == null) // if the sprite on spriteRenderer is null then
                 spriteRenderer.sprite = sprite1; // set the sprite to sprite1
 
             rb = GetComponent<Rigidbody2D>();
 
 
         }
     public void Update ()
     {
 
         rb.velocity = currSpeed;
         
         transform.position = Vector2.Lerp (transform.position, Camera.main.ScreenToWorldPoint (Input.mousePosition), moveSpeed);
 
         Vector3 difference = Camera.main.ScreenToWorldPoint (Input.mousePosition) - transform.position;
         difference.Normalize ();
 
 
 
         {
             if (canClick)
             {
                 if (Input.GetMouseButtonDown (0)) {
                     Debug.Log ("Left Mouse Button was pressed");
                     moveSpeed = 0f;
                     if (spriteRenderer.sprite == sprite1) { // if the spriteRenderer sprite = sprite1 then change to sprite2
                         spriteRenderer.sprite = sprite2;
 
                     }
                     mouseClicked = true; //register that the mouse has been clicked and the sprite is changed to sprite2
                     rightClicked = false;                
                     canClick = false;
                 }
             }
 
             if (mouseClicked) {        //checks if sprite has already been changed
                 Vector3 mousePos = Input.mousePosition;        //gets the current mouse position on screen 
                 int currentCase = 0;
                 //following does a case-check on the position of your mouse with respect to the sprite:
                 if (Camera.main.transform.position.x - (Screen.width/2) + mousePos.x < transform.position.x) {        
                     if (Camera.main.transform.position.x - (Screen.height/2)+mousePos.y < transform.position.y) {
                         currentCase = 2;
                     } else {
                         currentCase = 3;
                     }
                 } else {
                     if (Camera.main.transform.position.x - (Screen.height/2)+mousePos.y < transform.position.y) {
                         currentCase = 1;
                     } else {
                         currentCase = 0;
                     }
                 }
                 //create a new rotation:
                 transform.rotation = Quaternion.Euler (0, 0, 90 * currentCase);
             }
             {
 
                 if (Input.GetMouseButton(1)) {
                     Debug.Log ("Pressed secondary button.");
                     rightClicked = true;
                     mouseClicked = false;
 
                 }
                 if(rightClicked)
 
 
                     transform.position += (transform.right + transform.up).normalized *  speed * Time.deltaTime;
 
             }
         }
     }
 
 
         Coroutine changeSpriteRoutine;
         WaitForSeconds wfs = new WaitForSeconds(0.05f);
 
         void OnCollisionEnter2D (Collision2D whatHitMe)
         {
             GameObject g = whatHitMe.gameObject;
             if (g.CompareTag("Background") || g.CompareTag("Enemy"))
             {
                 if(changeSpriteRoutine == null)
                     changeSpriteRoutine = StartCoroutine(ChangeTheDamnSprite());
                 {
 
                     if (g.CompareTag("Background") || g.CompareTag("Enemy"))
                         Debug.Log ("hit");
                     {
 
                         rb.velocity = Vector2.Reflect(currSpeed, whatHitMe.contacts[0].normal);
                         rb.rotation += 90;
 
 
                     }
                 }
             }
         }
 
         IEnumerator ChangeTheDamnSprite() {
             spriteRenderer.sprite = sprite2;
             yield return wfs;
             spriteRenderer.sprite = sprite1;
             changeSpriteRoutine = null;
         }
 
 }

Here is the video

https://gfycat.com/SoupyPointlessAmericanindianhorse
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by Aske_Johansen · Sep 21, 2018 at 02:18 AM

First of all, your script always rotates the arrow 90 degrees counterclockwise(at least i think that counterclockwise is the positive direction). That means that the bounce only works as intended when the left side of the arrow hits the wall. When the right side hits first, it rotates the arrow so that it faces the wall, instead of away from it, which makes it rotate 90 degrees again.


Luckily for you, unity has some great built-in tools for bouncing objects (and physical simulations in general). If you are moving your arrow by adding a force or setting a velocity, you can use a "Physics material 2D" to do all the simulation for you.


Here's a possible solution that you can use. Assuming that you want your arrow to move at a constant speed, you should first of all set the velocity of the arrow to a constant value each update like this:

 void Update () {
     gameobject.getComponent<Rigidbody2D>().velocity = moveSpeed;
 }

This piece of code is run just before each frame, and should be placed just after your Start() method instead of your OnCollisionEnter2D. Now you just have to add a "Physics material 2D" material to your arrow. To create one of these materials, right-click in the asset folder that you want it, and select it under the "create" menu as shown below:


alt text


Now you should have a new material. Select the material, and set the bounciness to whatever you want (0 means no bounce at all, 1 means all force is preserved). I think you want to set it to 1. Also, you should probably set the friction to 0.


alt text


Now it's time to add this material to your arrow. Select your arrow in the inspector, and look at its Rigidbody2D. There you should see a field called "Material" with a little button on the side. Click on the button, and select your newly created material from the menu that just popped up...


(i would add another image here, but i am only allowed two images in each answer. Too bad)


EDIT: You also have to add a 2D collider component to your arrow. You do that by selecting your gameobject, going the the inspector and pressing the "Add component" beneath all the gameobjects components button. Then search for "2d collider" and add the collider that fits your gameobject best. In this case i would recommend the "2d polygon collider". It creates a collider that approximates the sprite of the gameobject.

And Voilà, now your arrow should bounce perfectly off all other colliders (At this point I'm assuming that your wall has a collider component attached).


untitled.png (44.8 kB)
untitled2.png (29.9 kB)
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image polan31 · Sep 21, 2018 at 07:30 PM 1
Share

Thanks for the answer, but unfortunately it does not work :( However, I appreciate the comprehensive answer

avatar image Aske_Johansen polan31 · Sep 21, 2018 at 07:36 PM 0
Share

Actually, now that you mention it, i forgot something. Your arrow has to have a 2d collider attached for it to work (There are many different kinds). You can add one in the inspector by pressing the "Add Component" and searching for "2d collider". You probably want the polygon collider.

avatar image polan31 Aske_Johansen · Sep 21, 2018 at 07:53 PM 0
Share

Hi. Thanks for the answer. $$anonymous$$y object has two colliders. The first one has also added psychic materials 2d with 0-0

I had to do it because otherwise the arrow did not bounce off the wall but was stuck in it (the arrow collider entered the wall collider)

Here you can read about it: http://johnstejskal.com/wp/setting-up-your-characters-2d-colliders-in-unity/ It's something similar :)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

104 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Reflecting Objects off of Boundaries/Walls 2 Answers

Making a pong-like game, and want the ball to reflect according to where on the paddle it hits 1 Answer

How can I get gameObject's all script components? 1 Answer

Balls bounce off wall in different ways 1 Answer

2D pong, bouncer - ball movement, friction, bounciness, speed [screenshot] 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges