Walking On Walls With Mouselook!

Hi! I just started using unity recently and I already figured out how to do a few simple things. My problem is as follows: I would like a script that would make the character be able to walk on walls (in other words, change gravity to the opposite of the character’s normal) all while being able to use mouselook as well. I found this code, which looks and works great, except for the fact that the “a” and “d” keyes turn the character instead of making it sidestep. Any help would be appreciated! Here’s the code I found earlier. Thanks in advance! :smiley: By the way, the script is added to an empty which has rigid body and a box collider.

var moveSpeed: float = 8; // move speed
var turnSpeed: float = 90; // turning speed (degrees)
var gravity: float = 10; // character gravity
var isGrounded: boolean;
var deltaGround: float = 0.2; // character is grounded up to this distance
var jumpSpeed: float = 10; // vertical jump initial speed
var jumpRange: float = 10; // range to detect target wall

private var myNormal: Vector3; // character normal
private var turnAngle: float = 0; // current character direction
private var distGround: float; // distance from character position to ground
private var jumping = false; // flag "I'm jumping to wall"
private var vertSpeed: float = 0; // vertical jump current speed 

function Start(){

	myNormal = transform.up; // starting character normal 
	rigidbody.freezeRotation = true; // disable physics rotation
	// distance from transform.position to ground
	distGround = collider.size.y / 2 - collider.center.y;  
}

function FixedUpdate(){
	// apply constant weight force
	rigidbody.AddForce(-gravity * myNormal);
}

function Update(){

	var ray: Ray;
	var hit: RaycastHit;

	if (!jumping){ // does nothing while jumping to wall
		if (Input.GetButtonDown("Jump")){ // jump pressed:
			ray = Ray(transform.position, transform.forward);
			if (Physics.Raycast(ray, hit, jumpRange)){ // wall ahead?
				JumpToWall(hit.point, hit.normal); // yes: jump to the wall
			}
			else if (isGrounded){ // no: if grounded, jump up
				vertSpeed = jumpSpeed;
			}				
		}
		else {
			var turn = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
			turnAngle = (turnAngle + turn) % 360; // update character direction 
			ray = Ray(transform.position, -myNormal); // cast ray downwards
			if (Physics.Raycast(ray, hit)){ // use it to update myNormal and isGrounded
				isGrounded = hit.distance <= distGround + deltaGround;
				myNormal = Vector3.Lerp(myNormal, hit.normal, Time.deltaTime);
			}
			else {
				isGrounded = false;
			}
			// rotate character to myNormal...
			var rot = Quaternion.FromToRotation(Vector3.up, myNormal);
			rot *= Quaternion.Euler(0,turnAngle,0); // and to current direction
			transform.rotation = rot;
			var move = Input.GetAxis("Vertical") * moveSpeed * Vector3.forward;
			move.y = vertSpeed; // include jump speed, if any
			transform.Translate(move * Time.deltaTime, Space.Self); // move the character
			vertSpeed -= gravity * Time.deltaTime; // apply gravity to jump, if any
			if (vertSpeed < 0) vertSpeed = 0; // clamp to zero
		}			
	}
}

function JumpToWall(point: Vector3, normal: Vector3){
	// jump to wall 
	jumping = true; // signal it's jumping to wall
	rigidbody.isKinematic = true; // disable physics while jumping
	var orgPos = transform.position;
	var orgRot = transform.rotation;
	var dstPos = point + normal * (distGround + 0.5); // will jump to 0.5 above wall
	var dir = dstPos - orgPos;
	var dstRot = Quaternion.FromToRotation(Vector3.up, normal);
	dstRot *= Quaternion.Euler(0, turnAngle, 0); // keep character direction
	for (var t: float = 0.0; t < 1.0; ){
		t += Time.deltaTime;
		transform.position = Vector3.Lerp(orgPos, dstPos, t);
		transform.rotation = Quaternion.Slerp(orgRot, dstRot, t);
		yield; // return here next frame
	}
	myNormal = normal; // update myNormal
	rigidbody.isKinematic = false; // enable physics
	jumping = false; // jumping to wall finished
}

Alright.

First, to disable rotation with the a and d keys, find these lines and comment them out:

var turn = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
turnAngle = (turnAngle + turn) % 360; // update character direction

Now, to make it so that you strafe, find this line:

var move = Input.GetAxis("Vertical") * moveSpeed * Vector3.forward;

And under it add:

move.x = Input.GetAxix("Horizontal") * moveSpeed;

That should work. If you are strafing, but in opposite directions, add a “*-1” to the end of that line. If you are moving backwards and forwards (which shouldn’t happen, but hey), change “move.x” to “move.z”.

Thanks it worked great! I didn’t realize it could have been something as small as one name but hey, that’s code for you! :smiley:

TheTimeLord.

Is there any way you could share the completed script set from this? I can not find a MouseLook that doesn’t freak out once you shift native y rot.

Thank you !!!