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

Click anywhere on screen to add force - not just on object

Discussion in 'Scripting' started by Deleted User, Nov 11, 2015.

  1. Deleted User

    Deleted User

    Guest

    I have a very ( very ) basic script on a gameObject that adds force onMouseUp : -

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class pushme : MonoBehaviour {
    5.  
    6.     void OnMouseUp() {
    7.        
    8.         GetComponent<Rigidbody>().AddForce(-transform.forward * 1000);
    9.         GetComponent<Rigidbody>().useGravity = true;
    10.            
    11.     }
    12. }
    And another basic script attached to the same object that always faces the mouse position : -

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class LookAtMouse : MonoBehaviour
    5. {
    6.    
    7.     // speed is the rate at which the object will rotate
    8.     public float speed;
    9.    
    10.     void FixedUpdate ()
    11.     {
    12.         // Generate a plane that intersects the transform's position with an upwards normal.
    13.         Plane playerPlane = new Plane(Vector3.up, transform.position);
    14.        
    15.         // Generate a ray from the cursor position
    16.         Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    17.        
    18.         // Determine the point where the cursor ray intersects the plane.
    19.         // This will be the point that the object must look towards to be looking at the mouse.
    20.         // Raycasting to a Plane object only gives us a distance, so we'll have to take the distance,
    21.         //   then find the point along that ray that meets that distance.  This will be the point
    22.         //   to look at.
    23.         float hitdist = 0.0f;
    24.         // If the ray is parallel to the plane, Raycast will return false.
    25.         if (playerPlane.Raycast (ray, out hitdist))
    26.         {
    27.             // Get the point along the ray that hits the calculated distance.
    28.             Vector3 targetPoint = ray.GetPoint(hitdist);
    29.            
    30.             // Determine the target rotation.  This is the rotation if the transform looks at the target point.
    31.             Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
    32.            
    33.             // Smoothly rotate towards the target point.
    34.             transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
    35.         }
    36.     }
    37. }
    I'd like some help in maybe combining these two scripts, in a format that would work as follows : -

    On MouseButtonDown - gameObject looks at mouse constantly, i.e. so whilst my mouse button is down, I can move the mouse around left, right, up and down, etc and have the gameObject always face the current mouse position, then on MouseButtonUp, apply the force in the chosen direction.

    This means the look at part only occurs when I actually click the mouse, not all the time, and then when I leave go, onMouseButtonUp, I shoot my gameObject off in the direction it is currently facing, any help please ?

    Thanks
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,179
    Your LookAtMouse's FixedUpdate needs to happen while the mouse is held down. If you wrap the entire code of the FixedUpdate in an "if (Input.GetMouseButton(0)) { ... }", that would make it only happen while the left mouse button is pressed.

    You could also replace FixedUpdate with OnMouseDrag, though that would mean that you'd have to click on the object, not anywhere.

    Oh, and the class "pushme" should be named "PushMe". It's a lot easier to read code that follows convention like that.
     
  3. Deleted User

    Deleted User

    Guest

    Thanks, I've already had some success with implementing what you mentioned, but I found the movement to be very jerky and only based on where I click on the screen, not freeform as I'd like. I'll keep cracking on unless anyone else chimes in ! :)
     
  4. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    @playmint You could create a UI Button, resize it to fit the Canvas, and set the Button's Opacity to 0, - Then add a script like this -

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.EventSystems;
    5.  
    6. public class ForceClick : MonoBehaviour, IPointerUpHandler
    7. {
    8.  
    9.     public Transform thing; // Set thing to the object u are adding the force to
    10.  
    11.     public void OnPointerUp(PointerEventData data)
    12.     {
    13.  
    14.  
    15.         thing.GetComponent<Rigidbody>().AddForce(-transform.forward * 1000);
    16.         thing.GetComponent<Rigidbody>().useGravity = true;
    17.  
    18.     }
    19. }
    20. }
    So this will make so whenever u let go of the Mouse Button anywhere on the screen it will add the force u wanted and set Gravity to true like u wanted
     
  5. Deleted User

    Deleted User

    Guest

    Thanks, Jonathan

    That's helpful, but only seems to work on one axis, not the direction I have my gameObject targeted towards, my gameObject is currently 'looking at' my mouse pointer, and should 'shoot' off in that direction, but this code, always shoots off in 1 direction only ( the default forward direction ).
     
  6. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Well If you wanted it to shoot off towards whatever its target is why dont u just add the force in the direction of the target instead of using transform.forward
     
  7. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Oh or you could just add the force local to the objects rotation lol
     
  8. Deleted User

    Deleted User

    Guest

    Hi, Jonathan

    In the small game I'm concepting, there are many targets, so I need to rotate my 'character' to face the particular 'enemies' I want to target, it's easier to rotate to aim and then shoot forward in the direction of any particular enemy I want to impact with.

    Please see the flash game in my other thread for clarity : -

    http://forum.unity3d.com/threads/charged-shot-script-help-payment-in-assets.367309/
     
  9. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Yeah adding the force local to the turtles rotation will do that
     
  10. Deleted User

    Deleted User

    Guest

    What I currently have : -

    A gameObject ( player )

    player has 2 scripts attached : -

    a LookAtMouse script, this only rotates the object on it's Y axis, and points to wherever the mouse is on the screen
    and a PushMe script, when I'm happy with where the object is pointing, I click on the object to propel it forward in the direction I want.

    SO... this currently works, but not in the way I ideally want....

    the LookAtMouse script can be quite jittery depending on mouse location, and the PushMe script is not ideal either as it moves at whatever force is hardcoded, and I want to have MORE or LESS power as required. As I posted before, for clarity see this thread : -

    http://forum.unity3d.com/threads/charged-shot-script-help-payment-in-assets.367309/
     
  11. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Hardcoded? Couldn't you just set the force amount as a variable so that you can change it to have "More or Less power"?
     
  12. Deleted User

    Deleted User

    Guest

    if I wasn't a stupid artist, probably, just don't know how ! ... :confused:
     
  13. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Oh its real easy take your pushme script for example -

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. public class pushme : MonoBehaviour {
    4.  
    5. //You can add a variable like the one below
    6. public float Power;
    7.  
    8.  
    9.     void OnMouseUp() {
    10.      
    11.         GetComponent<Rigidbody>().AddForce(-transform.forward * Power);
    12. // You can replace any number with a variable so In this case I replaced the 1000 with the Power variable
    13.         GetComponent<Rigidbody>().useGravity = true;
    14.          
    15.     }
    16. }
    So now you can change the Power variable to whatever you want from the Editor or from other scripts or from the pushme script itself
     
  14. Deleted User

    Deleted User

    Guest

    Thanks, Jonathan

    I do appreciate all your help, but not sure your understanding my requirement here, declaring the Power as a public variable is fine, but this is then still 'hardcoded' at runtime.

    In my case, I think I need to : -

    I need to declare a minimum charge variable
    I need to declare a maximum charge variable
    I need to declare a force variable ?

    in game, on MOUSE down, start increasing charge from minimum value and NO more than MAXIMUM value, on MOUSE up, AddForce where Force is the sum of how long we had the the mouse pressed down for and no more than the maximum value, this way for instance I could hold the mouse down and say the charge gets to 500, then let go, then that 500 amount of force is applied, if I instead hold the mouse button down and keep a hold for 5 minutes ( ridiculous I know ) and I reach maximum force of say, 1000, I can't surpass that, so the maximum force is applied instead.

    In the turtle game example, if you drag a little bit out the turtle moves a little, if you drag all the way out, the maximum force is applied, THIS is what I require, some way of adding force that can be anywhere between a minimum or maximum value before releasing the mouse and then applying that force amount, I would assume after release, I would also need to reinitialise the variables back their defaults.

    Seriously, though, it's nice to have a dialogue with anyone on this, I've so far discovered lots of ways NOT to do it, but useful learning.... :p
     
  15. Jonathan-Watkins

    Jonathan-Watkins

    Joined:
    Mar 10, 2015
    Posts:
    125
    Well its not "Hardcoded at runtime" because you can change that variable whenever you want through code...

    And if yes if you wanted a maximum force you can just do something like
    if(Power > MaxForce) {
    Power = MaxForce
    }
    And if you wanted it like the longer its held the higher the amount of force is then you can do something like set the Power to rise a certain amount after every x amount of seconds the mouse is held