WOW Camera Movement

in my code, I assign values in 2 places to the variable ‘correctedDistance’, one of them conditional on the correction of the value if the linecast detected a collision. subtract some fixed amount from those values to give yourself that buffer.

Maybe I’m just brain dead, but subtracting 100 is still not doing anything.

P.S.
I had to convert it to JavaScript, sorry!

public var target : Transform;

public var targetHeight : float = 1.7;

public var distance : float = 5.0;

public var maxDistance : float= 20;
public var minDistance : float = .6;

public var xSpeed : float = 250.0;
public var ySpeed : float = 120.0;

public var yMinLimit : int = -80;
public var yMaxLimit : int = 80;

public var zoomRate : int = 40;

public var rotationDampening : float = 3.0;
public var zoomDampening : float = 5.0;

private var x : float = 0.0;
private var y : float = 0.0;
private var currentDistance : float;
private var desiredDistance : float;
private var correctedDistance : float;

function Start ()
{
	var angles : Vector3 = transform.eulerAngles;
	x = angles.x;
	y = angles.y;
	
	currentDistance = distance;
	desiredDistance = distance;
	correctedDistance = distance;
	
	// Make the rigid body not change rotation
	if (rigidbody)
		rigidbody.freezeRotation = true;
}

/**
 * Camera logic on LateUpdate to only update after all character movement logic has been handled.
 */
function LateUpdate ()
{
	// Don't do anything if target is not defined
	if (!target)
		return;
	
	// If either mouse buttons are down, let the mouse 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") != 0 || Input.GetAxis("Horizontal") != 0)
	{
		var targetRotationAngle : float = target.eulerAngles.y;
		var currentRotationAngle : float = transform.eulerAngles.y;
		x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
	}
	
	y = ClampAngle(y, yMinLimit, yMaxLimit);
	
	// set camera rotation
	var rotation : Quaternion = Quaternion.Euler(y, x, 0);
	
	// calculate the desired distance
	desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
	desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
	correctedDistance = desiredDistance -100;
	
	// calculate desired camera position
	var position : Vector3 = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));
	
	// check for collision using the true target's desired registration point as set by user using height
	var collisionHit : RaycastHit;
	var trueTargetPosition : Vector3 = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);
	
	// if there was a collision, correct the camera position and calculate the corrected distance
	var isCorrected : boolean = false;
	if (Physics.Linecast(trueTargetPosition, position, collisionHit))
	{
		position = collisionHit.point;
		correctedDistance = Vector3.Distance(trueTargetPosition, position);
		correctedDistance -= 100;
		isCorrected = true;
	}
	
	// For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
	currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
	
	// recalculate position based on the new currentDistance
	position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight, 0));
	
	transform.rotation = rotation;
	transform.position = position;
}

private static function ClampAngle(_angle : float, _min : float, _max : float) : float
{
	if (_angle < -360)
		_angle += 360;
	if (_angle > 360)
		_angle -= 360;
	return Mathf.Clamp(_angle, _min, _max);
}

Hey all - just a quick thanks for posting these scripts. Very helpful for a project I’m working on. The camera.cs script is super useful!

Thanks!

Hello, everyone, thank you for being sharing their work.

Someone to solve the problem with the camera in the C# script or in Javascript?

Yes, but you should make a new topic, instead of posting in an old one.

NO NO NO… Pleas continue to write in THIS thread… I know the scripts at the beginning dont completely work, but if you subscribe to a lot of threads to watch the development and learn you NEED some kind of consistancy in how the information that this forum throws up.

PLEASE remeber, this is NOT chat… its a resource you are building, for those that follow in your footsteps…

OH… AND ONE MORE THING:
Could you clever coders please add the NAME to the script (camera.cs) as a comment actually IN the code at the top, plus author, plus email, plus date??? Just usual programming practice…

Cheers

Mark
Extreme Newbie

Actually, these last 2 scripts have turned out quite wonderful! They are used for the MMO I just finished at http://www.bobbersworld.com (it took 4 months of development time with 1 programmer, 1 modeler and 1 texture artist)

broken link my friend :slight_smile:

http://bobbersworld.com/, world, singular.

Looks great, btw. Best of luck with it.

yes, i too think this.

about the problem that i am geting in Camera Scripts is:

WowCamera.js
Posted for matrix211v1: Fri May 15, 2009 9:17 pm[/b]

```
**//WowCamera.js

//with test of Collision Correction

//Credits to this script: “matrix211v1”

public var target : Transform;

public var targetHeight : float = 1.7;

public var distance : float = 5.0;

public var maxDistance : float= 20;
public var minDistance : float = .6;

public var xSpeed : float = 250.0;
public var ySpeed : float = 120.0;

public var yMinLimit : int = -80;
public var yMaxLimit : int = 80;

public var zoomRate : int = 40;

public var rotationDampening : float = 3.0;
public var zoomDampening : float = 5.0;

private var x : float = 0.0;
private var y : float = 0.0;
private var currentDistance : float;
private var desiredDistance : float;
private var correctedDistance : float;

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

currentDistance = distance;
desiredDistance = distance;
correctedDistance = distance;

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

/**

  • Camera logic on LateUpdate to only update after all character movement logic has been handled.
    */
    function LateUpdate ()
    {
    // Don’t do anything if target is not defined
    if (!target)
    return;

    // If either mouse buttons are down, let the mouse 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”) != 0 || Input.GetAxis(“Horizontal”) != 0)
    {
    var targetRotationAngle : float = target.eulerAngles.y;
    var currentRotationAngle : float = transform.eulerAngles.y;
    x = Mathf.LerpAngle(currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
    }

    y = ClampAngle(y, yMinLimit, yMaxLimit);

    // set camera rotation
    var rotation : Quaternion = Quaternion.Euler(y, x, 0);

    // calculate the desired distance
    desiredDistance -= Input.GetAxis(“Mouse ScrollWheel”) * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
    desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    correctedDistance = desiredDistance -100;

    // calculate desired camera position
    var position : Vector3 = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));

    // check for collision using the true target’s desired registration point as set by user using height
    var collisionHit : RaycastHit;
    var trueTargetPosition : Vector3 = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);

    // if there was a collision, correct the camera position and calculate the corrected distance
    var isCorrected : boolean = false;
    if (Physics.Linecast(trueTargetPosition, position, collisionHit))
    {
    position = collisionHit.point;
    correctedDistance = Vector3.Distance(trueTargetPosition, position);
    correctedDistance -= 100;
    isCorrected = true;
    }

    // For smoothing, lerp distance only if either distance wasn’t corrected, or correctedDistance is more than currentDistance
    currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;

    // recalculate position based on the new currentDistance
    position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight, 0));

    transform.rotation = rotation;
    transform.position = position;
    }

private static function ClampAngle(_angle : float, _min : float, _max : float) : float
{
if (_angle < -360)
_angle += 360;
if (_angle > 360)
_angle -= 360;
return Mathf.Clamp(_angle, min, max);
}**
** __*************__ __*************__ __*************__ __*************__ __**WowCamera.cs**__ __**Posted for Paintbrush: Thu May 07, 2009 10:05 am[/b]**__ __**Please enter in link to see my result of this script.**__ __**http://www.universalgamesonline.com.br/unity3d/studies/wowcamera.cs.html**__ __**

**//WowCamera.cs

//Credits to this script: “Paintbrush”

using UnityEngine;
using System.Collections;

public class WowCamera : MonoBehaviour
{

public Transform target;

public float targetHeight = 1.7f;
public float distance = 5.0f;

public float maxDistance = 20;
public float minDistance = .6f;

public float xSpeed = 250.0f;
public float ySpeed = 120.0f;

public int yMinLimit = -80;
public int yMaxLimit = 80;

public int zoomRate = 40;

public float rotationDampening = 3.0f;
public float zoomDampening = 5.0f;

private float x = 0.0f;
private float y = 0.0f;
private float currentDistance;
private float desiredDistance;
private float correctedDistance;

void Start ()
{
Vector3 angles = transform.eulerAngles;
x = angles.x;
y = angles.y;

    currentDistance = distance;
    desiredDistance = distance;
    correctedDistance = distance;

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

}

/**
 * Camera logic on LateUpdate to only update after all character movement logic has been handled.
 */

void LateUpdate ()
{
// Don’t do anything if target is not defined
if (!target)
return;

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

    y = ClampAngle(y, yMinLimit, yMaxLimit);

    // set camera rotation
    Quaternion rotation = Quaternion.Euler(y, x, 0);

    // calculate the desired distance
    desiredDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs(desiredDistance);
    desiredDistance = Mathf.Clamp(desiredDistance, minDistance, maxDistance);
    correctedDistance = desiredDistance;

    // calculate desired camera position
    Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + new Vector3(0, -targetHeight, 0));

    // check for collision using the true target's desired registration point as set by user using height
    RaycastHit collisionHit;
    Vector3 trueTargetPosition = new Vector3(target.position.x, target.position.y + targetHeight, target.position.z);

    // if there was a collision, correct the camera position and calculate the corrected distance
    bool isCorrected = false;
    if (Physics.Linecast(trueTargetPosition, position, out collisionHit))
    {
        position = collisionHit.point;
        correctedDistance = Vector3.Distance(trueTargetPosition, position);
        isCorrected = true;
    }
   
    // For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
    currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp(currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;

    // recalculate position based on the new currentDistance
    position = target.position - (rotation * Vector3.forward * currentDistance + new Vector3(0, -targetHeight, 0));

    transform.rotation = rotation;
    transform.position = position;

}

private static float ClampAngle(float angle, float min, float max)
{
    if (angle < -360)
        angle += 360;
    if (angle > 360)
        angle -= 360;
    return Mathf.Clamp(angle, min, max);
}

}
__
**__ <strong>__*************__</strong> <strong>__*************__</strong> <strong>__*************__</strong> <strong>__*************__</strong> <strong>__**WowCamera.js**__</strong> <strong>__**Posted for matrix211v1: Sun May 03, 2009 2:48 am[/b]**__</strong> <strong>__**http://www.universalgamesonline.com.br/unity3d/studies/wowcamera.js.html**__</strong> <strong>__**__
//WowCamera.js

//When the camera hits something, it “instantly” gets behind the player.

//Credits to this script: “matrix211v1”

var target : Transform;

var targetHeight = 12.0;
var distance = 5.0;

var maxDistance = 20;
var minDistance = 2.5;

var xSpeed = 250.0;
var ySpeed = 120.0;

var yMinLimit = -20;
var yMaxLimit = 80;

var zoomRate = 20;

var rotationDampening = 3.0;

var theta2 : float = 0.5;

private var x = 0.0;
private var y = 0.0;

private var fwd = new Vector3();
private var rightVector = new Vector3();
private var upVector = new Vector3();
private var movingVector = new Vector3();
private var collisionVector = new Vector3();
private var isColliding : boolean = false;

private var a1 = new Vector3();
private var b1 = new Vector3();
private var c1 = new Vector3();
private var d1 = new Vector3();
private var e1 = new Vector3();
private var f1 = new Vector3();
private var h1 = new Vector3();
private var i1 = new Vector3();

@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(!target)
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);

var rotation:Quaternion = Quaternion.Euler(y, x, 0);
var position = target.position - (rotation * Vector3.forward * distance + Vector3(0,-targetHeight,0));

// Check to see if we have a collision
collisionVector = AdjustLineOfSight(transform.position, position);

// Check Line Of Sight
if (collisionVector != Vector3.zero)
{
Debug.Log(“Check Line Of Sight”);
a1 = transform.position;
b1 = position;
c1 = AdjustLineOfSight(transform.position, position);
d1 = c1 - a1;
e1 = d1.normalized * -1;
f1 = d1 + e1 * 1;
g1 = f1 + a1;
position = g1;

  // check distance player to camera
  h1 = position - a1;
  if (h1.magnitude < 10)
  {
     position = a1 - fwd * 4;
     //position.y = targetPlayer.y;
     theta2 = theta2 + .25;
  }
  
  // set new camera distance
  h1 = position - a1;
  distance = h1.magnitude;

}

// check collision
if (Physics.CheckSphere (position, .5) )
{
a1 = transform.position;

  newPosition = a1 - fwd * 4;
  //newPosition.y = targetPlayer.y;
  theta2 = theta2 + .25;
  
  // set new camera distance
  h1 = position - a1;
  distance = h1.magnitude;

}

//position = Vector3.Slerp(transform.position, position, Time.deltaTime * 100);

transform.rotation = rotation;
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);
}

function AdjustLineOfSight (vecA: Vector3, vecB: Vector3)
{
var hit: RaycastHit;

  if (Physics.Linecast (vecA, vecB, hit))
  {
     Debug.Log("I hit something");
     return hit.point;
  }
 
 return Vector3.zero;

}
__```**




I thanks all for helps and shares!!!
And sorry for this BIG Post.
*************__

Not sure what the issue is by looking at the screen shot BUT make sure you have your player as your Target in the component editor.

yes, my player is in Target of Componet WowCamera Script in my Main Camera.

thanks for helping.

i am making images of my errors, of your others Script posted in Sun May 03, 2009 2:48 am

I think that you are simply not setting up the variables exposed on the WoWCamera component. that I guess you have added to your Camera.

just adjusting your cameras start position relative to the parented character isnt enough, click your camera, and make the adjustments on the WoWCamera component.

ALSO:
Earlier message complained of whacky jumping in the idle state… I too get this… I am however NO CODER… just a dirty mean code stealer… Was this fixed? Matrix?? Please, Pretty please?

Also Im getting an error Axis Run not set up. This is because you have a reference to using the T key (line 51) for run. I dont have this setup… had a look but cant figure it out… I added Run, but then… settings… Hjelp!

What else? Oh… just to say that I was V impressed that the mouse wheel affects the distance to character… nice, genuine touch.

One thing, to be picky… Both Left and right mouse buttons do the same. In WoW however Rt mouse steers (same as you have done) but left mouse rotates camera around the character (tis the only way you can see your own face) I think this might auto correct after a while. So left click is more like a camera positioning tool.

yes, i have adjusted values of camera, and too have tested modify anythings in scripts, but without sucess.

I have posted my error in Page 2, please, if somebody have patience, look my building Web Player that i have posted the Links, in page 2 with the 3 differents scripts used.

The scripts have been pretty helpful in getting a camera setup. I have based by implementation on Paintbrush’s C# code, although I’m running into the issue that matrix211v1 reported, and which Paintbrush seemed to have a solution to.

The camera position is aligned with the surface, so the camera is clipping through. I’d like to have some padding around the camera (0.25) that keeps it away from the geometry it would otherwise clip into.

I’ve tried using the CheckSphere(), and while it does detect that it’s clipping into geometry, there seems to be no way of determining what it’s colliding with, and therefore no easy way of determining the objects direction.

Should I be adding a Sphere collider on the camera? Or make it a RigidBody so the OnCollisionEnter/OnCollisionStay function? The Linecast has the RaycastHit variable which provides info on the object it collided with, including the surface normal. Is there anyway to get that information without using Raycasts? Or is there some combination of Raycasts and CheckSphere calls that will generate the results I’m looking for?

I’ve attached an image for what I’m trying to accomplish (A) versus what I’m currently experiencing (B).

165813--5974--$unity_camera_collision_116.png

Thanks for posting this about implementing the camera positions. It’s helpful because I’m trying to get to know some more about camera positioning and the details as you walked/thought through it are helpful when I get stuck.

Thanks so much for all of this. It’s been a valuable learning experience.

I’ve been trying to make it so that when you push down both mouse buttons at the same time, you move forward in the direction that the character is facing. I did manage to get some movement out of it, but it wasn’t oriented correctly as the player turned. Does anyone know how this would be accomplished?

Here’s what I’ve been working with:

	  if(Input.GetMouseButton(1)  Input.GetMouseButton(0))
   {	  
	forward = transform.TransformDirection(Vector3.forward);
	forward = forward.normalized; 
	moveDirection = forward;
	moveDirection = moveDirection.normalized; 
   }

It moves, just not always the direction that the player is facing. :frowning:

:smile:
favorite~

all these scripts are really interresting, i want to make a Real wow camera too but too hard for the poor developper i am :frowning: so if you’ve any script of that, tell us !!! :smile:

Thank you all for this wonderful script. I’m an artist, not a programmer, and this frees me up to do the work that I want to do. Part of that work requires having a free mouse for the player to interact with the environment by clicking on objects, and now I can concentrate on that.

I am so happy to be part of such a wonderful community of kind, giving people here with Unity. You are all Rock Stars!