- Home /
Simulating magnetic shoes?
I'm using a script to simulate walking in magnetic shoes on a spaceship, so I can walk on any surface:
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 {
var turn = Input.GetAxis("Mouse X") * turnSpeed * Time.deltaTime; turnAngle = (turnAngle + turn) % 360;
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.x = Input.GetAxis("Horizontal") * moveSpeed;
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
}
There a few problems I need to fix with this script:
when I go off a sharp angle, I keep falling in the direction of my last surface, instead of floating in space, I was trying to find some way to transform the "jump to surface" into "attach to nearest surface".
The rotation when standing in between each surface is spazzy, even in the tubular hallway inside the ship.
Sometimes I end up going through the walls.
if nothing else, I just want to be able to walk on all the surfaces smoothly, I don't need to jump.
Your answer
![](https://koobas.hobune.stream/wayback/20220613073752im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Move along surface normal of hollowed pipe with cube 0 Answers
Custom Gravity 1 Answer
how can I align player with slope normals(no rigidbody) 0 Answers
Normal Walker: Player Y Rotation Snapping back to 0? 0 Answers
My characters in Unity float slightly above my ground I imported and made in Blender 0 Answers