Skip to content

Instantly share code, notes, and snippets.

@314pies
Created August 31, 2018 12:58
Show Gist options
  • Save 314pies/b5f4380f9949b03b8302e69490f10fd1 to your computer and use it in GitHub Desktop.
Save 314pies/b5f4380f9949b03b8302e69490f10fd1 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using LWWeaponSystem;
using LWNet;
using LWControl;
namespace LWCharacterSystem.Player
{
[RequireComponent(typeof(AudioSource))]
public class LWCharacterController : MonoBehaviour
{
LWView view;
/// <summary>
/// Currnent movement on flat 2D
/// </summary>
[HideInInspector]
public MovementPad movementInput = MovementPad.Empty;
public MovementPad CurrentMovement { get { return currentMovement; } }
private MovementPad currentMovement;
/// <summary>
/// The X rotation of the character
/// </summary>
public Transform RotationX;
/// <summary>
/// The Y rotation of the character
/// </summary>
public Transform RotationY;
/// <summary>
/// The character walk speed
/// </summary>
[SerializeField]
private float walkspeed = 5;
/// <summary>
/// IF walk speed = 1
/// </summary>
private const float HalfewalkSpeed = 0.707f;
/// <summary>
/// The Character run speed
/// </summary>
[SerializeField]
private float runspeed;
/// <summary>
/// Weapon manager for playing first person anim....etc
/// </summary>
private WeaponManager weaponManager;
/// <summary>
/// The initial jump speed
/// </summary>
public float JumpSpeed = 6;
/// <summary>
/// Double Jump Speed
/// </summary>
public float DoubleJumpSpeed = 9.0f;
public JumpingStatus JumpStatus { get { return jumpStatus; } }
/// <summary>
/// Player jumping status
/// </summary>
private JumpingStatus jumpStatus = JumpingStatus.Idle;
/// <summary>
/// The first person view run animation speed
/// </summary>
public float FPVRunAnimSpeed = 1.2f;
/// <summary>
/// The first person view of walk anim speed
/// </summary>
public float FPVWalkAnimSpeed = 1.1f;
/// <summary>
/// Will effect player's falling speed
/// </summary>
public float gravity = 15.0f;
/// <summary>
/// Apply gravity?
/// </summary>
public bool ApplyGravity = true;
/// <summary>
/// controller
/// </summary>
private CharacterController controller;
void Awake()
{
view = GetComponent<LWView>();
controller = GetComponent<CharacterController>();
weaponManager = GetComponent<WeaponManager>();
audioSource = gameObject.AddComponent<AudioSource>();
characterBehavior = GetComponent<CharacterBehavior>();
CharacterPhysic = GetComponent<Rigidbody>();
CharacterPhysic.isKinematic = true;
PhysicsCollider = GetComponent<CapsuleCollider>();
PhysicsCollider.enabled = false;
}
private Vector3 movingDir = Vector3.zero;
public bool IsPlayerGrounded
{
get
{
return isPlayerGrounded;
}
}
/// <summary>
/// Set this character position
/// </summary>
public void SetPosition(Vector3 position)
{
bool _originEnableSate = this.enabled;
this.enabled = false;
transform.position = position;
this.enabled = _originEnableSate;
}
/*
/// <summary>
/// Set this character position and rotation
/// </summary>
public void SetPosAndRot(Vector3 position, Vector3 rotation){
bool _originEnableSate = this.enabled;
this.enabled = false;
transform.position = position;
transform.eulerAngles = new Vector3(transform.eulerAngles.x,rotation.y,transform.eulerAngles.z);
RotationY.eulerAngles = new Vector3(Mathf.Clamp(rotation.x,-90,80) , RotationY.eulerAngles.y, RotationY.eulerAngles.z);
this.enabled = _originEnableSate;
}
/// <summary>
/// Set this character position and rotation using the pass through transform
/// </summary>
public void SetPosAndRot(Transform targetTransform){
SetPosAndRot(targetTransform.position, targetTransform.eulerAngles);
}
*/
/// <summary>
/// since its <see cref="GetPlayerGroundedStatus"/> already been invoked every frame, why not cache it?
/// </summary>
private bool isPlayerGrounded = false;
private bool isAiming = false;
void Update()
{
FPVMechanicAnimType fpvAnimType = FPVMechanicAnimType.Idle;
if (controller.isGrounded)
{
movingDir.y = 0;
jumpingQuota = JumpingQuota;
jumpCount = 0;
}
isPlayerGrounded = GetPlayerGroundedStatus();
isAiming = WeaponManager.Singleton.IsAiming;
if (ControlManager.Singleton.ControlSwitches.Movement)
{
if (isPlayerGrounded && !isAiming)
{
fpvAnimType = FPVMechanicAnimType.Walk;
}
if (movementInput == MovementPad.WalkFoward)
{
movingDir.x = 0;
movingDir.z = 1;
currentMovement = MovementPad.WalkFoward;
}
else if (movementInput == MovementPad.WalkFowardRight)
{
movingDir.x = HalfewalkSpeed;
movingDir.z = HalfewalkSpeed;
currentMovement = MovementPad.WalkFowardRight;
}
else if (movementInput == MovementPad.WalkRight)
{
movingDir.x = 1;
movingDir.z = 0;
currentMovement = MovementPad.WalkRight;
}
else if (movementInput == MovementPad.WalkRightBackward)
{
movingDir.x = HalfewalkSpeed;
movingDir.z = -HalfewalkSpeed;
currentMovement = MovementPad.WalkRightBackward;
}
else if (movementInput == MovementPad.WalkBackward)
{
movingDir.x = 0;
movingDir.z = -1;
currentMovement = MovementPad.WalkBackward;
}
else if (movementInput == MovementPad.WalkBackwardLeft)
{
movingDir.x = -1;
movingDir.z = -1;
currentMovement = MovementPad.WalkBackwardLeft;
}
else if (movementInput == MovementPad.WalkLeft)
{
movingDir.x = -1;
movingDir.z = 0;
currentMovement = MovementPad.WalkLeft;
}
else if (movementInput == MovementPad.WalkLeftFoward)
{
movingDir.x = -HalfewalkSpeed;
movingDir.z = HalfewalkSpeed;
currentMovement = MovementPad.WalkLeftFoward;
}
else if (movementInput == MovementPad.Sprint)//Sprinting
{
movingDir.x = 0;
movingDir.z = 1;
}
else if (movementInput == MovementPad.Empty)
{
movingDir.x = 0;
movingDir.z = 0;
fpvAnimType = FPVMechanicAnimType.Idle;
currentMovement = MovementPad.Empty;
}
if (movementInput != MovementPad.Sprint)
{
movingDir.x *= walkspeed;
movingDir.z *= walkspeed;
}
else//sprint
{
if (isPlayerGrounded)
{
if (isAiming)
{
fpvAnimType = FPVMechanicAnimType.Idle;
movingDir.x *= walkspeed;
movingDir.z *= walkspeed;
currentMovement = MovementPad.WalkFoward;
}
else if (WeaponManager.Singleton.IsFireButtonPressed)
{
fpvAnimType = FPVMechanicAnimType.Walk;
movingDir.x *= walkspeed;
movingDir.z *= walkspeed;
currentMovement = MovementPad.WalkFoward;
}
else if (WeaponManager.Singleton.ActiveWeaponStatus == WeaponStatus.Reloading)
{
fpvAnimType = FPVMechanicAnimType.Walk;
movingDir.x *= walkspeed;
movingDir.z *= walkspeed;
currentMovement = MovementPad.WalkFoward;
}
else//Normap run
{
fpvAnimType = FPVMechanicAnimType.Run;
movingDir.x *= runspeed;
movingDir.z *= runspeed;
currentMovement = MovementPad.Sprint;
}
}
else//Normap run
{
fpvAnimType = FPVMechanicAnimType.Idle;
movingDir.x *= runspeed;
movingDir.z *= runspeed;
currentMovement = MovementPad.Sprint;
}
}
}
if (isJumpInputCatched)
{
if (jumpingQuota > 0)
{
jumpCount++;
jumpingQuota--;
if (jumpCount == 1)
{
movingDir.y = JumpSpeed;
jumpStatus = JumpingStatus.Jumping;
if (movementInput != MovementPad.Sprint)
weaponManager.PlayFPVMechanicAnim(FPVMechanicAnimType.Landing);
}
else
{
jumpingQuota--;
movingDir.y = DoubleJumpSpeed;
jumpStatus = JumpingStatus.DoubleJumping;
weaponManager.PlayFPVMechanicAnim(FPVMechanicAnimType.Jumping);
audioSource.PlayOneShot(JumpJetSE);
//Activated Jump Jet
view.FastRPC("PlayDJEff", false, MessageReciever.Others, null);
}
}
isJumpInputCatched = false;
}
movingDir = transform.TransformDirection(movingDir);
if (ApplyGravity)
movingDir.y -= gravity * Time.deltaTime;
controller.Move(movingDir * Time.deltaTime);
weaponManager.PlayFPVMechanicAnim(fpvAnimType);
FootSteps();
#if UNITY_EDITOR
CharacterVelocity = controller.velocity;
#endif
}
/// <summary>
/// Caught any jumping input?
/// </summary>
private bool isJumpInputCatched = false;
public int JumpingQuota = 2;
private int jumpingQuota;
private int jumpCount = 0;
public AudioClip JumpJetSE;
/// <summary>
/// Active jumping behavior
/// </summary>
public void Jump()
{
if (ControlManager.Singleton.ControlSwitches.Jump)
isJumpInputCatched = true;
}
/// <summary>
/// LW RPC must be paired, ref <see cref="ThirdPersonCharacterInterface.PlayDJEff(byte[])"/>
/// </summary>
/// <param name="_data"></param>
[FastLWRPC]
public void PlayDJEff(byte[] _data)
{
//Do nothing
}
CharacterBehavior characterBehavior;
/// <summary>
/// A not too sensitive method for whether is player grounded
/// </summary>
/// <returns></returns>
private bool GetPlayerGroundedStatus()
{
if (controller.isGrounded || characterBehavior.IsRayGrounded)
return true;
else
return false;
}
[Header("Steps Sound Effects")]
//foot step sound effects
public AudioClip[] concrete;
public AudioClip[] wood;
public AudioClip[] dirt;
public AudioClip[] metal;
public AudioClip[] snow;
public AudioSource audioSource;
private bool StepBuffered = false;
/// <summary>
/// Frequency of playing stepping audio effects
/// </summary>
public float audioStepLengthWalk = 0.45f;
/// <summary>
/// Frequency of playing stepping audio effects
/// </summary>
public float audioStepLengthRun = 0.25f;
private float TimeSet;
private AudioClip SoundClip;
private float volume;
private float audioStepLength = 0.45f;
void FootSteps()
{
if (isPlayerGrounded && !StepBuffered)
{
if (movementInput == MovementPad.Empty)
{
audioSource.Stop();
return;
}
else if (movementInput != MovementPad.Sprint)//walk
{
audioStepLength = audioStepLengthWalk;
volume = 0.7f;
}
else//sprint
{
audioStepLength = audioStepLengthRun;
volume = 1.0f;
}
//Detect floor physics material
switch (characterBehavior.FloorMat)
{
case "Concrete": SoundClip = concrete[Random.Range(0, concrete.Length)]; break;
case "Wood": SoundClip = wood[Random.Range(0, wood.Length)]; break;
case "Metal": SoundClip = metal[Random.Range(0, metal.Length)]; break;
case "Dirt": SoundClip = dirt[Random.Range(0, dirt.Length)]; break;
case "Untagged": SoundClip = concrete[Random.Range(0, concrete.Length)]; break;
case "snow": SoundClip = dirt[Random.Range(0, dirt.Length)]; break;
default: SoundClip = null; break;
}
if (SoundClip != null)
{
audioSource.clip = SoundClip;
audioSource.volume = volume;
audioSource.Play();
StartCoroutine(StepAudioCooling(audioStepLength));
}
}
}
/// <summary>
/// The step sound effect will be available after WaitTime sec
/// </summary>
/// <param name="WaitTime">How long is the cooling time</param>
/// <returns></returns>
IEnumerator StepAudioCooling(float WaitTime)
{
StepBuffered = true;
yield return new WaitForSeconds(WaitTime);
StepBuffered = false;
}
/// <summary>
/// Work with rigidbody
/// </summary>
CapsuleCollider PhysicsCollider;
Rigidbody CharacterPhysic;
void OnDisable()
{
//Switch to rigidbody physics
controller.Move(Vector3.zero);
CharacterPhysic.isKinematic = false;
print(controller.velocity);
controller.Move(Vector3.zero);
CharacterPhysic.velocity = characterBehavior.playerVel;
controller.enabled = false;
PhysicsCollider.enabled = true;
}
void OnEnable()
{
//Switch to character controller
controller.enabled = true;//tagged
PhysicsCollider.enabled = false;
CharacterPhysic.isKinematic = true;
}
#if UNITY_EDITOR
[Header("Debugs")]
public Vector3 CharacterVelocity;
#endif
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment