Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Screen To World Point Help

Discussion in 'Scripting' started by FartherGamer, Jan 13, 2022.

  1. FartherGamer

    FartherGamer

    Joined:
    Jan 7, 2022
    Posts:
    5
    Hello All, I'm just going to say I'm very new to scripting so forgive any obvious mistakes I may be making, I’m trying to make a movement system for a ball in a 2d game, the idea is where ever you click the mouse the ball should jump in that direction and I’m using the screen to world point to track the mouse location on click, however that only works when the ball is in its original starting location, for example if the ball went far left on the first click the camera follows but the mouse no longer tracks correctly it will keep jumping to the left regardless of where I click the mouse leading me to believe it’s still tracking from the original screen to world point before the camera moved so no matter where I click on screen it thinks that I'm clicking to the left when in reality I'm clicking the far right on the screen.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BallMovement : MonoBehaviour
    6. {
    7.     public Rigidbody2D sphereRigidbody;
    8.     private float launchForce = 2;
    9.     private float holdDownStartTime;
    10.     public bool isGrounded;
    11.     public Transform groundCheck;
    12.     public LayerMask groundLayer;
    13.    
    14.  
    15.  
    16.     private void Start()
    17.     {
    18.         sphereRigidbody = GetComponent<Rigidbody2D>();
    19.     }
    20.     private void Update()
    21.     {
    22.  
    23.        Vector2 target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    24.  
    25.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
    26.        
    27.        
    28.  
    29.         if (Input.GetMouseButtonDown(0))
    30.         {
    31.             holdDownStartTime = Time.time;
    32.         }
    33.  
    34.         if (Input.GetMouseButtonUp(0))
    35.         {          
    36.            if (isGrounded == true)
    37.             {            
    38.                 float holdDownTime = Time.time - holdDownStartTime;
    39.                 float maxLaunchForce = launchForce * holdDownTime;
    40.                 sphereRigidbody.AddForce(target * maxLaunchForce, ForceMode2D.Impulse);
    41.             }
    42.            
    43.            
    44.         }
    45.  
    46.     }
    47.  
    48. }
     

    Attached Files:

    Last edited: Jan 14, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,518
    Screenshots of code are not a thing. If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/

    You must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    I notice you are passing Input.mousePosition into ScreenToWorld()... go look at the docs for what this function expects the .z value to be. You're implicitly giving zero.
     
    FartherGamer and GroZZleR like this.
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Welcome to the forum! Please refrain from posting screenshots of code in the future, just paste the code here inside an appropriate [ code ] [ /code ] blocks.

    As for your issue, counterintuitively, ScreenToWorldPoint actually requires a Z position to give an accurate value. Give this a shot:
    Code (csharp):
    1.  
    2. Camera camera = Camera.main;
    3. Vector2 mousePosition = Input.mousePosition;
    4.  
    5. Vector3 screenPoint = new Vector3(mousePosition.x, mousePosition.y, camera.nearClipPlane);
    6.  
    7. Vector3 target = camera.ScreenToWorldPoint(screenPoint);
    8.  
    9. // rest of your code
    10.  
     
    FartherGamer and Kurt-Dekker like this.
  4. FartherGamer

    FartherGamer

    Joined:
    Jan 7, 2022
    Posts:
    5
    Thank you for the information and I'm sorry I wasn't aware of the normal here I will remember for future here is my code displayed correctly

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BallMovement : MonoBehaviour
    6. {
    7.     public Rigidbody2D sphereRigidbody;
    8.     private float launchForce = 2;
    9.     private float holdDownStartTime;
    10.     public bool isGrounded;
    11.     public Transform groundCheck;
    12.     public LayerMask groundLayer;
    13.    
    14.  
    15.  
    16.     private void Start()
    17.     {
    18.         sphereRigidbody = GetComponent<Rigidbody2D>();
    19.     }
    20.     private void Update()
    21.     {
    22.  
    23.        Vector2 target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    24.  
    25.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
    26.        
    27.        
    28.  
    29.         if (Input.GetMouseButtonDown(0))
    30.         {
    31.             holdDownStartTime = Time.time;
    32.         }
    33.  
    34.         if (Input.GetMouseButtonUp(0))
    35.         {          
    36.            if (isGrounded == true)
    37.             {            
    38.                 float holdDownTime = Time.time - holdDownStartTime;
    39.                 float maxLaunchForce = launchForce * holdDownTime;
    40.                 sphereRigidbody.AddForce(target * maxLaunchForce, ForceMode2D.Impulse);
    41.             }
    42.            
    43.            
    44.         }
    45.  
    46.     }
    47.  
    48. }
     
  5. FartherGamer

    FartherGamer

    Joined:
    Jan 7, 2022
    Posts:
    5
    Thank you for the welcome and I will remember about the screenshots from now on, I just didn't know, here is my code the correct way and I just tried what you suggested but still get the same result, when the game starts it works as intended but when the ball and cam move to a new position the mouse tracking breaks and the ball jumps to the left regardless of where I clicked... honestly feels like the screen space being monitored is not moving with the cam and ball but I just dunno
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BallMovement : MonoBehaviour
    6. {
    7.     public Rigidbody2D sphereRigidbody;
    8.     private float launchForce = 2;
    9.     private float holdDownStartTime;
    10.     public bool isGrounded;
    11.     public Transform groundCheck;
    12.     public LayerMask groundLayer;
    13.  
    14.  
    15.  
    16.     private void Start()
    17.     {
    18.         sphereRigidbody = GetComponent<Rigidbody2D>();
    19.     }
    20.     private void Update()
    21.     {
    22.  
    23.        Vector2 target = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    24.  
    25.         isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
    26.      
    27.      
    28.  
    29.         if (Input.GetMouseButtonDown(0))
    30.         {
    31.             holdDownStartTime = Time.time;
    32.         }
    33.  
    34.         if (Input.GetMouseButtonUp(0))
    35.         {        
    36.            if (isGrounded == true)
    37.             {          
    38.                 float holdDownTime = Time.time - holdDownStartTime;
    39.                 float maxLaunchForce = launchForce * holdDownTime;
    40.                 sphereRigidbody.AddForce(target * maxLaunchForce, ForceMode2D.Impulse);
    41.             }
    42.          
    43.          
    44.         }
    45.  
    46.     }
    47.  
    48. }
     
    Last edited: Jan 14, 2022
  6. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Look at the API docs for Rigidbody2D.AddForce. It doesn't take a world position as the first argument which is what you're passing it. It takes a world direction of the force i.e. it'll add what you pass to the linear velocity.

    A direction from your Rigidbody2D to the target you calculated comes from "target - sphereRigidbody.position". You'll need to normalize this Vector2 to a unit-vector first prior to scaling it by your launch force so:

    Code (CSharp):
    1. sphereRigidbody.AddForce((target - sphereRigidbody.position).normalized * maxLaunchForce, ForceMode2D.Impulse);
    Also, note that you've posted the same thing twice above to two different devs. There's no need to do that, everyone can see a reply.
     
    GroZZleR and FartherGamer like this.
  7. FartherGamer

    FartherGamer

    Joined:
    Jan 7, 2022
    Posts:
    5
    Thank you, I will try this out now and I just didn't want to be considered rude by ignoring anyone's comment so I replied to both.
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    NOTE: I edited my post above with a correction. The correct direction is "target - sphereRigidbody.position" not the other way around I originally posted; that would move it away from the target.
     
    FartherGamer likes this.
  9. FartherGamer

    FartherGamer

    Joined:
    Jan 7, 2022
    Posts:
    5
    Your correction is exactly what I was missing and now everything works perfectly ! Truly Thank you so much.
     
    MelvMay likes this.