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

Need help with 2D Physics and Rotation

Discussion in 'Scripting' started by Omni_Owl, Mar 18, 2016.

  1. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    I'm learning Unity 5 at the moment, pretty much a beginner. I have a bachelor in Computer Science and have worked with other engines previously.

    So in this project of mine, I have this mechanic that when you click on the screen I apply force there and then the 2D Bodies in that area will have physics applied to them, as if it was an explosion. Currently I'm just working on the Physics part of it before adding the shine.

    But I have a bit of trouble executing this right. Below is a gif of what happens:



    As you can see, it doesn't matter where I click, the Force is applied exactly the same every time (direction and all) and the body that I am applying it to (The Yellow Rectangle) does not even have it's rotation modified by this adding of force (but that is probably because I don't understand how to do this quite right).

    Below is my script that takes care of the interaction:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GameController : MonoBehaviour
    5. {
    6.     public float SonicBombRange;
    7.     public float SonicBombForceX, SonicBombForceY;
    8.  
    9.     private bool IsInMenu;
    10.  
    11.     void Start()
    12.     {
    13.         IsInMenu = false;
    14.     }
    15.  
    16.     void Update()
    17.     {
    18.         if (Input.GetMouseButtonDown(0) && !IsInMenu)
    19.         {
    20.             OnPointerClick();
    21.         }
    22.     }
    23.  
    24.     public void OnPointerClick()
    25.     {
    26.         RaycastHit2D[] hits = Physics2D.CircleCastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), 10.0f, Vector2.zero, SonicBombRange);
    27.         foreach (RaycastHit2D hit in hits)
    28.         {
    29.             if (hit.collider != null)
    30.             {
    31.                 if (hit.rigidbody != null)
    32.                 {
    33.                     //hit.rigidbody.AddRelativeForce(new Vector2(SonicBombForceX, SonicBombForceY));
    34.                     hit.rigidbody.AddForce(new Vector2(SonicBombForceX,SonicBombForceY));
    35.                     //hit.rigidbody.AddForceAtPosition(new Vector2(SonicBombForceX, SonicBombForceY), hit.transform.position);
    36.                 }
    37.             }
    38.         }
    39.     }
    40.  
    41.     public void SetIsInMenu(bool newState)
    42.     {
    43.         IsInMenu = newState;
    44.     }
    45. }
    I need help with making this explosion believable. Adding more, realistic force to the object. So that those objects will have force applied not just to the rigid body component, but also rotation and finally that the force added is relative to how close the object is to the core of the explosion.
     
    Last edited: Mar 18, 2016
  2. Austin-Gregory

    Austin-Gregory

    Joined:
    Sep 19, 2013
    Posts:
    78
    You're just applying the force to the rigidbody. You're not doing anything else so the result should be expected. In order to apply a force relative to where you clicked, you'll need to calculate a direction vector. You'll need the direction between your click point and the cube. Maybe distance as well to modify the force amount.

    If you don't understand how to do this, what I said probably makes no sense. Check out this entry in the manual:
    Direction and Distance From One Object to Another
     
  3. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    Yeah I had the feeling I needed to do something like that as well. I'll give it a look, thanks.
     
  4. Omni_Owl

    Omni_Owl

    Joined:
    Nov 26, 2013
    Posts:
    176
    Well that did something at least. I tinkered around a bit with what was provided on that page and here is the result of that:

    https://gfycat.com/DentalElatedDesertpupfish

    The very first one is what I'd like to have as it's very controlled and soft. But I am not sure how to balance that properly so my click is...not as disruptive hah. Below is my current code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.SceneManagement;
    4.  
    5. public class GameController : MonoBehaviour
    6. {
    7.     public float SonicBombRange;
    8.     public float SonicBombForceX, SonicBombForceY;
    9.  
    10.     private bool IsInMenu;
    11.  
    12.     void Start()
    13.     {
    14.         IsInMenu = false;
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         if (Input.GetMouseButtonDown(0) && !IsInMenu)
    20.         {
    21.             OnPointerClick();
    22.         }
    23.  
    24.         if(Input.GetKeyDown(KeyCode.R))
    25.         {
    26.             SceneManager.LoadScene("main");
    27.         }
    28.     }
    29.  
    30.     public void OnPointerClick()
    31.     {
    32.         Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    33.         RaycastHit2D[] hits = Physics2D.CircleCastAll(mousePosition, 10.0f, Vector2.zero, SonicBombRange);
    34.         foreach (RaycastHit2D hit in hits)
    35.         {
    36.             if (hit.collider != null)
    37.             {
    38.                 if (hit.rigidbody != null)
    39.                 {
    40.                     Vector2 heading = new Vector2(hit.transform.position.x,hit.transform.position.y) - mousePosition;
    41.                     float distance = heading.magnitude;
    42.                     Vector2 direction = heading / distance;
    43.                     hit.rigidbody.AddForceAtPosition((direction * SonicBombForceX), hit.point, ForceMode2D.Force);
    44.                 }
    45.             }
    46.         }
    47.     }
    48.  
    49.     public void SetIsInMenu(bool newState)
    50.     {
    51.         IsInMenu = newState;
    52.     }
    53. }
    I figured out that with this setup I just need one float for the force that I multiply the Direction with. But the value that I set it to in the GIF above is 425.