...
This commit is contained in:
@ -0,0 +1,260 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityStandardAssets.CrossPlatformInput;
|
||||
using UnityStandardAssets.Utility;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
#pragma warning disable 618, 649
|
||||
namespace UnityStandardAssets.Characters.FirstPerson
|
||||
{
|
||||
[RequireComponent(typeof (CharacterController))]
|
||||
[RequireComponent(typeof (AudioSource))]
|
||||
public class FirstPersonController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool m_IsWalking;
|
||||
[SerializeField] private float m_WalkSpeed;
|
||||
[SerializeField] private float m_RunSpeed;
|
||||
[SerializeField] [Range(0f, 1f)] private float m_RunstepLenghten;
|
||||
[SerializeField] private float m_JumpSpeed;
|
||||
[SerializeField] private float m_StickToGroundForce;
|
||||
[SerializeField] private float m_GravityMultiplier;
|
||||
[SerializeField] private MouseLook m_MouseLook;
|
||||
[SerializeField] private bool m_UseFovKick;
|
||||
[SerializeField] private FOVKick m_FovKick = new FOVKick();
|
||||
[SerializeField] private bool m_UseHeadBob;
|
||||
[SerializeField] private CurveControlledBob m_HeadBob = new CurveControlledBob();
|
||||
[SerializeField] private LerpControlledBob m_JumpBob = new LerpControlledBob();
|
||||
[SerializeField] private float m_StepInterval;
|
||||
[SerializeField] private AudioClip[] m_FootstepSounds; // an array of footstep sounds that will be randomly selected from.
|
||||
[SerializeField] private AudioClip m_JumpSound; // the sound played when character leaves the ground.
|
||||
[SerializeField] private AudioClip m_LandSound; // the sound played when character touches back on ground.
|
||||
|
||||
private Camera m_Camera;
|
||||
private bool m_Jump;
|
||||
private float m_YRotation;
|
||||
private Vector2 m_Input;
|
||||
private Vector3 m_MoveDir = Vector3.zero;
|
||||
private CharacterController m_CharacterController;
|
||||
private CollisionFlags m_CollisionFlags;
|
||||
private bool m_PreviouslyGrounded;
|
||||
private Vector3 m_OriginalCameraPosition;
|
||||
private float m_StepCycle;
|
||||
private float m_NextStep;
|
||||
private bool m_Jumping;
|
||||
private AudioSource m_AudioSource;
|
||||
|
||||
// Use this for initialization
|
||||
private void Start()
|
||||
{
|
||||
m_CharacterController = GetComponent<CharacterController>();
|
||||
m_Camera = Camera.main;
|
||||
m_OriginalCameraPosition = m_Camera.transform.localPosition;
|
||||
m_FovKick.Setup(m_Camera);
|
||||
m_HeadBob.Setup(m_Camera, m_StepInterval);
|
||||
m_StepCycle = 0f;
|
||||
m_NextStep = m_StepCycle/2f;
|
||||
m_Jumping = false;
|
||||
m_AudioSource = GetComponent<AudioSource>();
|
||||
m_MouseLook.Init(transform , m_Camera.transform);
|
||||
}
|
||||
|
||||
|
||||
// Update is called once per frame
|
||||
private void Update()
|
||||
{
|
||||
RotateView();
|
||||
// the jump state needs to read here to make sure it is not missed
|
||||
if (!m_Jump)
|
||||
{
|
||||
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
|
||||
}
|
||||
|
||||
if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
|
||||
{
|
||||
StartCoroutine(m_JumpBob.DoBobCycle());
|
||||
PlayLandingSound();
|
||||
m_MoveDir.y = 0f;
|
||||
m_Jumping = false;
|
||||
}
|
||||
if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)
|
||||
{
|
||||
m_MoveDir.y = 0f;
|
||||
}
|
||||
|
||||
m_PreviouslyGrounded = m_CharacterController.isGrounded;
|
||||
}
|
||||
|
||||
|
||||
private void PlayLandingSound()
|
||||
{
|
||||
m_AudioSource.clip = m_LandSound;
|
||||
m_AudioSource.Play();
|
||||
m_NextStep = m_StepCycle + .5f;
|
||||
}
|
||||
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
float speed;
|
||||
GetInput(out speed);
|
||||
// always move along the camera forward as it is the direction that it being aimed at
|
||||
Vector3 desiredMove = transform.forward*m_Input.y + transform.right*m_Input.x;
|
||||
|
||||
// get a normal for the surface that is being touched to move along it
|
||||
RaycastHit hitInfo;
|
||||
Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,
|
||||
m_CharacterController.height/2f, Physics.AllLayers, QueryTriggerInteraction.Ignore);
|
||||
desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized;
|
||||
|
||||
m_MoveDir.x = desiredMove.x*speed;
|
||||
m_MoveDir.z = desiredMove.z*speed;
|
||||
|
||||
|
||||
if (m_CharacterController.isGrounded)
|
||||
{
|
||||
m_MoveDir.y = -m_StickToGroundForce;
|
||||
|
||||
if (m_Jump)
|
||||
{
|
||||
m_MoveDir.y = m_JumpSpeed;
|
||||
PlayJumpSound();
|
||||
m_Jump = false;
|
||||
m_Jumping = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MoveDir += Physics.gravity*m_GravityMultiplier*Time.fixedDeltaTime;
|
||||
}
|
||||
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);
|
||||
|
||||
ProgressStepCycle(speed);
|
||||
UpdateCameraPosition(speed);
|
||||
|
||||
m_MouseLook.UpdateCursorLock();
|
||||
}
|
||||
|
||||
|
||||
private void PlayJumpSound()
|
||||
{
|
||||
m_AudioSource.clip = m_JumpSound;
|
||||
m_AudioSource.Play();
|
||||
}
|
||||
|
||||
|
||||
private void ProgressStepCycle(float speed)
|
||||
{
|
||||
if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))
|
||||
{
|
||||
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed*(m_IsWalking ? 1f : m_RunstepLenghten)))*
|
||||
Time.fixedDeltaTime;
|
||||
}
|
||||
|
||||
if (!(m_StepCycle > m_NextStep))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_NextStep = m_StepCycle + m_StepInterval;
|
||||
|
||||
PlayFootStepAudio();
|
||||
}
|
||||
|
||||
|
||||
private void PlayFootStepAudio()
|
||||
{
|
||||
if (!m_CharacterController.isGrounded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// pick & play a random footstep sound from the array,
|
||||
// excluding sound at index 0
|
||||
int n = Random.Range(1, m_FootstepSounds.Length);
|
||||
m_AudioSource.clip = m_FootstepSounds[n];
|
||||
m_AudioSource.PlayOneShot(m_AudioSource.clip);
|
||||
// move picked sound to index 0 so it's not picked next time
|
||||
m_FootstepSounds[n] = m_FootstepSounds[0];
|
||||
m_FootstepSounds[0] = m_AudioSource.clip;
|
||||
}
|
||||
|
||||
|
||||
private void UpdateCameraPosition(float speed)
|
||||
{
|
||||
Vector3 newCameraPosition;
|
||||
if (!m_UseHeadBob)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (m_CharacterController.velocity.magnitude > 0 && m_CharacterController.isGrounded)
|
||||
{
|
||||
m_Camera.transform.localPosition =
|
||||
m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +
|
||||
(speed*(m_IsWalking ? 1f : m_RunstepLenghten)));
|
||||
newCameraPosition = m_Camera.transform.localPosition;
|
||||
newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();
|
||||
}
|
||||
else
|
||||
{
|
||||
newCameraPosition = m_Camera.transform.localPosition;
|
||||
newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();
|
||||
}
|
||||
m_Camera.transform.localPosition = newCameraPosition;
|
||||
}
|
||||
|
||||
|
||||
private void GetInput(out float speed)
|
||||
{
|
||||
// Read input
|
||||
float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");
|
||||
float vertical = CrossPlatformInputManager.GetAxis("Vertical");
|
||||
|
||||
bool waswalking = m_IsWalking;
|
||||
|
||||
#if !MOBILE_INPUT
|
||||
// On standalone builds, walk/run speed is modified by a key press.
|
||||
// keep track of whether or not the character is walking or running
|
||||
m_IsWalking = !Input.GetKey(KeyCode.LeftShift);
|
||||
#endif
|
||||
// set the desired speed to be walking or running
|
||||
speed = m_IsWalking ? m_WalkSpeed : m_RunSpeed;
|
||||
m_Input = new Vector2(horizontal, vertical);
|
||||
|
||||
// normalize input if it exceeds 1 in combined length:
|
||||
if (m_Input.sqrMagnitude > 1)
|
||||
{
|
||||
m_Input.Normalize();
|
||||
}
|
||||
|
||||
// handle speed change to give an fov kick
|
||||
// only if the player is going to a run, is running and the fovkick is to be used
|
||||
if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude > 0)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RotateView()
|
||||
{
|
||||
m_MouseLook.LookRotation (transform, m_Camera.transform);
|
||||
}
|
||||
|
||||
|
||||
private void OnControllerColliderHit(ControllerColliderHit hit)
|
||||
{
|
||||
Rigidbody body = hit.collider.attachedRigidbody;
|
||||
//dont move the rigidbody if the character is on top of it
|
||||
if (m_CollisionFlags == CollisionFlags.Below)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (body == null || body.isKinematic)
|
||||
{
|
||||
return;
|
||||
}
|
||||
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
|
||||
}
|
||||
}
|
||||
}
|
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs.meta
generated
Normal file
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs.meta
generated
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05ec5cf00ca181d45a42ba1870e148c3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityStandardAssets.Utility;
|
||||
|
||||
namespace UnityStandardAssets.Characters.FirstPerson
|
||||
{
|
||||
public class HeadBob : MonoBehaviour
|
||||
{
|
||||
public Camera Camera;
|
||||
public CurveControlledBob motionBob = new CurveControlledBob();
|
||||
public LerpControlledBob jumpAndLandingBob = new LerpControlledBob();
|
||||
public RigidbodyFirstPersonController rigidbodyFirstPersonController;
|
||||
public float StrideInterval;
|
||||
[Range(0f, 1f)] public float RunningStrideLengthen;
|
||||
|
||||
// private CameraRefocus m_CameraRefocus;
|
||||
private bool m_PreviouslyGrounded;
|
||||
private Vector3 m_OriginalCameraPosition;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
motionBob.Setup(Camera, StrideInterval);
|
||||
m_OriginalCameraPosition = Camera.transform.localPosition;
|
||||
// m_CameraRefocus = new CameraRefocus(Camera, transform.root.transform, Camera.transform.localPosition);
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// m_CameraRefocus.GetFocusPoint();
|
||||
Vector3 newCameraPosition;
|
||||
if (rigidbodyFirstPersonController.Velocity.magnitude > 0 && rigidbodyFirstPersonController.Grounded)
|
||||
{
|
||||
Camera.transform.localPosition = motionBob.DoHeadBob(rigidbodyFirstPersonController.Velocity.magnitude*(rigidbodyFirstPersonController.Running ? RunningStrideLengthen : 1f));
|
||||
newCameraPosition = Camera.transform.localPosition;
|
||||
newCameraPosition.y = Camera.transform.localPosition.y - jumpAndLandingBob.Offset();
|
||||
}
|
||||
else
|
||||
{
|
||||
newCameraPosition = Camera.transform.localPosition;
|
||||
newCameraPosition.y = m_OriginalCameraPosition.y - jumpAndLandingBob.Offset();
|
||||
}
|
||||
Camera.transform.localPosition = newCameraPosition;
|
||||
|
||||
if (!m_PreviouslyGrounded && rigidbodyFirstPersonController.Grounded)
|
||||
{
|
||||
StartCoroutine(jumpAndLandingBob.DoBobCycle());
|
||||
}
|
||||
|
||||
m_PreviouslyGrounded = rigidbodyFirstPersonController.Grounded;
|
||||
// m_CameraRefocus.SetFocusPoint();
|
||||
}
|
||||
}
|
||||
}
|
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/HeadBob.cs.meta
generated
Normal file
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/HeadBob.cs.meta
generated
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83c81407209f85e4c87c0cda8b32868e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityStandardAssets.CrossPlatformInput;
|
||||
|
||||
namespace UnityStandardAssets.Characters.FirstPerson
|
||||
{
|
||||
[Serializable]
|
||||
public class MouseLook
|
||||
{
|
||||
public float XSensitivity = 2f;
|
||||
public float YSensitivity = 2f;
|
||||
public bool clampVerticalRotation = true;
|
||||
public float MinimumX = -90F;
|
||||
public float MaximumX = 90F;
|
||||
public bool smooth;
|
||||
public float smoothTime = 5f;
|
||||
public bool lockCursor = true;
|
||||
|
||||
|
||||
private Quaternion m_CharacterTargetRot;
|
||||
private Quaternion m_CameraTargetRot;
|
||||
private bool m_cursorIsLocked = true;
|
||||
|
||||
public void Init(Transform character, Transform camera)
|
||||
{
|
||||
m_CharacterTargetRot = character.localRotation;
|
||||
m_CameraTargetRot = camera.localRotation;
|
||||
}
|
||||
|
||||
|
||||
public void LookRotation(Transform character, Transform camera)
|
||||
{
|
||||
float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
|
||||
float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;
|
||||
|
||||
m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
|
||||
m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);
|
||||
|
||||
if(clampVerticalRotation)
|
||||
m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);
|
||||
|
||||
if(smooth)
|
||||
{
|
||||
character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,
|
||||
smoothTime * Time.deltaTime);
|
||||
camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,
|
||||
smoothTime * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
character.localRotation = m_CharacterTargetRot;
|
||||
camera.localRotation = m_CameraTargetRot;
|
||||
}
|
||||
|
||||
UpdateCursorLock();
|
||||
}
|
||||
|
||||
public void SetCursorLock(bool value)
|
||||
{
|
||||
lockCursor = value;
|
||||
if(!lockCursor)
|
||||
{//we force unlock the cursor if the user disable the cursor locking helper
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCursorLock()
|
||||
{
|
||||
//if the user set "lockCursor" we check & properly lock the cursos
|
||||
if (lockCursor)
|
||||
InternalLockUpdate();
|
||||
}
|
||||
|
||||
private void InternalLockUpdate()
|
||||
{
|
||||
if(Input.GetKeyUp(KeyCode.Escape))
|
||||
{
|
||||
m_cursorIsLocked = false;
|
||||
}
|
||||
else if(Input.GetMouseButtonUp(0))
|
||||
{
|
||||
m_cursorIsLocked = true;
|
||||
}
|
||||
|
||||
if (m_cursorIsLocked)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Locked;
|
||||
Cursor.visible = false;
|
||||
}
|
||||
else if (!m_cursorIsLocked)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
Cursor.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Quaternion ClampRotationAroundXAxis(Quaternion q)
|
||||
{
|
||||
q.x /= q.w;
|
||||
q.y /= q.w;
|
||||
q.z /= q.w;
|
||||
q.w = 1.0f;
|
||||
|
||||
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);
|
||||
|
||||
angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);
|
||||
|
||||
q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/MouseLook.cs.meta
generated
Normal file
9
Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/MouseLook.cs.meta
generated
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37e60a97f2c87ae41b6cdc1055d78cb9
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityStandardAssets.CrossPlatformInput;
|
||||
|
||||
namespace UnityStandardAssets.Characters.FirstPerson
|
||||
{
|
||||
[RequireComponent(typeof (Rigidbody))]
|
||||
[RequireComponent(typeof (CapsuleCollider))]
|
||||
public class RigidbodyFirstPersonController : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public class MovementSettings
|
||||
{
|
||||
public float ForwardSpeed = 8.0f; // Speed when walking forward
|
||||
public float BackwardSpeed = 4.0f; // Speed when walking backwards
|
||||
public float StrafeSpeed = 4.0f; // Speed when walking sideways
|
||||
public float RunMultiplier = 2.0f; // Speed when sprinting
|
||||
public KeyCode RunKey = KeyCode.LeftShift;
|
||||
public float JumpForce = 30f;
|
||||
public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
|
||||
[HideInInspector] public float CurrentTargetSpeed = 8f;
|
||||
|
||||
#if !MOBILE_INPUT
|
||||
private bool m_Running;
|
||||
#endif
|
||||
|
||||
public void UpdateDesiredTargetSpeed(Vector2 input)
|
||||
{
|
||||
if (input == Vector2.zero) return;
|
||||
if (input.x > 0 || input.x < 0)
|
||||
{
|
||||
//strafe
|
||||
CurrentTargetSpeed = StrafeSpeed;
|
||||
}
|
||||
if (input.y < 0)
|
||||
{
|
||||
//backwards
|
||||
CurrentTargetSpeed = BackwardSpeed;
|
||||
}
|
||||
if (input.y > 0)
|
||||
{
|
||||
//forwards
|
||||
//handled last as if strafing and moving forward at the same time forwards speed should take precedence
|
||||
CurrentTargetSpeed = ForwardSpeed;
|
||||
}
|
||||
#if !MOBILE_INPUT
|
||||
if (Input.GetKey(RunKey))
|
||||
{
|
||||
CurrentTargetSpeed *= RunMultiplier;
|
||||
m_Running = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Running = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !MOBILE_INPUT
|
||||
public bool Running
|
||||
{
|
||||
get { return m_Running; }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class AdvancedSettings
|
||||
{
|
||||
public float groundCheckDistance = 0.01f; // distance for checking if the controller is grounded ( 0.01f seems to work best for this )
|
||||
public float stickToGroundHelperDistance = 0.5f; // stops the character
|
||||
public float slowDownRate = 20f; // rate at which the controller comes to a stop when there is no input
|
||||
public bool airControl; // can the user control the direction that is being moved in the air
|
||||
[Tooltip("set it to 0.1 or more if you get stuck in wall")]
|
||||
public float shellOffset; //reduce the radius by that ratio to avoid getting stuck in wall (a value of 0.1f is nice)
|
||||
}
|
||||
|
||||
|
||||
public Camera cam;
|
||||
public MovementSettings movementSettings = new MovementSettings();
|
||||
public MouseLook mouseLook = new MouseLook();
|
||||
public AdvancedSettings advancedSettings = new AdvancedSettings();
|
||||
|
||||
|
||||
private Rigidbody m_RigidBody;
|
||||
private CapsuleCollider m_Capsule;
|
||||
private float m_YRotation;
|
||||
private Vector3 m_GroundContactNormal;
|
||||
private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsGrounded;
|
||||
|
||||
|
||||
public Vector3 Velocity
|
||||
{
|
||||
get { return m_RigidBody.velocity; }
|
||||
}
|
||||
|
||||
public bool Grounded
|
||||
{
|
||||
get { return m_IsGrounded; }
|
||||
}
|
||||
|
||||
public bool Jumping
|
||||
{
|
||||
get { return m_Jumping; }
|
||||
}
|
||||
|
||||
public bool Running
|
||||
{
|
||||
get
|
||||
{
|
||||
#if !MOBILE_INPUT
|
||||
return movementSettings.Running;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_RigidBody = GetComponent<Rigidbody>();
|
||||
m_Capsule = GetComponent<CapsuleCollider>();
|
||||
mouseLook.Init (transform, cam.transform);
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
RotateView();
|
||||
|
||||
if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
|
||||
{
|
||||
m_Jump = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
GroundCheck();
|
||||
Vector2 input = GetInput();
|
||||
|
||||
if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
|
||||
{
|
||||
// always move along the camera forward as it is the direction that it being aimed at
|
||||
Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
|
||||
desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;
|
||||
|
||||
desiredMove.x = desiredMove.x*movementSettings.CurrentTargetSpeed;
|
||||
desiredMove.z = desiredMove.z*movementSettings.CurrentTargetSpeed;
|
||||
desiredMove.y = desiredMove.y*movementSettings.CurrentTargetSpeed;
|
||||
if (m_RigidBody.velocity.sqrMagnitude <
|
||||
(movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
|
||||
{
|
||||
m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IsGrounded)
|
||||
{
|
||||
m_RigidBody.drag = 5f;
|
||||
|
||||
if (m_Jump)
|
||||
{
|
||||
m_RigidBody.drag = 0f;
|
||||
m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
|
||||
m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
|
||||
m_Jumping = true;
|
||||
}
|
||||
|
||||
if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
|
||||
{
|
||||
m_RigidBody.Sleep();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RigidBody.drag = 0f;
|
||||
if (m_PreviouslyGrounded && !m_Jumping)
|
||||
{
|
||||
StickToGroundHelper();
|
||||
}
|
||||
}
|
||||
m_Jump = false;
|
||||
}
|
||||
|
||||
|
||||
private float SlopeMultiplier()
|
||||
{
|
||||
float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
|
||||
return movementSettings.SlopeCurveModifier.Evaluate(angle);
|
||||
}
|
||||
|
||||
|
||||
private void StickToGroundHelper()
|
||||
{
|
||||
RaycastHit hitInfo;
|
||||
if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
|
||||
((m_Capsule.height/2f) - m_Capsule.radius) +
|
||||
advancedSettings.stickToGroundHelperDistance, Physics.AllLayers, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f)
|
||||
{
|
||||
m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Vector2 GetInput()
|
||||
{
|
||||
|
||||
Vector2 input = new Vector2
|
||||
{
|
||||
x = CrossPlatformInputManager.GetAxis("Horizontal"),
|
||||
y = CrossPlatformInputManager.GetAxis("Vertical")
|
||||
};
|
||||
movementSettings.UpdateDesiredTargetSpeed(input);
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
private void RotateView()
|
||||
{
|
||||
//avoids the mouse looking if the game is effectively paused
|
||||
if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;
|
||||
|
||||
// get the rotation before it's changed
|
||||
float oldYRotation = transform.eulerAngles.y;
|
||||
|
||||
mouseLook.LookRotation (transform, cam.transform);
|
||||
|
||||
if (m_IsGrounded || advancedSettings.airControl)
|
||||
{
|
||||
// Rotate the rigidbody velocity to match the new direction that the character is looking
|
||||
Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
|
||||
m_RigidBody.velocity = velRotation*m_RigidBody.velocity;
|
||||
}
|
||||
}
|
||||
|
||||
/// sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
|
||||
private void GroundCheck()
|
||||
{
|
||||
m_PreviouslyGrounded = m_IsGrounded;
|
||||
RaycastHit hitInfo;
|
||||
if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
|
||||
((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance, Physics.AllLayers, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
m_IsGrounded = true;
|
||||
m_GroundContactNormal = hitInfo.normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IsGrounded = false;
|
||||
m_GroundContactNormal = Vector3.up;
|
||||
}
|
||||
if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
|
||||
{
|
||||
m_Jumping = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81c9795a96c094f4cbde4d65546aa9b2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
Reference in New Issue
Block a user