Jump to content


Photo

My first cameraScript


  • Please log in to reply
No replies to this topic

#1 duke_Qa

duke_Qa

    I've had this avatar since... 2003?

  • Network Staff
  • 3,837 posts
  • Location:Norway
  • Division:Revora
  • Job:Artist

Posted 28 February 2010 - 08:06 PM

So, after working up until 5am this morning, I finally got the camerascript i've been working on up to a proper level. Here we have a quick test-link.

I still have a few things I'd want to optimize before I show you all the script, but this is practically a project i can continue on until I die more or less, so we'll see how long I continue with it. It's been a very enlightening experience to figure out how Unity3d's scripting language works as of yet, and with all the comments i've added to the script i hope i can share some of my experiences with you once i feel its tidy enough to show off :thumbsupdrool:


Edit: Okay, think this is good enough. Going to have to spend tomorrow making a basic mesh to test out shaders and lighting in a scene with this camera.

Direct link to js file

alot of text incoming, hope you enjoy uncolored code :grin: If not, just put it into unity and it will put the syntax color coding into place.

// A quick how to use: save script in your project, apply it to your camera, create an empty gameObject and insert it onto emptyCamTarget, and finally insert an object that you want the camera to focus on to begin with and when reset. 


//-----------------------------------------variables Stored here-----------------------------------------------
//-----------------------------------------variables Stored here-----------------------------------------------
//-----------------------------------------variables Stored here-----------------------------------------------
//-----------------------------------------variables Stored here-----------------------------------------------

var emptyCamTarget : Transform; //
var objectToAimFor: Transform;
//most of the variables below are for the DollyFunction, but also a few for the MoveFunction. this is what happens when you take a script and re-write it; you get a semi-mess :S 
var distanceMin = 10.0;
var distanceMax = 15.0;
var distanceInitial = 12.5;
var scrollSpeed = 5.0;
var xSpeed = 250.0;
var ySpeed = 250.0;
var yMinLimit = -20;
var yMaxLimit = 80;

private var x = 0.0;  //private variables doesnt allow you to change them in the inspector when you've applied the script to a component. keeps things nice and tidy. 
private var y = 0.0;
private var distanceCurrent = distanceInitial;
private var targetLoose: boolean; 
private var cameraTransform; 
private var EmptyVar;
cameraTransform = Camera.main.transform;; //I spent hours trying to find a way to dynamically select the component the script is hooked up to, And then it turned out to be "name".... jeeebus. Anyway, redundant, but nice to have for later...
//the variables for my resetTarget Function
var resetSpeed= 25.0;
private var targetVectorPos: Vector3;
private var start : Transform;
start = emptyCamTarget;
private var end : Transform;
private var startTimeVar:float;
private var currTimeVar: float;
private var resetCheck: int=0;
private var resetGoTime: int=0;
//resetGoTime=0;
//resetCheck=0;
end=objectToAimFor;
private var dist;
//the variables needed for my moveTarget Function
private var x2 = 0.0;
private var y2 = 0.0;
var MoveSpeed = 10.0;
private var MTFCheck: int=15;
private var initialX: int;
private var initialY: int;

//zoom2 variables belov
private var initialZoomX: float;
private var ZoomX: float;
private var zoomCheck: int;
zoomCheck=0;
//some variables to adjust navigation depending on the screen size. without them the movements on a smaller resolution gets very tedious, as i have adjusted the speeds according to a screen around 1050x1024 in this script. once you get a 600x450 screen with those options, things feel slow...
private var ScreenMultiX: float;
private var ScreenMultiY: float;
//-----------------------------------------Scripting starts here -----------------------------------------------
//-----------------------------------------Scripting starts here -----------------------------------------------
//-----------------------------------------Scripting starts here -----------------------------------------------
//-----------------------------------------Scripting starts here -----------------------------------------------



//a small GUI test, so i can type in some text about which buttons to use and whatnot
var windowInfo : Rect = Rect (20, 20, 120, 50);
function OnGUI () {
	GUI.Button (Rect (5, 5, 100, 20), GUIContent ("toolTip", " LMB - Dolly Camera \n MMB - Move Camera \n RMB - Zoom Camera \n Space - Reset Camera "));
	GUI.Label (Rect (0, 40, 200, 200), GUI.tooltip);

}


//Here we have some stuff i'm not sure what is good for. i have to research this part more. But it apparently is important to make a partial class our of this script for Unity to understand it. 
@AddComponentMenu("Camera-Control/MayaLikeMouseNavigation")
partial class cameraScriptMoveAndStuff { }

function Start () {

emptyCamTarget.position=objectToAimFor.position;
print ("emptyCanTargetPos: "+emptyCamTarget.position);
ScreenMultiX=1.0/Screen.width*1000.0;   
ScreenMultiY=1.0/Screen.height*1000.0;
//print("A: "+Screen.width+"B: "+Screen.height);
//print("heightProportion: "+ScreenMultiY+", widthProportion: "+ScreenMultiX);

	var angles = transform.eulerAngles;
	x = angles.y;
	y = angles.x;
	x2 = angles.y;
	y2 = angles.x;
	print("x2: "+x2+", y2:"+y2);
	

	// Make the rigid body not change rotation
	   if (rigidbody) {
		rigidbody.freezeRotation = true; }
		
		
}

//This is the lateUpdate the function that checks every frame(late, something about which way things should come in) if something should be done, where most things must be placed to get any dynamic changes. this is where the input-commands should be. 
function LateUpdate () {
	if (emptyCamTarget) 
	{
	if (Input.GetMouseButton(0)) { //this function checks if you are clicking your lmb and runs the function that rotates the camera around the "emptyCamTarget"
		DollyCamera();
		
		//some testing of creating empty things...
		   
	}
	
	
	if(Input.GetMouseButton(1)){//this is the right-click zoom function
	ZoomCamera2();
	}
	else zoomCheck=0;
	
	
	if (Input.GetMouseButton(2)) { //this function checks if you are pressing the MMB and then runs the function that moves the "emptyCamTarget" around
	MoveTarget();
		
	}	
	else {
	ReleaseTarget(); MTFCheck=0;
	}
	
	
	 if (Input.GetButton("Jump")) { //this function checks for space, and if its being pressed down, will move to your chosen "objectToAimFor".
	resetGoTime=1;
	
	}
	if (Input.GetButtonUp("Jump"))	 resetCheck=0; 
	
		
	ZoomCamera(); //this one just runs all the time, in case you scroll with the scrollbutton
	if(resetGoTime){ResetPosition();} //this one only runs when resetGotime is 1, 
}


}



//---------------------------------------------Custom Functions below----------------------------------------------
//---------------------------------------------Custom Functions below----------------------------------------------
//---------------------------------------------Custom Functions below----------------------------------------------




function DollyCamera () { 
	//this function spins the camera around the emptyCamTarget, alot of borrowed code here, don't ask me about clampAngle and quaternion.euler...read up on them... well clamAngle is not very detailed, but it basically stops the angle from going beyond certain levels. 
	x += Input.GetAxis("Mouse X") * xSpeed *ScreenMultiX* 0.02;
	y -= Input.GetAxis("Mouse Y") * ySpeed *ScreenMultiY* 0.02;
	
	
	y = ClampAngle(y, yMinLimit, yMaxLimit);  
		   
	var rotation = Quaternion.Euler(y, x, 0);
	var position = rotation * Vector3(0.0, 0.0, -distanceCurrent) + emptyCamTarget.position;
	
	transform.rotation = rotation;
	transform.position = position;
	}
	
	//the function that lets you zoom with the scroll-button
function ZoomCamera() {

	distanceCurrent -= Input.GetAxis("Mouse ScrollWheel") * scrollSpeed;

	distanceCurrent = Mathf.Clamp(distanceCurrent, distanceMin, distanceMax);
	 
 
	var rotation = Quaternion.Euler(y, x, 0);
	var position = rotation * Vector3(0.0, 0.0, -distanceCurrent) + emptyCamTarget.position;
	transform.position = position;		
}


function ZoomCamera2() {
	//this is the right-click zoom function. pretty much the same as the above, but with different input and some more if-sentences
	
	if (!zoomCheck){
		initialZoomX=Input.mousePosition.x;
	}
	if (zoomCheck){
		distanceCurrent -=(Input.mousePosition.x -initialZoomX) * scrollSpeed*ScreenMultiX*0.001;
		distanceCurrent = Mathf.Clamp(distanceCurrent, distanceMin, distanceMax);
	 
		var rotation = Quaternion.Euler(y, x, 0);
		var position = rotation * Vector3(0.0, 0.0, -distanceCurrent) + emptyCamTarget.position;
		transform.position = position;		
		initialZoomX=Input.mousePosition.x;
	
	}
	zoomCheck=1;
}


function MoveTarget() {
	 //this one moves the camera and emptyCamTarget when you MM-click,

	 emptyCamTarget.parent=cameraTransform;
	 print("emptyCamTargetParent: "+emptyCamTarget.parent);
	 if (!MTFCheck){ //on the first round, saves the initial X and Y. after that the script does this after it has moved the emptyCamTarget.
		 initialX=Input.mousePosition.x;
		 initialY=Input.mousePosition.y;
	 }

	 if (MTFCheck){ //a continuance of the above if, except that on the first runthrough it doesn't do crap. which gives me a starting position in X and Y I can use...
		 x2=(Input.mousePosition.x -initialX)* MoveSpeed * (distanceCurrent /4)*ScreenMultiX*0.001;
		 y2=(Input.mousePosition.y -initialY)* MoveSpeed * (distanceCurrent /4)*ScreenMultiY*0.001; 
			print("x2: "+x2+", y2:"+y2);
		 initialX=Input.mousePosition.x;
		 initialY=Input.mousePosition.y;
		 emptyCamTarget.transform.Translate(-x2, -y2, 0, cameraTransform.transform);
		 if(!(Input.mousePosition.x -initialX) && !(Input.mousePosition.y -initialY) ) ReleaseTarget(); //this one is needed because if the emptyCamTarget is parented to the camera, it will slide along into eternity. once the difference on the X and Y from last frame and current frame =0, it will unparent the emptyCamTarget and the camera stops moving
	 }

	 MTFCheck =1;
	 
}


function ReleaseTarget(){
	//where the aim-target will be parented back to the world
	emptyCamTarget.parent=null;
}

function ResetPosition(){
//the function to get your camera back to point zero if you get lost. basically works by figuring out the emptyCamTarget's current translation-position, and interpolating a curve between that position and the emptyCamTarget-object in the scene. 
	
			if (!resetCheck) {
				startTimeVar=Time.time;
				targetVectorPos=emptyCamTarget.position; //this hooks my "emptyCamTarget"'s position vector3 into a individual vector3 variable, so it won't change while moving the emptyCamTarget
				start=emptyCamTarget;
				}
			resetCheck =1;
			currTimeVar=Time.time-startTimeVar;

			
			//emptyCamTarget.position = Vector3.Lerp(targetVectorPos, end.position, (currTimeVar*resetSpeed*0.01));			 //the one i spent most time creating, ironically i like the smooth "flawed" one better because it is smoother, 
			emptyCamTarget.position = Vector3.Lerp(start.position, end.position, (currTimeVar*resetSpeed*0.01));	//
			//Debug.Log("01timeVariable: "+(currTimeVar*resetSpeed*0.01));
			dist = Vector3.Distance(start.position, end.position);
			print ("Distance to other: " + dist);
			if((dist)<0.2) {resetGoTime=0; resetCheck =0;}  //the final check that checks how far the two locations are from each-other. once its within 0.2 of each-other, the function stops and resets itself. 


		}
	

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);
}

Edited by duke_Qa, 05 March 2010 - 11:36 PM.

"I give you private information on corporations for free and I'm a villain. Mark Zuckerberg gives your private information to corporations for money and he's 'Man of the Year.'" - Assange





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users