Last active
October 4, 2019 10:20
-
-
Save verborghs/39a845c6b4772863f8478970ed8531ed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
public class PlayerBehaviour : MonoBehaviour | |
{ | |
public float Speed; | |
public float JumpHeight; | |
public float MaxSlope; | |
public float DynamicFriction; | |
private CharacterController _controller; | |
void Start() | |
{ | |
_controller = GetComponent<CharacterController>(); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
var velocity = _controller.velocity; | |
var camera = Camera.main; | |
//Determine the player surface | |
var groundNormal = Vector3.up; | |
var groundPoint = Vector3.zero; | |
var characterCenter = transform.position + _controller.center; | |
var characterRayCastHeight = _controller.height / 2 + _controller.skinWidth * 2; | |
var groundLayer = LayerMask.GetMask("Walkable"); | |
float radius = _controller.radius * 0.99f; | |
//determine point of floor contact | |
RaycastHit hitInfo; | |
var groundPointRay = new Ray(characterCenter, Vector3.down); | |
if (Physics.SphereCast(groundPointRay, radius, out hitInfo, characterRayCastHeight, groundLayer)) | |
{ | |
groundPoint = hitInfo.point; | |
} | |
//determine orientation of surface at floor contact | |
var groundNormalRay = new Ray(new Vector3(groundPoint.x, characterCenter.y, groundPoint.z), Vector3.down); | |
if (Physics.Raycast(groundNormalRay, out hitInfo, characterRayCastHeight)) | |
{ | |
groundNormal = hitInfo.normal; | |
} | |
//determine camera forward and right in xz-plane | |
Vector3 cameraForward = Vector3.Scale(camera.transform.forward, new Vector3(1, 0, 1)).normalized; | |
Vector3 cameraRight = Vector3.Scale(camera.transform.right, new Vector3(1, 0, 1)).normalized; | |
//get right stick input | |
float horizontalRight = UnityEngine.Input.GetAxis("RightStick_Horizontal"); | |
float verticalRight = UnityEngine.Input.GetAxis("RightStick_Vertical"); | |
//calculate the player orientation | |
Vector2 directionRight = new Vector2(horizontalRight, verticalRight); | |
directionRight = directionRight.sqrMagnitude > 2 ? directionRight.normalized : directionRight; | |
Vector3 worldDirectionRight = cameraRight * directionRight.x + cameraForward * directionRight.y; | |
if (!Mathf.Approximately(worldDirectionRight.sqrMagnitude, 0.0f)) | |
{ | |
Quaternion worldOrientation = Quaternion.LookRotation(worldDirectionRight, Vector3.up); | |
//rotate the player | |
transform.rotation = worldOrientation; | |
} | |
//gravity | |
velocity += Physics.gravity * Time.deltaTime; | |
//get left stick input | |
float horizontalLeft = UnityEngine.Input.GetAxis("LeftStick_Horizontal"); | |
float verticalLeft = UnityEngine.Input.GetAxis("LeftStick_Vertical"); | |
// calculate the player movement direction | |
Vector2 directionLeft = new Vector2(horizontalLeft, verticalLeft); | |
directionLeft = directionLeft.sqrMagnitude > 2 ? directionLeft.normalized : directionLeft; | |
Vector3 worldDirection = cameraRight * directionLeft.x + cameraForward * directionLeft.y; | |
if (_controller.isGrounded) | |
{ | |
//only keep vertical velocity | |
velocity = Vector3.Scale(velocity, new Vector3(0, 1, 0)); | |
//transform velocity into pure velocity along plane. | |
velocity = Vector3.ProjectOnPlane(velocity, groundNormal); | |
//calculate ground orientation | |
Vector3 groundTangent = worldDirection; | |
Vector3.OrthoNormalize(ref groundNormal, ref groundTangent); | |
Debug.Log(groundTangent); | |
Debug.Log(velocity.ToString("0.0000")); | |
//add movement to velocity | |
velocity += groundTangent * worldDirection.magnitude * Speed; | |
//jump | |
if (Input.GetButtonDown("A")) | |
{ | |
//jump impulse | |
velocity = new Vector3( | |
velocity.x, | |
Mathf.Sqrt(2 * Physics.gravity.magnitude * JumpHeight), | |
velocity.z); | |
} | |
else | |
{ | |
//interact | |
if (Input.GetButtonDown("B")) | |
{ | |
var halfExtents = new Vector3(_controller.radius * 0.5f, | |
_controller.height / 2.0f, _controller.radius * 1.0f); | |
var forwardOffset = transform.forward * halfExtents.x; | |
var upOffset = transform.up * halfExtents.y; | |
var interactiveCenter = transform.position + forwardOffset + upOffset; | |
var interactiveLayer = LayerMask.GetMask("Interactive"); | |
var interactives = | |
Physics.OverlapBox(interactiveCenter, halfExtents, transform.rotation, interactiveLayer); | |
if (interactives.Length > 0 ) | |
{ | |
var physics = interactives[0].GetComponentInParent<Rigidbody>(); | |
Vector3 direction = interactives[0].transform.position - transform.position; | |
direction.y = 0; | |
physics.AddForce(direction * 8.0f, ForceMode.Impulse); | |
} | |
} | |
} | |
} | |
_controller.Move(velocity * Time.deltaTime); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment