What I need is for my character to be aware of the direction he needs to walk in order to climb up/down any slope, without relying on the gravity to pull him down or push up as he keeps trying to walk into the slope horizontally (I need that actual direction for other things). I've made this code which can only move me on the world's X-Z plane, now I need to change the "forward" and "right" variables so that they're adjusted to the surface. I know it has something to do with angles, normals, vectors and quaternions, and it's something VERY simple, but I just can't figure it out :(
I've already added a temporary part of the code that gets the normal of the colliding surface, because I'm sure it's needed for the formula somehow. The code's pretty well commented:
var cam: Transform;
var shadow: Transform;
var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;
//the direction vector for the next move
private var moveDirection = Vector3.zero;
//when hitting something, store the surface's normal
private var hitting: boolean;
private var hitnormal: Vector3.up;
function OnControllerColliderHit (hit : ControllerColliderHit) : void {
hitting=true;
hitnormal=hit.normal;
}
//just adjust the blob shadow to be above you
function Update() {
shadow.position=transform.position;
shadow.position.y+=3;
}
function FixedUpdate() {
//forward vector relative to camera
var forward=cam.TransformDirection(Vector3.forward);
//reset y to walk horizontally, so that camera looking up doesnt matter
forward.y=0;
//normalize to apply speed later
forward=forward.normalized;
//right vector relative to the camera, to strafe
var right=Vector3(forward.z, 0, -forward.x);
//make the player always look forward relatively to the camera
transform.rotation=Quaternion.LookRotation(forward);
//get the player's move controller component
var controller : CharacterController = GetComponent(CharacterController);
//controls when grounded / not flying
if (controller.isGrounded) {
//move along the forward/right plane according to input, with current speed, also avoiding strafe speed by normalizing vector
moveDirection=((Input.GetAxisRaw("Horizontal")*right+Input.GetAxisRaw("Vertical")*forward).normalized)*speed;
//temporary jumping input
if (Input.GetButton ("Jump")) {
hitting=false;
hitnormal=Vector3.up;
//add the jump speed to the vertical part of the move direction
moveDirection.y = jumpSpeed;
}
}
//apply gravity by reducing the vertical part of the move direction by the gravity value with time
moveDirection.y-=gravity*Time.deltaTime;
//apply the actual movement, with time, by using the controller component
controller.Move(moveDirection*Time.deltaTime);
}