1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| using UnityEngine;
using System.Collections;
public class testCam : MonoBehaviour {
public float moveSpeed = 20;
public float lerpSpeed = 20;
public float gravity = 10;
public float jumpRange = 5;
public float jumpSpeed = 5;
public float deltaGround = 0.2f;
private float distGround;
private bool isGrounded = false;
private Vector3 myNormal;
private Camera Pov;
private RaycastHit hit;
private Ray ray;
private Vector3 surfaceNormal;
private bool jumping;
// Use this for initialization
void Start () {
myNormal = Vector3.up; // normal starts as character up direction
rigidbody.freezeRotation = true; // disable physics rotation
distGround = 1;//coll.bounds.extents.y - coll.center.y;
Debug.Log("up " + transform.up);
Pov = transform.FindChild("Camera").gameObject.camera;
}
void FixedUpdate() {
rigidbody.AddForce(-gravity*rigidbody.mass*myNormal);
}
// Update is called once per frame
void Update () {
if (jumping)
return;
if (Input.GetButtonDown("Jump")) { // jump pressed:
hit = new RaycastHit();
ray = Pov.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, jumpRange)) { // wall ahead?
JumpToWall(hit.point, hit.normal); // yes: jump to the wall
} else if (isGrounded) { // no: if grounded, jump up
rigidbody.velocity += jumpSpeed * myNormal;
}
}
// Moving forward and backward
var forwardVector = Pov.transform.forward;
//forwardVector.y = 0;
forwardVector *= Input.GetAxis("Vertical");
transform.Translate(forwardVector*Time.deltaTime*moveSpeed);
// Moving left and right
var lateralVector = Pov.transform.right;
//lateralVector.y = 0;
lateralVector *= Input.GetAxis("Horizontal");
transform.Translate(lateralVector*Time.deltaTime*moveSpeed);
// update surface normal and isGrounded:
ray = new Ray(transform.position, -myNormal); // cast ray downwards
if (Physics.Raycast(ray, out hit)){ // use it to update myNormal and isGrounded
isGrounded = hit.distance <= distGround + deltaGround;
surfaceNormal = hit.normal;
}
else {
isGrounded = false;
// assume usual ground normal to avoid "falling forever"
surfaceNormal = Vector3.up;
}
myNormal = Vector3.Lerp(myNormal, surfaceNormal, lerpSpeed*Time.deltaTime);
Vector3 myForward = Vector3.Cross(transform.right, myNormal);
Quaternion targetRot = Quaternion.LookRotation(myForward, myNormal);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, lerpSpeed*Time.deltaTime);
}
void JumpToWall(Vector3 point, Vector3 normal) {
// jump to wall
jumping = true; // signal it's jumping to wall
rigidbody.isKinematic = true; // disable physics while jumping
Vector3 dstPos = point + normal * (distGround + 0.5f); // will jump to 0.5 above wall
Vector3 myForward = Vector3.Cross(transform.right, normal);
Quaternion dstRot = Quaternion.LookRotation(myForward, normal);
for (float t = 0.0f; t < 1.0f; ){
t += Time.deltaTime;
transform.position = Vector3.Lerp(transform.position, dstPos, t);
transform.rotation = Quaternion.Slerp(transform.rotation, dstRot, t);
//Pov.transform.rotation = transform.rotation;
//Pov.transform.position = transform.position;
}
myNormal = normal; // update myNormal
rigidbody.isKinematic = false; // enable physics
jumping = false; // jumping to wall finished
Debug.Log("up " + transform.up);
}
} |
Partager