walking on the wall

Hi, for my game, I wanted to create some very strange training level where you can manipulate the gravity by clicking on a wall. When doing this, every rigidbody object (including the player) should be pulled in the direction of this wall until the player clicks on another place in space… When jumping, you should turn 180° around the x-axis and the gravity should be inverted…

It’s not working like I want it, so I ask if anybody could help me there…
This is the player script, the click-and-change-gravity-function isn’t included (because I haven’t had the time to write it yet), but if you could help me there too, that’d be very nice…

var speed = 10.0;
var maxVelocityChange = 10.0;
var canJump = true;
var jumpHeight = 2.0;
private var grounded = false;
var globalGravi : Quaternion;
var gravity : Vector3;
private var toWall : boolean = false;
private var rot = 0.0;

@script RequireComponent(Rigidbody)

function Awake ()
{
	rigidbody.freezeRotation = true;
}

function FixedUpdate ()
{
	if (grounded)
	{
		// Calculate how fast we should be moving
		var targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		targetVelocity = transform.TransformDirection(targetVelocity);
		targetVelocity *= speed;
		
		// Apply a force that attempts to reach our target velocity
		var velocity = rigidbody.velocity;
		var velocityChange = (targetVelocity - velocity);
		velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
		velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
		velocityChange.y = 0;
		rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
	
		// Jump
		if (canJump  Input.GetButton("Jump"))
		{
			var gravi = gravity.x+gravity.y+gravity.z;
			rigidbody.velocity += transform.up * (2 * jumpHeight * -gravi);
		}
	}
	if (toWall == true) {
		transform.rotation.x = Mathf.Lerp(transform.rotation.x,-rot,Time.deltaTime);
		if (transform.rotation.x == -rot) {
			toWall = false;
		}
	}
	if (canJump  Input.GetButtonDown("Jump"))
	{
		rot = transform.rotation.x;
		gravity = -gravity;
		toWall = true;
	}

	// We apply gravity manually for more tuning control
	rigidbody.AddForce(gravity);
	if (toWall == false) {
		transform.rotation = Quaternion.Slerp(transform.rotation,globalGravi,Time.time);
	}
	
	grounded = false;
}

function OnCollisionStay ()
{
	grounded = true;	
}

It’s the modified rigidbodyfirstpersoncontroller code, simly attach it to a gameObject with a caplsule collider, mouse look and rigidbody (maybe also a camera) and test it in a level with a ceiling, so you don’t fly away when pushing Space…

You can actually change the value of Physics.gravity. Maybe you could point gravity in the direction of a wall when it gets clicked.

I tried that, but than, I have to rotate the character which causes serious problems with mouselook.cs and my controller scripts… :?
I already wrote a code for simply rotating the level when clicking on a wall, but than the player sometimes falls out of the level or slides through walls…

That’s a pretty good way to handle something like this. You’re definitely sure you’ve got the necessary colliders on all the walls?

Yes, every wall has a simple box collider, but the level rotates using lerp, with transform.Rotate or rigidbody.angularVelocity this problem wouldn’t show up, but then it doesn’t rotates around the player’s position too, and I would have to write some very complecated script to prevent the level from rotating to the wrong direction or it wouldn’t stop turning…