- Home /
Move object towards mouse in full 3D space
Hello,
I'm working on a 3D space game and would like to move the ship like in EVE. This means, I can rotate the camera around the ship (got that) and double-click in a direction to turn and move there. The camera is always focused on the player ship, but can move further out and rotate around it.
1) How do I get the point where the mouse is? I was thinking about surrounding the player ship with a sphere and ray intersect it, but it seems like the sphere needs a bounding box to be intersected, which then pushes my ship (rigidbody) out (and would probably push away other objects aswell). Is there a way to intersect with it, but ignore it for physics? Or a totally different way of doing this?
2) How to properly rotate the ship towards that point, is there a semi-simple way to use rigidbody physics for that or is it better to skip physics and directly tween the rotation? Guess this is rather alot of code, so general advices would help already.
First question is most important for me to move on, if you can provide code samples I would prefer Javascript, but anything will do. I'll add further details if needed.
Answer by Mexallon · May 15, 2013 at 12:49 PM
Hej there.
1) Have a look at the **Physics.Raycast** class. As I played EVE alot (see username :)) i know what you want. I think what you need for that in Unity is something like this .
2) Rotating the ship is really easy. You can use transform.LookAt to let the ship look into that direction you got from the raycast. What you probably want to add after that is done is a linear interpolation from the current rotation to the desired because the ship would just change its rotation in one frame. See this reference.
If you have no Idea of how to use Lerp (Linear Interpolation) functions have a look at this great tutorial.
1) Thanks, the problem was that your example needs something to intersect with, but ray.GetPoint(100.0) seems to do the trick without any intersect.
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var destination : Vector3 = ray.GetPoint (100.0);
It's not a true destination, but a point I can rotate towards.
2) LookAt already changes the object, is there a function to get the target rotation without actually rotating the object? And I'm still curious how it could work with proper physics, but you got me started :)
to 2): What do you mean with target rotation? You could calculate the angle between the current rotation and the desired - if thats what you want have a look at Vector.Angle.
Answer by supamigit · Apr 25, 2014 at 12:17 PM
I set up 6 planes in every direction 2000 away from center then used this script... if moves from start which is next thing to change to a +- fast slower method...
Raycast bounces off the planes allowing the ship to move up and down in the Z access
oh left click double initiates move to that direction right click hold allows to move the camera 360 all directions around the ship
Code Below..........
#pragma strict
var PlayerCamera : Transform;
private var ThisTransform : Transform;
var CameraOffset : Vector3 = Vector3(0,3,10);
var CameraSpeed : int = 200;
var yMinLimit = -90;
var yMaxLimit = 90;
private var MouseInput : Vector2;
private var directionTurn : Vector3;
private var singleClick : boolean = false;
private var count : int;
private var Turn : boolean;
private var cTimer : float;
var doubleClickTime : float = .5;
function Start () {
ThisTransform = transform;
PlayerCamera.eulerAngles = Vector3(0, 0, 0);
PlayerCamera.position = Vector3(ThisTransform.position.x, ThisTransform.position.y + CameraOffset.y, ThisTransform.position.z - CameraOffset.z);
}
function Update () {
ThisTransform.Translate(Vector3.forward * 5 * Time.deltaTime);
if(Input.GetMouseButtonDown(0)){
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
singleClick = true;
count ++;
}
if(singleClick == true){
cTimer += Time.deltaTime;
if(count >1){
directionTurn = ray.direction * 2000;
Turn = true;
singleClick = false;
count = 0;
cTimer = 0;
}
if(cTimer >= doubleClickTime){
count = 0;
singleClick = false;
Turn = false;
cTimer = 0;
}
}
if(Turn){
var Rotation = Quaternion.LookRotation(directionTurn - ThisTransform.position);
ThisTransform.rotation = Quaternion.RotateTowards(ThisTransform.rotation, Rotation, Time.deltaTime * 50);
ThisTransform.eulerAngles.z = 0;
var targetDir = directionTurn - transform.position;
var forward = transform.forward;
var angle = Vector3.Angle(targetDir, forward);
if(angle < 0.05){
Turn = false;
}
}
}
function LateUpdate(){
UpdateCamera();
}
function UpdateCamera () {
var rot : Quaternion = Quaternion.Euler(MouseInput.y, MouseInput.x, 0);
var pos : Vector3 = rot * Vector3(0.0, CameraOffset.y, -CameraOffset.z) + ThisTransform.position;
if(Input.GetMouseButton(1)) {
MouseInput.x += Input.GetAxis("Mouse X") * CameraSpeed * Time.deltaTime;
MouseInput.y -= Input.GetAxis("Mouse Y") * CameraSpeed * Time.deltaTime;
MouseInput.y = ClampAngle(MouseInput.y, yMinLimit, yMaxLimit);
}
PlayerCamera.position = pos;
PlayerCamera.rotation = rot;
}
static function ClampAngle (angle : float, min : float, max : float) {
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp (angle, min, max);
}
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Mouse Movement (Tracking) 1 Answer
Animation not working correctly on moving object 1 Answer
Attach an object to the mouse cursor? 0 Answers
Moving a gameobject with mouse 1 Answer