Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Player Controller for Leap
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
using FMODUnity;
namespace Vrij2
{
public class PlayerCamera : MonoBehaviour
{
public delegate void StartGameDelegate ();
public static event StartGameDelegate GameStarted;
public GameObject camGO;
Camera cam;
Transform camTrans;
bool _gameStarted = false;
public LayerMask cameraCollisionMask;
const float cameraCollisionBuffer = .5f;
const float lookAtOffset = 3f;
const float movementLerpFactor = 0.24f, rotationLerpFactor = .5f;
Vector3 camRoot = new Vector3(0, 4, -9);
RaycastHit _cameraCollisionHit;
Vector3 _desiredCamPosition;
//Dynamic FoV
PlayerController playerController;
Rigidbody playerRig;
const float baseFoV = 60, maxFoV = 66;
const float maxFoVSpeed = 50;
VoiceOverDirector voiceOverDirector;
private void Awake ()
{
voiceOverDirector = GetComponentInChildren<VoiceOverDirector>();
IntroCutscene introCutscene = FindObjectOfType<IntroCutscene>();
if (!introCutscene) {
Debug.Log("Cutscene not found");
Initialize();
}
}
public void Initialize ()
{
camGO.SetActive(true);
camTrans = camGO.transform;
camTrans.parent = transform.parent;
cam = camGO.GetComponent<Camera>();
playerController = FindObjectOfType<PlayerController>();
playerRig = playerController.GetComponent<Rigidbody>();
camTrans.position = transform.position + transform.rotation * camRoot;
camTrans.Rotate(transform.rotation.eulerAngles);
PlayerController._controlsActive = true;
//Alert all subscribers that the game has started
if (GameStarted != null) {
GameStarted();
_gameStarted = true;
}
voiceOverDirector.StartCoroutine(voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.GameStart));
}
void Update ()
{
if (_gameStarted) {
//Position with obstruction detection
if (Physics.Raycast(transform.position, transform.rotation * camRoot, out _cameraCollisionHit, Vector3.Distance(transform.position, transform.position + camRoot), cameraCollisionMask)) {
_desiredCamPosition = _cameraCollisionHit.point + (transform.position - _cameraCollisionHit.point).normalized * cameraCollisionBuffer;
} else {
_desiredCamPosition = Vector3.Lerp(camTrans.position, transform.position + transform.rotation * camRoot, movementLerpFactor);
}
//Resolve position
camTrans.position = _desiredCamPosition;
//Rotation
Quaternion oldRot = camTrans.rotation;
camTrans.LookAt(transform.position + transform.forward * lookAtOffset, transform.up);
Quaternion newRot = camTrans.rotation;
camTrans.rotation = Quaternion.Lerp(oldRot, newRot, rotationLerpFactor);
//Dynamic FoV
float velocity = playerRig.velocity.magnitude;
if (velocity >= maxFoVSpeed) {
cam.fieldOfView = maxFoV;
} else {
float factor = velocity / maxFoVSpeed;
cam.fieldOfView = baseFoV + (maxFoV - baseFoV) * factor;
}
}
}
}
}
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace Vrij2
{
public class PlayerController : MonoBehaviour
{
Rigidbody rig;
[HideInInspector] public static bool _controlsActive = false;
public bool Grounded
{
get {
return _grounded;
}
}
public LayerMask groundedRayMask;
const float lizardLength = 2.8f;
float groundedRayDistance = 1.5f; //Half of height of transform is added in Awake()
bool _anyGroundedRayHit = false;
bool _grounded = false;
[HideInInspector] public bool _tongueshotActive = false;
private float tongueshotExitSpeed;
[HideInInspector] public bool _leapActive = false;
[HideInInspector] public bool _rollActive = false;
float rollSpeed;
public float MaxForwardSpeed
{
get {
return maxForwardSpeed;
}
}
public float ForwardSpeed
{
get {
return _forwardSpeed;
}
}
const float maxForwardSpeed = 56;
const float groundedAcceleration = 320;
const float groundedDeceleration = 210;
const float airborneDeceleration = 21f;
float _forwardSpeed = 0;
float _fallingSpeed = 0;
const float minimumTurnRate = .57f;
const float maximumTurnRate = 1.42f;
const float steeringDeadzone = .2f;
const float quickTurnDuration = .19f;
const float quickTurnCooldown = .12f;
const float quickturnDeadzone = .3f;
[HideInInspector] public bool _canPerformQuickTurn = true;
const float desiredDistanceToGround = .94f; //distance from the bottom of the mesh
const float alignGroundedRotationSpeed = 220;
const float alignAirborneRotationSpeed = 470;
const float fallingAcceleration = 100;
const float fallingMaxSpeed = 67;
RaycastHit _groundedRayHit;
bool _midRayHit = false;
[HideInInspector] public bool _alive = true;
[HideInInspector] public bool _standingStill = false;
const float secondsTillStandingStillPlays = 5;
float _timeSpentStandingStill = 0;
InGameMenu menu;
GameMusic music;
Renderer skinRenderer;
const float maxShaderGlow = 3;
float _shaderGlow = 0;
VoiceOverDirector voiceOverDirector;
bool _standingStillPlayed = true;
public enum EnemyTypes { Snake, Spider, Hedgehog };
void Awake ()
{
rig = GetComponent<Rigidbody>();
groundedRayDistance += transform.localScale.y / 2;
menu = FindObjectOfType<InGameMenu>();
music = FindObjectOfType<GameMusic>();
music.intensity = 1.5f;
//Setup skin glow
skinRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
skinRenderer.material.shader = Shader.Find("Shader Forge/Lizard_Glow");
voiceOverDirector = GetComponentInChildren<VoiceOverDirector>();
}
private void Update ()
{
MeasureStandingStill();
ShaderGlow();
}
void FixedUpdate ()
{
CheckGrounded();
if (_controlsActive) {
Movement();
Steering();
QuickTurn();
AlignWithGround();
}
}
void ShaderGlow ()
{
_shaderGlow = ForwardSpeed / maxForwardSpeed * maxShaderGlow;
skinRenderer.material.SetFloat("_Glowiness", _shaderGlow);
}
//If the player stands still for some time a voice over clip plays
void MeasureStandingStill ()
{
if (ForwardSpeed < 1) {
if (!_standingStill) {
_standingStill = true;
}
_timeSpentStandingStill += Time.deltaTime;
if (_timeSpentStandingStill > secondsTillStandingStillPlays && !_standingStillPlayed) {
voiceOverDirector.StartCoroutine(voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.StandingStill));
_standingStillPlayed = true;
}
} else {
_standingStill = false;
_standingStillPlayed = false;
_timeSpentStandingStill = 0;
}
}
void CheckGrounded ()
{
//Shoot 3 rays at the front, middle and rear of the player character
Vector3 rayOrigin;
for (int i = 0; i < 3; i++) {
rayOrigin = transform.position + transform.forward * (lizardLength / 2 * i - lizardLength / 2);
if (Physics.Raycast(rayOrigin, -transform.up, groundedRayDistance, groundedRayMask)) {
_anyGroundedRayHit = true;
}
}
//If any of the 3 rays hit we're grounded
if (_anyGroundedRayHit) {
_grounded = true;
} else {
_grounded = false;
}
_anyGroundedRayHit = false;
//The middle ray hitting is used in AllignWithGround()
if (Physics.Raycast(transform.position, -transform.up, out _groundedRayHit, groundedRayDistance, groundedRayMask)) {
_midRayHit = true;
} else {
_midRayHit = false;
}
}
void Movement ()
{
if (!_tongueshotActive && !_leapActive) {
if (_grounded) {
_fallingSpeed = 0;
//Retrieve inputs
float targetSpeed;
if (Input.GetAxis("RightTrigger") >= .1f) {
targetSpeed = maxForwardSpeed * Input.GetAxis("RightTrigger");
} else {
targetSpeed = maxForwardSpeed * Input.GetAxisRaw("KeyboardVertical");
}
//Increase speed if rolling
if (targetSpeed != 0 && _rollActive) {
targetSpeed *= rollSpeed / maxForwardSpeed;
}
//Accelerate/deccelerate
if (targetSpeed > _forwardSpeed) {
_forwardSpeed = Mathf.MoveTowards(_forwardSpeed, targetSpeed, groundedAcceleration * Time.fixedDeltaTime);
} else {
_forwardSpeed = Mathf.MoveTowards(_forwardSpeed, 0, groundedDeceleration * Time.fixedDeltaTime);
}
} else {
//Airborne movement. Forwards movement never hits 0 to avoid getting stuck
_forwardSpeed = Mathf.MoveTowards(_forwardSpeed, 2, airborneDeceleration * Time.fixedDeltaTime);
_fallingSpeed = Mathf.MoveTowards(_fallingSpeed, fallingMaxSpeed, fallingAcceleration * Time.fixedDeltaTime);
}
//Resolve velocity
rig.velocity = transform.forward * _forwardSpeed + -Vector3.up * _fallingSpeed;
} else {
_fallingSpeed = 0;
if (_tongueshotActive) {
_forwardSpeed = tongueshotExitSpeed;
}
}
}
void Steering ()
{
//Retrieve steering inputs
float input;
if (Mathf.Abs(Input.GetAxis("LeftStickHorizontal")) >= steeringDeadzone) {
input = Input.GetAxis("LeftStickHorizontal");
} else {
input = Input.GetAxisRaw("KeyboardHorizontal");
}
//Adjust turn rate by velocity and resolve
float turnRate = maximumTurnRate - (maximumTurnRate - minimumTurnRate) * (Mathf.Abs(rig.velocity.magnitude) / maxForwardSpeed);
transform.Rotate(new Vector3(0, turnRate * input, 0), Space.Self);
}
void QuickTurn ()
{
if (_canPerformQuickTurn) {
//Retrieve inputs
Vector3 direction;
if (Mathf.Abs(Input.GetAxis("RightStickHorizontal")) >= quickturnDeadzone || Mathf.Abs(Input.GetAxis("RightStickVertical")) >= quickturnDeadzone) {
direction = new Vector3(Input.GetAxis("RightStickHorizontal"), 0, Input.GetAxis("RightStickVertical"));
} else {
direction = new Vector3(Input.GetAxisRaw("ArrowsHorizontal"), 0, Input.GetAxisRaw("ArrowsVertical"));
}
//Resolve quickturn
if (direction != Vector3.zero) {
_canPerformQuickTurn = false;
StartCoroutine(QuickTurnRoutine(direction));
}
}
}
IEnumerator QuickTurnRoutine (Vector3 direction)
{
//Determine angle to turn to
float rotationAngle = Vector3.Angle(-Vector3.forward, direction);
if (direction.x < 0) {
rotationAngle = -rotationAngle;
}
//Rotate over time
float rotationPerSecond = rotationAngle / quickTurnDuration;
for (float t = 0; t < quickTurnDuration; t += Time.deltaTime) {
transform.Rotate(new Vector3(0, rotationPerSecond * Time.deltaTime, 0), Space.Self);
yield return null;
}
yield return new WaitForSeconds(quickTurnCooldown);
_canPerformQuickTurn = true;
}
void AlignWithGround ()
{
if (!_tongueshotActive && !_leapActive) {
float rotationSpeed;
Quaternion newRot;
if (_grounded) {
//Stick to the floor underneath the center of the player
if (_midRayHit) {
transform.position = Vector3.Lerp(transform.position, _groundedRayHit.point + transform.up * desiredDistanceToGround, 0.2f);
}
//Allign transform with the normal of the face underneath
Vector3 newNormal = _groundedRayHit.normal;
Vector3 newForward = Vector3.Cross(transform.right, newNormal);
newRot = Quaternion.LookRotation(newForward, newNormal);
rotationSpeed = alignGroundedRotationSpeed * Time.fixedDeltaTime;
} else {
//Allign transform to neutral position (belly down)
newRot = Quaternion.Euler(0, transform.eulerAngles.y, 0);
rotationSpeed = alignAirborneRotationSpeed * Time.fixedDeltaTime;
}
transform.rotation = Quaternion.RotateTowards(transform.rotation, newRot, rotationSpeed);
}
}
public void SetRollSpeed (float speed)
{
rollSpeed = speed;
}
public void SetTongueshotExitSpeed (float speed)
{
tongueshotExitSpeed = speed;
}
public void TakeDamage (EnemyTypes enemyType)
{
if (_alive) {
//Disable the game
_alive = false;
menu.DeathMenu();
Time.timeScale = 0;
//Play correct voice over clip
switch (enemyType) {
case EnemyTypes.Spider:
voiceOverDirector.StartCoroutine(routine: voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.SpiderDeath));
break;
case EnemyTypes.Hedgehog:
voiceOverDirector.StartCoroutine(routine: voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.HedgehogDeath));
break;
case EnemyTypes.Snake:
voiceOverDirector.StartCoroutine(routine: voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.SnakeDeath));
break;
}
}
}
}
}
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
namespace Vrij2
{
public class PlayerTransformations : MonoBehaviour
{
enum Transformations { Roll = 0, Leap, Tongueshot };
Rigidbody rig;
const int numberOfTransformations = 2;
Transformations[] transformations;
int _timesTransformed = 0;
public float EnergyGathered
{
get {
return _energyGathered;
}
}
public Text transformationsCompleteDisplay;
const float maxEnergy = 100;
const float energyGainedPerSecond = 3;
const float energyLostPerSecond = 5;
const float gainSpeedThreshold = 36;
const float loseSpeedThreshold = 24;
float _energyGathered = 0;
public LayerMask tongueCheckMask;
//Player Feedback Particles
public ParticleSystem transformParticles;
public ParticleSystem headButtParticles;
InstructionsScript instructions;
VoiceOverDirector voiceOverDirector;
bool _fiftyEnergyClipPlayed = false;
private void Awake ()
{
//SET TRANSFORMATION ORDER HERE:
transformations = new Transformations[numberOfTransformations] { Transformations.Roll, Transformations.Tongueshot };
rig = GetComponent<Rigidbody>();
transformParticles.GetComponent<ParticleSystem>();
var emission = transformParticles.emission;
emission.rateOverTime = 0;
headButtParticles.GetComponent<ParticleSystem>();
headButtParticles.Stop();
GameObject temp = GameObject.FindGameObjectWithTag("Instructions");
instructions = temp.GetComponent<InstructionsScript>();
voiceOverDirector = GetComponentInChildren<VoiceOverDirector>();
}
void Update ()
{
float velocity = rig.velocity.magnitude;
//Gain/lose energy based on speed
if (velocity >= gainSpeedThreshold) {
if (_energyGathered < 100) {
_energyGathered += energyGainedPerSecond * Time.deltaTime;
}
}
if (velocity <= loseSpeedThreshold) {
if (_energyGathered > 0 && _energyGathered < 100) {
_energyGathered -= energyLostPerSecond * Time.deltaTime;
}
}
//Lock energy when fully transformed
if (_timesTransformed >= numberOfTransformations) {
_energyGathered = 100;
transformationsCompleteDisplay.enabled = true;
}
//If energy is full and right button pressed, transform
if (_energyGathered >= 100) {
if (Input.GetButtonDown("YButton") && numberOfTransformations > _timesTransformed || Input.GetKeyDown("f") && numberOfTransformations > _timesTransformed) {
Transformation(transformations[_timesTransformed]);
transformParticles.Emit(200);
}
}
//Display instruction to transform if possible
if (_timesTransformed < numberOfTransformations) {
if (_energyGathered < 100) {
instructions.pressY.enabled = false;
} else if (_timesTransformed < numberOfTransformations) {
instructions.pressY.enabled = true;
}
}
//Play voice vlip when at 50 energy
if (_energyGathered > 50 && _fiftyEnergyClipPlayed == false) {
_fiftyEnergyClipPlayed = true;
voiceOverDirector.StartCoroutine(routine: voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.FiftyEnergy));
}
}
void Transformation (Transformations whichForm)
{
switch (whichForm) {
case Transformations.Roll:
if (GetComponent<Transformation_Roll>() == null) {
Transformation_Roll temp = gameObject.AddComponent<Transformation_Roll>();
temp.Initialize();
voiceOverDirector.StartCoroutine(voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.TransformationOne));
}
break;
case Transformations.Tongueshot:
if (GetComponent<Transformation_Tongueshot>() == null) {
Transformation_Tongueshot temp = gameObject.AddComponent<Transformation_Tongueshot>();
temp.Initialize();
voiceOverDirector.StartCoroutine(voiceOverDirector.PlayClip(VoiceOverDirector.VoiceOverTypes.TransformationTwo));
}
break;
case Transformations.Leap:
if (GetComponent<Transformation_Leap>() == null) {
Transformation_Leap temp = gameObject.AddComponent<Transformation_Leap>();
temp.Initialize();
}
break;
}
_energyGathered = 0;
_timesTransformed++;
}
public void GainEnergy (float energy)
{
_energyGathered += energy;
if (energy > maxEnergy)
_energyGathered = maxEnergy;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment