Results 1 to 5 of 5
  1. #1
    Join Date
    Apr 2002
    Location
    Denmark
    Posts
    1,823

    Quickie howto: Moving an object by clicking a mouse button (C#)

    Made this for rflx and thoght I'd share. Maybe someone else out there is wondering how to do it

    Move object by mouse click:

    Webplayer compiled example here: http://kronholm.org/unity/rflx/mousemove/
    Assets and code here: http://kronholm.org/unity/rflx/mousemove_project/

    MouseMovement.cs which is also in the RAR file in the above link:
    Code:
    using UnityEngine;
    using System.Collections;
    
    public class MouseMovement : MonoBehaviour {
        GameObject player;
        RaycastHit hit;
        
        // Use this for initialization
    	void Start () {
            player = GameObject.Find("Player");
            hit = new RaycastHit(); 
    	}
    
    	// Update is called once per frame
    	void Update () {
            if (Input.GetKeyDown(KeyCode.Mouse0)) {
                if (Input.GetMouseButtonDown(0)) {
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                    
                    if (Physics.Raycast(ray, out hit, 1000.0f)) {
                        Vector3 newpos = new Vector3(hit.point.x, 0.5f, hit.point.z);
                        player.transform.position = newpos;
                    }
                }
            }
    	}
    }
    You cast a ray from the camera, which may or may not hit the floor. If it does, you put the position of the hit on an object, here the player.
    Dan 'pezz' Kronholm.
    Currently working on: The MMO class!.
    Previously working on: Game called "Boom Bots", while learning Unity and C#. WIP thread here.

  2. #2
    Join Date
    May 2008
    Posts
    542
    Yep, when I found out about the raycasting it totally blew my mind and opened itself up to me as a solution to one of the biggest mysteries of programming 3d game worlds.

    I was so giddy when I figured out how raycasting work and the logic behind it... taking the screen space coordinates, unprojecting the near clipping plane screen space coordinates and the far clipping plane screen space coordinates, and casting a ray from one to the other and figuring out what object in the world it's colliding with.

    So many cool things you can do with that information, like getting the surface normal so you can orient your objects(such as a 3d mouse cursor) dynamically along the surface.

    It was one of those great landmarks for me in 3d game development. I'm sure for others though it was an easy thing to figure out.
    Hello everyone and welcome to another 3DBuzz VTM, and tonight we'll be programming in Brain****!

  3. #3
    Join Date
    Oct 2011
    Posts
    2
    I actually cant get it to work. I get this "NullReferenceExceptionMouseMovement.Update () (at Assets/Assets/MouseMovement.cs:22)"

  4. #4
    Join Date
    Jun 2003
    Posts
    150
    One issue you may run into is your camera being inside a piece of geometry or underneath/behind terrain is the ray cast giving you the point closest to the camera, which will not be seen, causing your character to move in the opposite direction you intended.

    To correct this you need to see which way the surface the ray hit is facing relative to the camera's direction. It's a simple matter of checking to see if the dot product of the direction of the ray and the normal of the surface it hit is positive(bad, facing away from the camera) or negative(good, facing towards the camera). If you get a positive result you can simply recast the ray from that point in the same direction and see if you get a negative value. You can continuously do this until said condition is met. I've added/modified the code already posted to show this.

    Sorry for the odd spacing, I wrote the code in MonoDevelop to get correct spacing and when copy/pasting to here it didn't quite come out right.

    Code:
    using UnityEngine;
    
    using System.Collections;
    
    
    
    public class MouseMovement : MonoBehaviour {
    
        GameObject player;
    
        RaycastHit hit;
    
        
    
        // Use this for initialization
    
    	void Start () {
    
            player = GameObject.Find("Player");
    
            hit = new RaycastHit(); 
    
    	}
    
    
    
    	// Update is called once per frame
    
    	void Update () {
    
            if (Input.GetKeyDown(KeyCode.Mouse0)) {
    
                if (Input.GetMouseButtonDown(0)) {
    
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    
                    
    
                    if (Physics.Raycast(ray, out hit, 1000.0f)) {
    
                        
    
    			//MODIFIED FROM HERE ON BY EDGE DAMODRED, ORIGINAL AUTHOR IS pezz FROM 3DBuzz.com
    
    							
    
    			//need the camera direction(provided by the original ray cast) and surface we hit
    
    			float dot = Vector3.Dot(ray.direction, hit.normal);
    
    				
    
    			//need some kind of threshold for floating point values to use it for boolean logic.
    
    			//in this case I've chosen 0.000001f, any value below that is no longer positive(true).
    
    				
    
    			while(dot > 0.000001f)
    
    			{
    
    				//Recast the ray from the position we hit and store the new value.
    
    				//add 1 unit(ray.direction) to the position in the original
    
    				// direction so we don't hit this point again.
    
    					
    
    				if(!Physics.Raycast(hit.point+ray.direction,ray.direction,out hit,1000))
    
    				{
    
    					//Could not hit a point at all!
    
    					return;
    
    				}
    
    				dot = Vector3.Dot(ray.direction,hit.normal);
    
    			}
    
    					
    
    			//Once it gets past the loop above we'll have the correct point the player
    
    			//saw himself clicking on instead of the one hidden due to 
    
    			// backface culling(not showing polygons that have their designated positive side facing away from the camera).
    
                        Vector3 newpos = new Vector3(hit.point.x, 0.5f, hit.point.z);
    
                        player.transform.position = newpos;
    
                    }
    
                }
    
            }
    
    	}
    
    }
    Last edited by Edge Damodred; 01-18-2012 at 09:04 PM.

  5. #5
    Join Date
    Oct 2011
    Posts
    2
    Thank you for answering again. But still cant get it going, really been trying.

    Im going to try to specify what im trying to do.

    The mouse function I want to implement on a tower Defence game that im making in unity but going to port to Android or Ipad.
    Atm im only managing to move the "tower" to the point right beside it. Im literally just moving it 1pixel per click.

    I know im pretty vague but any help would be make my day !

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •