using UnityEngine; using System.Collections; public class ZeroGravCC : MonoBehaviour { float moveSpeed = 6; // move speed float turnSpeed = 90; // turning speed (degrees/second) float lerpSpeed = 10; // smoothing speed float gravity = 10; // gravity acceleration bool isGrounded; float deltaGround = 0.2f; // character is grounded up to this distance float jumpSpeed = 10; // vertical jump initial speed float jumpRange = 10; // range to detect target wall private Vector3 surfaceNormal; // current surface normal private Vector3 myNormal; // character normal private float distGround; // distance from character position to ground private bool jumping = false; // flag "I'm jumping to wall" private float vertSpeed = 0; // vertical jump current speed private Rigidbody rb; // private ThirdPersonCharacter thirdPersonScript; void Start(){ myNormal = transform.up; // normal starts as character up direction rb.freezeRotation = true; // disable physics rotation // distance from transform.position to ground distGround = transform.position.y - 0f; rb = gameObject.GetComponent<Rigidbody>(); // thirdPersonScript = gameObject.GetComponent<ThirdPersonCharacter>(); } void FixedUpdate(){ // apply constant weight force according to character normal: rb.AddForce(-gravity*rb.mass*myNormal); } void Update(){ // jump code - jump to wall or simple jump if (jumping) return; // abort Update while jumping to a wall Ray ray; RaycastHit hit; if (Input.GetButtonDown("Jump")){ // jump pressed: if (Physics.Raycast(transform.position, -myNormal, out hit, jumpRange)){ // wall ahead? // JumpToWall(hit.point, hit.normal); // yes: jump to the wall } else if (isGrounded){ // no: if grounded, jump up rb.velocity += jumpSpeed * myNormal; } } // movement code - turn left/right with Horizontal axis: transform.Rotate(0, Input.GetAxis("Horizontal")*turnSpeed*Time.deltaTime, 0); // update surface normal and isGrounded: if (Physics.Raycast(transform.position, -myNormal, out hit, Mathf.Infinity)){ // use it to update myNormal and isGrounded isGrounded = hit.distance <= distGround + deltaGround; surfaceNormal = hit.normal; // thirdPersonScript.newNormal = surfaceNormal; } else { isGrounded = false; // assume usual ground normal to avoid "falling forever" surfaceNormal = Vector3.up; } myNormal = Vector3.Lerp(myNormal, surfaceNormal, lerpSpeed*Time.deltaTime); // find forward direction with new myNormal: var myForward = Vector3.Cross(transform.right, myNormal); // align character to the new myNormal while keeping the forward direction: var targetRot = Quaternion.LookRotation(myForward, myNormal); transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, lerpSpeed*Time.deltaTime); // move the character forth/back with Vertical axis: transform.Translate(0, 0, Input.GetAxis("Vertical")*moveSpeed*Time.deltaTime); } // public void JumpToWall(Vector3 point, Vector3 normal){ // // jump to wall // jumping = true; // signal it's jumping to wall // rb.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 myForward = Vector3.Cross(transform.right, normal); // var dstRot = Quaternion.LookRotation(myForward, normal); // for (float t = 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 // } }