Need To Get camera to start behind object on each level

I have the camera search for a new target if it has none(when a new level is loaded) and that works fine. But it always is looking at the target from poor angles upon loading. I am having trouble modifying this script( this was originally made by another unity user see top comment for link to the thread he posted it in) and not sure where to go.

The object CamLoc is a cube i have in the spot the camera should start in. It has been made to be part of the object so that the vectors of the CamLoc object are were i want the camera to be when it loads.

But something in this script is moving it to those wierd locations after i move it were i want and it is never seen.

If anyone can help I’d be super appreciative since I have to demo the game tomorrow and the camera is basically the last thing to get right.

//modified from http://forum.unity3d.com/threads/16949-WOW-Camera-Movement/page5
var target : Transform; 
var targetHeight = 2.0; 
var distance = 2.8; 
var maxDistance = 10; 
var minDistance = 0.5; 
var xSpeed = 250.0; 
var ySpeed = 120.0; 
var yMinLimit = -40; 
var yMaxLimit = 80; 
var zoomRate = 20; 
var rotationDampening = 3.0; 
private var x = 0.0; 
private var y = 0.0; 
var isTalking:boolean = false;
var body : GameObject;

@script AddComponentMenu("Camera-Control/WoW Camera") 

function Start () { 
    var angles = transform.eulerAngles; 
    x = angles.y; 
    y = angles.x; 

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

function LateUpdate () { 
	if(Application.loadedLevelName != "Menu"){
	   if(!target) {
			
			transform.position = GameObject.Find("CamLoc").transform.position;

			body = GameObject.Find("Body");
			target = body.transform;
			return; 
		}
	
	
   // If either mouse buttons are down, let them govern camera position 
   if (Input.GetMouseButton(0) || (Input.GetMouseButton(1))){ 
   x += Input.GetAxis("Mouse X") * xSpeed * 0.02; 
   y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02; 
   
    
   // otherwise, ease behind the target if any of the directional keys are pressed 
   } else if(Input.GetAxis("Vertical") || Input.GetAxis("Horizontal")) { 
      var targetRotationAngle = target.eulerAngles.y; 
      var currentRotationAngle = transform.eulerAngles.y; 
      x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime); 
    }
      

   distance -= (Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime) * zoomRate * Mathf.Abs(distance); 
   distance = Mathf.Clamp(distance, minDistance, maxDistance); 
    
   y = ClampAngle(y, yMinLimit, yMaxLimit); 
   
  // ROTATE CAMERA:
   var rotation:Quaternion = Quaternion.Euler(y, x, 0); 
   transform.rotation = rotation; 
   
   // POSITION CAMERA:
   var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0)); 
   transform.position = position; 
   
	// IS VIEW BLOCKED?
    var hit : RaycastHit; 
    var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
	// Cast the line to check:
    if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
		// If so, shorten distance so camera is in front of object:
		var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28; 
		// Finally, rePOSITION the CAMERA:
		position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0)); 
		transform.position = position; 
	}
	}
}

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

Is suspect that the issue you have is in this code, as the rest look very similar to a camera control script I am using

	// IS VIEW BLOCKED?
    var hit : RaycastHit; 
    var trueTargetPosition : Vector3 = target.transform.position - Vector3(0,-targetHeight,0);
	// Cast the line to check:
    if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
		// If so, shorten distance so camera is in front of object:
		var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28; 
		// Finally, rePOSITION the CAMERA:
		position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0)); 
		transform.position = position; 
	}

You should check that the hit is not the Camera other with you are always “BEHIND” something…
if (hit.transform != transform) …

Sorry I’m not as experienced as I may have came off to be. I know it involves raycasts( something I am totally unfamiliar wit) and sadly not quite sure how to implement your idea.

Thanks for the reply regardless!

 if (Physics.Linecast (trueTargetPosition, transform.position, hit)) {  
              if (hit.transform != transform)
             {
		// If so, shorten distance so camera is in front of object:
		var tempDistance = Vector3.Distance (trueTargetPosition, hit.point) - 0.28; 
		// Finally, rePOSITION the CAMERA:
		position = target.position - (rotation * Vector3.forward * tempDistance + Vector3(0,-targetHeight,0)); 
		transform.position = position; 
	}
}

Like that

I added in the code but sadly the problem persists. In fact it still is located in the same spots. Its as if the camera moves as close to the object as the code allows and the looks from there. In various levels the camera will end up if different places around the object depending on where it was on the last scene.

Ok Question … trueTargetPosition, whiat is this trying to do?

Also try adding some Debug.Log or so print(“…”) statement to find out what the code is actually doing…

I believe its just a variable being used to detect a collision between where the camera is and where you want it to be to see if a wall is in the way and to accommodate accordingly.

And as for prints and debug.log do you mean place them inside the if to see if all are executing?

Ok I have just run the script in a simulated scene – flat plane with some object to hide behind…

Seems to be working for me…

What is the “target” set to and what is the “body” set to? on the script

The “Body” is the mesh of the main character which becomes the target. If it runs fine on yours what did you change, or could you post what ran on yours so we can attempt to find the differences. And by the way thank you SO for trying so hard to figure this out.

I ran the default script you posted.

I have a Capsule which is the “player” and I set target on the script to this and body to this.

I made no other changes.

It possibly the start angle is higher that youd like… it is possible to get a screen shot showing the issue?

421448--14642--$camProb1.jpg

421448--14644--$camProb2.jpg

forgive me if the links to pics don’t work. And forgive the crappy building model (its a placeholder :P)

anyway at first pic about to select to leave room note camera position is about what i want.

second indicates an unrendered mesh cube of where i would like it to load.

third is where it loads

I take it the camera is set DontDestroyOnLoad…

This looks like the x,y needs to be reset between scene loads… as its passing its position… (These hold the position on the camera, and seem to be holding across scenes)

possibly this could be done in the OnAwake, but im not sure that is executed on a scene load…

If you hold a movement key, does the camera move back to the correct position (your script has this in it to slerp back to behind during movement.)

Another way you could do it, is set the camera position to the location of the unrendered cube by attaching a findCamera set position script on it with the Code in the OnStart procedure (but this will still need the x,y reset to appropriate values for the new location).

putting the code in the OnAwake did not change anything.

And yes after i load into a new scene if the player walks forward the camera bgins to move to the right location.

create a procedure to call that allows you to set the x and y variables which control the camera location. then you can call this at the same point you call a scene load to set the variable appropriately for the start position on the next scene/level.

some like

public void SetCameraLocate(float camX, float camY)
{
   x = camX ;
  y = camY ;

}

then you should be able to do camera.SetCameraLocate(0,0) or whatever other values feel right…