Camera/Object control with mouse, 4 axis steady rotate

OK so, heres my problem.

I have a spaceship. When i move my mouse up, the ship looks up. Great!.
Well the problem is, i have to keep moving the mouse up to make it continue to rotate.

I cant seem to figure out how i can move the mouse a little upwards and have the model constantly rotating without moving the mouse any further, and perhaps the farther i move the mouse the faster it rotates.

Replace the word up with left down and right respectively.

currently i am using this which sortof works. I have the spaceship and the camera “bolted” together so you see what the ship sees basically.

var flyingSpeed = 500; 
var minThrust = 20; 
var maxThrust = 300; 
var Accel = maxThrust / 4;
var turnSpeed = 100; 


function Update() { 


	if(Input.GetButton("Jump")){  
	flyingSpeed = flyingSpeed+maxThrust;
	if(flyingSpeed>2000)
	{
	flyingSpeed= flyingSpeed-500;
    }
	}
	if(!Input.GetButton("Jump"))
	{
	flyingSpeed = Accel + Mathf.Clamp(flyingSpeed, minThrust, maxThrust + Accel);
	}

	if(("Jump"))
	{ 
   rigidbody.velocity = transform.forward * Time.deltaTime * flyingSpeed;
	}

	
   if(Input.GetAxis("Mouse X") > 0.0){ 
      transform.Rotate(0.0, turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
   } 
   if(Input.GetAxis("Mouse X") < 0.0){ 
      transform.Rotate(0.0, -turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
   } 
   if(Input.GetAxis("Mouse Y") > 0.0){ 
      transform.Rotate(-20.0, Time.deltaTime, 0.0); 
   } 
    
   if(Input.GetAxis("Mouse Y") < 0.0){
      transform.Rotate(20.0, Time.deltaTime, 0.0); 
     } 


}

You’ll probably want to work with the mouse position rather than the mouse delta.

IIRC, the ‘Mouse X’ and ‘Mouse Y’ axes return the mouse delta for that update; that’s why you have to keep moving the mouse in order to continue to rotate.

It sounds like what you want to do is rotate based on the current position of the mouse relative (presumably) to the center of the screen. You’d probably want a ‘dead area’ in the middle, and then outside that area, the rate of rotation would be proportional to the distance from the mouse position to the center of the screen, and the direction of rotation would be based on the direction vector from the center of the screen to the mouse position. (Or it least that’s what it sounds like you’re looking for.)

what you described is exactly what im going for. but im too stupid to code that. lol. camera/movement controls are hard to graspo in my feeble little mindo

so basically instead of time.deltatime i use time.mouseposition?

Why would you expect the mouse position be a member of the ‘Time’ class? (Yes, that’s sort of a rhetorical question, but I think it’s worth asking.)

Ok, let’s take it a step at a time. Since you’ll need to know where the center of the screen is, a good first step would probably be to create a Vector3 (or Vector2) object that represents the center of the screen. Do you know how to do that?

vector 2 im guessing would be something like

Vector2 size = gameReference.GraphicsDevice.Viewport.TitleSafeArea.Center

lol? lemme mull around a minute.

possibly this:

private var screenCenter : Vector2;

function Awake () {
    screenCenter = Vector2(Screen.width/2, Screen.height/2);
}

That looks good to me :slight_smile: (One comment though - I’d probably compute that exactly where it’s needed rather than computing and saving it in Awake(), just in case the screen resolution changes while the game is running.)

Now, the next thing you need is the vector from the screen center to the mouse position; this will tell you where the mouse is relative to the screen center. (For example, if the screen center is 512, 384 and the mouse position is 502, 394, the mouse position relative to the screen center is -10, 10. Make sense?)

So, do you know how to compute that vector?

heres what i combobulated so far

var halfScreen : Vector2;
var screenCenter : Vector2 = Input.mousePosition - halfScreen;
var quadrant : Vector2 = Vector2(Mathf.Sign(screenCenter.x), Mathf.Sign(screenCenter.y));

function Start(){

	halfScreen = Vector2(Screen.width/2.0, Screen.height/2.0);

}

after this i just need to plug that stuff into this stuff

 if(Input.GetAxis("Mouse X") > 0.0){ //if the right arrow is pressed 
      transform.Rotate(0.0, turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World); //and then turn the plane 
   } 
   if(Input.GetAxis("Mouse X") < 0.0){ //if the left arrow is pressed 
      transform.Rotate(0.0, -turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World); //The X-rotation turns the plane - the Z-rotation tilts it 
   } 
   if(Input.GetAxis("Mouse Y") > 0.0){ //if the up arrow is pressed 
      transform.Rotate(-20.0 * Time.deltaTime, 0.0, 0.0); 
   } 
    
   if(Input.GetAxis("Mouse Y") < 0.0){ //if the down arrow is pressed 
      transform.Rotate(20.0 * Time.deltaTime, 0.0, 0.0); 
     }

think i might have lost track of something. im seeing what i need to do i think… hard to focus with a stuffy nose. haha

Edit: wow im an idiot. lol i was like wtf is all these errors. then i realised what i was doing.

 var halfScreen : Vector2;
var screenCenter : Vector2;
var quadrant : Vector2;


function Start(){

	halfScreen = Vector2(Screen.width/2.0, Screen.height/2.0);

}


function Update() { 

	quadrant = Vector2(Mathf.Sign(screenCenter.x), Mathf.Sign(screenCenter.y));
	screenCenter = Input.mousePosition - halfScreen;

Be sure to think about when and where each bit of code will execute. I’m not sure if/how the code you posted above works, but remember that a piece of code that only executes once (e.g. during initialization or in the Awake() or Start() function) will only reflect the state of things at that time. So, if you only compute ‘halfScreen’ in Start(), it will only ever reflect the resolution at the time the Start() function is executed; if the resolution changes at some later time, ‘halfScreen’ will no longer be correct.

Similarly, for something like this:

var screenCenter : Vector2 = Input.mousePosition - halfScreen;

Even if it compiles and works as expected (and I don’t know enough about UnityScript to say if it will), it’ll only execute once, when the object is initialized. That is, screenCenter will not continue to reflect the current position of the mouse as the game runs. Does that make sense?

Also, ‘screenCenter’ isn’t a good name for that variable; something like ‘relativeMousePosition’ would make more sense.

I wouldn’t get too far ahead of yourself with this. Instead of moving on to trying to implement the movement code itself, I’d recommend getting just the relative mouse position stuff working, and only that. You’ve got the right idea, generally speaking, but you need to get the code in the right place and make sure it’s working correctly before you move on. (A good way to determine whether the code is doing the right thing would be to print out the relative mouse position using Debug.Log(), and see if it’s what you expect it to be.)

[Edit: Your revised code is getting a bit closer :)]

ok the last bit of code i posted works. the output is 1,-1 or 1,1, or 0,1 or 0,-1

which works for the most simple part of the movement. when the mouse is in a quadrant, the object moves.

but its not quite right.

right now the screen is divided more like a “+” sign, when it needs to be divided by an “x” sign. also, i need to implement a “dead zone” in the middle where the object dosent move at all.

hmm.

so instead of

quadrant = Vector2(Mathf.Sign(screenCenter.x), Mathf.Sign(screenCenter.y));

i have

quadrant = Vector2(screenCenter.x, screenCenter.y);

this outputs a more reasonable number to work with so i can code a dead zone and quadrant the screen properly.

now i just need to figure out an equation that does that.

if quadrant = ????????????????????????????????????????

p.s. ill modify the screenCenter after this bit.
oh and Edit: ive been told that putting the halfscreen = vector2 part in the update part, its heavy on the processing.
since i want to keep it as simple and efficient as possibile from the beginning, i think (since this game will only be played in a web player) having it update only once will be fine. (maybe) otherwise i have no other idea where to put it.

Yes, I mentioned that in my first reply :slight_smile:

For the ‘dead area’, compute the distance (could also use squared distance, but distance would be easier and the cost shouldn’t be a concern here) from the mouse position to the center of the screen. Then, only proceed if the distance is greater than some specified threshold (which you might want to represent in terms of a percentage of the screen height if you want it to be consistent regardless of resolution).

Once you have that part working, you can move on to determining the quadrant.

the dead zone is killing me. cant figure it out. is gotta be small, not big at all. like maybe 20 pixels radius

Post your code.

heres the new stuff added in with the old stuff.

the old stuff on the bottom is what is actually controlling the movement as i havent figured out how to implement the quadrant based system yet.

var flyingSpeed = 500; 
var minThrust = 20; 
var maxThrust = 300; 
var Accel = maxThrust / 4;
var turnSpeed = 100; 
var halfScreen : Vector2;
var relativeMousePosition : Vector2;
var quadrant : Vector2;

function Start(){

	

}


function Update() { 

 halfScreen = Vector2(Screen.width/2.0, Screen.height/2.0);
 quadrant =  Vector2(relativeMousePosition.x, relativeMousePosition.y);
 relativeMousePosition = Input.mousePosition - halfScreen;
 print(quadrant);


if(Input.GetButton("Jump")){  
 flyingSpeed = flyingSpeed+maxThrust;
if(flyingSpeed>2000)
{
flyingSpeed= flyingSpeed-500;
}
}
if(!Input.GetButton("Jump"))
{
flyingSpeed = Accel + Mathf.Clamp(flyingSpeed, minThrust, maxThrust + Accel);
}

if(("Jump"))
{ 
 rigidbody.velocity = transform.forward * Time.deltaTime * flyingSpeed;
}
	
if(Input.GetAxis("Mouse X") > 0.0){
 transform.Rotate(0.0, turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
}
if(Input.GetAxis("Mouse X") < 0.0){
 transform.Rotate(0.0, -turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
}
if(Input.GetAxis("Mouse Y") > 0.0){
 transform.Rotate(-20.0 * Time.deltaTime, 0.0, 0.0); 
}
if(Input.GetAxis("Mouse Y") < 0.0){
 transform.Rotate(20.0 * Time.deltaTime, 0.0, 0.0); 
} 


}

edited to look better. i think.

Sorry for being picky, but I find it difficult (or tedious, at least) to read code that’s not properly formatted/indented.

For what it’s worth, I find that if you replace all tabs with spaces before posting, it usually comes out right (assuming the indentation was consistent to begin with). Another tip would be to remove ‘trailing’ comments and/or break your lines so that they don’t wrap in the code box.

These may seem like minor details, but addressing these issues will make it much easier to look over your code and get a sense of what you’re trying to do.

lol sorry i was just copy pasting what i had. btw i figured it out. so ill edit the old post and post the new movement here. funny how it all worked out and the dead zone just kinda fell on my lap.

if(relativeMousePosition.x > 20.0){
 transform.Rotate(0.0, turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
}
if(relativeMousePosition.x < -20.0){
 transform.Rotate(0.0, -turnSpeed * Time.deltaTime, 0.0 * Time.deltaTime, Space.World);
}
if(relativeMousePosition.y > 20.0){
 transform.Rotate(-20.0 * Time.deltaTime, 0.0, 0.0); 
}
if(relativeMousePosition.y < -20.0){
 transform.Rotate(20.0 * Time.deltaTime, 0.0, 0.0); 
} 


}

p.s. how do you break the code line so its easier to look at?

You just do it manually. Here’s your code formatted in an (IMO) more readable way:

if (relativeMousePosition.x > 20.0) {
    transform.Rotate(
        0.0, turnSpeed * Time.deltaTime, 0.0, Space.World);
}
if (relativeMousePosition.x < -20.0) {
    transform.Rotate(
        0.0, -turnSpeed * Time.deltaTime, 0.0, Space.World);
}
if (relativeMousePosition.y > 20.0) {
    transform.Rotate(-20.0 * Time.deltaTime, 0.0, 0.0); 
}
if(relativeMousePosition.y < -20.0) {
    transform.Rotate(20.0 * Time.deltaTime, 0.0, 0.0); 
}

next up:

adding graphics and more 3d elements. the fun and easy stuff. lol. ill watch my fps go from 250 to about 12 in no time.

thanks for the help.

qatc