Skip to content
Snippets Groups Projects
ZeroGravCC.cs 3.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • kgingras's avatar
    kgingras committed
    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
    //	}
    }