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! 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
}