Created
November 27, 2019 13:38
-
-
Save MikouZonata/08f65662a157375f4327699e608c03ad to your computer and use it in GitHub Desktop.
You_v3.2r1
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 System.Collections; | |
using UnityEngine; | |
using XInputDotNetExtended; | |
using FMODUnity; | |
public class GameManager : MonoBehaviour | |
{ | |
public GameObject level; | |
public GameObject kevinPrefab, maanPrefab; | |
Kevin kevin; | |
Maan maan; | |
KevinManager kevinManager; | |
MaanManager maanManager; | |
MenuManager menuManager; | |
Transform[] trackPieces; | |
bool firstTimeInit = true; | |
const int secondsBeforeDeactivation = 90; | |
float _deactivationTimer = 0; | |
const int secondsBeforeFirstCloud = 90; | |
const int secondsBeforeFatigue = 40; | |
float _pacingTimer = 0; | |
//FMOD | |
const string fmodLinkedPath = "event:/Linked_Up"; | |
FMOD.Studio.EventInstance fmodLinkedInstance; | |
bool _fmodLinkedPlaying = false; | |
public GameObject singleMonitorErrorDisplay; | |
const float singleMonitorErrorUptime = 7; | |
void Awake () | |
{ | |
Init(); | |
} | |
void Init () | |
{ | |
if (firstTimeInit) { | |
//Activate both displays if not in editor | |
Display.displays[0].Activate(); | |
#if UNITY_EDITOR | |
#else | |
if (Display.displays.Length > 1) { | |
Display.displays[1].Activate(); | |
} else { | |
StartCoroutine(SingleMonitorErrorMessage()); | |
} | |
#endif | |
Cursor.visible = false; | |
//Retrieve all pieces of the level | |
Transform trackPiecesParent = level.transform; | |
trackPieces = new Transform[trackPiecesParent.childCount]; | |
for (int i = 0; i < trackPieces.Length; i++) { | |
trackPieces[i] = trackPiecesParent.GetChild(i); | |
} | |
maanManager = GetComponent<MaanManager>(); | |
kevinManager = GetComponent<KevinManager>(); | |
menuManager = GetComponent<MenuManager>(); | |
firstTimeInit = false; | |
} | |
//Create player characters | |
maan = (Instantiate(maanPrefab, new Vector3(-1, .05f, 0), Quaternion.identity).GetComponent<Maan>()); | |
maan.playerIndex = (XInputDotNetPure.PlayerIndex) 0; | |
StaticData.playerTransforms[0] = maan.transform; | |
kevin = (Instantiate(kevinPrefab, new Vector3(1, .05f, 0), Quaternion.identity).GetComponent<Kevin>()); | |
kevin.playerIndex = (XInputDotNetPure.PlayerIndex) 1; | |
StaticData.playerTransforms[1] = kevin.transform; | |
maan.Init(maanManager, kevin.transform); | |
kevin.Init(kevinManager, maan.transform); | |
maanManager.Init(trackPieces, maan); | |
kevinManager.Init(trackPieces, kevin); | |
//Main menu manager | |
menuManager.Init(this); | |
_deactivationTimer = 0; | |
maan.GetComponent<PauseScreen>().Init(this, maan, XInputDotNetPure.PlayerIndex.One); | |
kevin.GetComponent<PauseScreen>().Init(this, kevin, XInputDotNetPure.PlayerIndex.Two); | |
fmodLinkedInstance = RuntimeManager.CreateInstance(fmodLinkedPath); | |
} | |
public void DeactivateGame () | |
{ | |
kevinManager.Deactivate(); | |
maanManager.Deactivate(); | |
menuManager.ActivateMenu(); | |
StaticData.menuActive = true; | |
} | |
public void ActivateGame () | |
{ | |
Init(); | |
_pacingTimer = 0; | |
_deactivationTimer = 0; | |
StaticData.menuActive = false; | |
} | |
void Update () | |
{ | |
//If the game is running | |
if (!StaticData.menuActive) { | |
//Check to see whether players are close enough to be considered linked | |
if (Vector3.Distance(kevin.transform.position, maan.transform.position) <= StaticData.distanceToLink) { | |
StaticData.playersAreLinked = true; | |
} else { | |
StaticData.playersAreLinked = false; | |
} | |
//If any inputs are detected postpone deactivating the game | |
if (XInputEX.GetAnyInput(PlayerIndex.One) || XInputEX.GetAnyInput(PlayerIndex.Two)) { | |
_deactivationTimer = 0; | |
} | |
//Deactivate the game after a period of inactivity | |
_deactivationTimer += Time.deltaTime; | |
if (_deactivationTimer > secondsBeforeDeactivation) { | |
_deactivationTimer = 0; | |
DeactivateGame(); | |
} | |
//Maan's Cloud and Kevin's Fatigue activate after some time has passed | |
_pacingTimer += Time.deltaTime; | |
if (_pacingTimer >= secondsBeforeFirstCloud) { | |
maanManager.ActivateCloud(); | |
} | |
if (_pacingTimer >= secondsBeforeFatigue) { | |
kevin.ActivateFatigue(); | |
} | |
} | |
//Play global audio if players are linked | |
if (_fmodLinkedPlaying && !StaticData.playersAreLinked) { | |
_fmodLinkedPlaying = false; | |
fmodLinkedInstance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); | |
} | |
if (!_fmodLinkedPlaying && StaticData.playersAreLinked) { | |
_fmodLinkedPlaying = true; | |
fmodLinkedInstance.start(); | |
} | |
} | |
IEnumerator SingleMonitorErrorMessage () | |
{ | |
singleMonitorErrorDisplay.SetActive(true); | |
yield return new WaitForSeconds(singleMonitorErrorUptime); | |
singleMonitorErrorDisplay.SetActive(false); | |
} | |
} |
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 System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using UnityEngine.SceneManagement; | |
//using XInputDotNetPure; | |
using Utility; | |
using FMODUnity; | |
using XInputDotNetExtended; | |
public class Kevin : MonoBehaviour, ICharacter | |
{ | |
public XInputDotNetPure.PlayerIndex playerIndex = XInputDotNetPure.PlayerIndex.One; | |
KevinManager manager; | |
Transform maan; | |
Rigidbody rig; | |
const float FoVBaseDegrees = 60, FoVDegreesPerVelocity = .4f; | |
Camera mainCam; | |
Transform mainCamTrans; | |
Quaternion mainCamDefaultRot; | |
ParticleSystem sideDriftParticles; | |
ParticleSystem.EmissionModule sideDriftEmissionModule; | |
float _sideDriftDefaultEmission; | |
PauseScreen pauseScreen; | |
bool pauseActive = true; | |
public LineRenderer linkRenderer; | |
public Transform modelAnchor; | |
const float modelFatigueForwardsFactor = 18; | |
const float modelMaxForwardsAngle = 9, modelMaxSidewaysAngle = 9; | |
const float throttleMaxForwardSpeed = 28; | |
const float throttleAcceleration = 2, throttleNaturalDecceleration = 18; | |
Vector3 _velocity = Vector3.zero; | |
float _triggerValue = 0; | |
float _speedPoint = 0, _throttleSpeed = 0; | |
public GameObject fatigueSmokeGO; | |
const float fatigueRecoverRate = .167f, fatigueIncreaseRate = .011f; | |
const float fatigueFirstPlacePenalty = .006f; | |
const float fatigueRechargePerPickup = 0.04f; | |
const float fatigueSlowFactorMin = .5f; | |
const float fatigueSmokeThreshold = .68f; | |
bool overrideFatigue = false; | |
bool fatigueActive = false; | |
float _fatigue = 0f; | |
bool _fatigueSmokePlaying = false; | |
const float maxTurnRate = 192, minTurnRate = 76; | |
const float turnRateLossPerVelocity = 4.22f; | |
const float sideDriftPerVelocity = .42f, sideDriftMaxVelocity = 22, sideDriftMinVelocity = 12; | |
const float driftingMaxSideFactor = 5.2f, driftingMaxTurnFactor = 1.24f, driftingTimeToMax = .12f; | |
float driftingSideAcceleration, driftingTurnAcceleration; | |
float _steeringSideDrift = 0; | |
float _driftingTurnFactor = 1, _driftingSideFactor = 1; | |
const float struggleMinTime = 1.2f, struggleMaxTime = 3.0f; | |
float _struggleTimer = 0, _struggleTime = 10; | |
Vector3 _struggleVelocity = Vector3.zero; | |
public Transform leaderboardFrame; | |
//Loving is currently disabled | |
public GameObject lovePrefab; | |
bool _goingToLove = false; | |
bool _lovedOnPass = false; | |
//FMOD | |
const string fmodHoverPath = "event:/Kevin/Hover_Engine"; | |
const float fmodHoverPitchThreshold = .65f; | |
FMOD.Studio.EventInstance fmodHoverInstance; | |
FMOD.Studio.ParameterInstance fmodHoverPitch; | |
bool _fmodHoverPlaying = false; | |
public void Init (KevinManager manager, Transform maan) | |
{ | |
rig = GetComponent<Rigidbody>(); | |
mainCam = transform.GetChild(0).GetComponent<Camera>(); | |
mainCamTrans = mainCam.transform; | |
mainCamDefaultRot = mainCamTrans.rotation; | |
sideDriftParticles = GetComponentInChildren<ParticleSystem>(); | |
sideDriftEmissionModule = sideDriftParticles.emission; | |
_sideDriftDefaultEmission = sideDriftEmissionModule.rateOverTime.constant; | |
sideDriftEmissionModule.rateOverTime = 0; | |
var emission = sideDriftParticles.emission; | |
emission.rateOverTime = 0; | |
driftingSideAcceleration = (driftingMaxSideFactor - 1) / driftingTimeToMax; | |
driftingTurnAcceleration = (driftingMaxTurnFactor - 1) / driftingTimeToMax; | |
pauseScreen = GetComponent<PauseScreen>(); | |
ActivatePause(); | |
_struggleTime = Random.Range(struggleMinTime, struggleMaxTime); | |
fmodHoverInstance = RuntimeManager.CreateInstance(fmodHoverPath); | |
fmodHoverInstance.getParameter("Engine_Pitch", out fmodHoverPitch); | |
fatigueSmokeGO.SetActive(false); | |
this.manager = manager; | |
this.maan = maan; | |
} | |
public void Destroy () | |
{ | |
StopAllCoroutines(); | |
fmodHoverInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE); | |
Destroy(gameObject); | |
} | |
private void Update () | |
{ | |
if (!pauseActive) { | |
if (XInputEX.GetButtonDown(playerIndex, XInputEX.Buttons.Start)) { | |
ActivatePause(); | |
} | |
} | |
CameraFoV(); | |
ShowLink(); | |
ModelRotation(); | |
Fatigue(); | |
//Loving(); | |
if (!StaticData.playersAreLinked && rig.velocity.sqrMagnitude < 1) { | |
_struggleTimer += Time.deltaTime; | |
if (_struggleTimer > _struggleTime) { | |
StartCoroutine(Struggle()); | |
_struggleTime = Random.Range(struggleMinTime, struggleMaxTime); | |
_struggleTimer = 0; | |
} | |
} else { | |
_struggleTimer = 0; | |
_struggleTime = Random.Range(struggleMinTime, struggleMaxTime); | |
} | |
} | |
void FixedUpdate () | |
{ | |
_triggerValue = XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Right); | |
Throttle(); | |
_velocity.z = _throttleSpeed * FatigueSlowFactor(); //_boostSpeed; | |
_velocity.x = _steeringSideDrift; | |
_velocity += _struggleVelocity; | |
transform.Rotate(new Vector3(0, Steering(), 0)); | |
rig.velocity = transform.rotation * _velocity; | |
} | |
private void OnTriggerEnter (Collider other) | |
{ | |
if (other.tag == "Pickup") { | |
manager.PickUpPickup(Util.ToInt(transform.name), Util.ToInt(other.name)); | |
_fatigue = Mathf.Clamp(_fatigue - fatigueRechargePerPickup, 0, 1); | |
} | |
} | |
void ActivatePause () | |
{ | |
pauseActive = true; | |
pauseScreen.Activate(); | |
} | |
public void DeactivatePause () | |
{ | |
pauseActive = false; | |
} | |
void CameraFoV () | |
{ | |
mainCam.fieldOfView = FoVBaseDegrees + _velocity.z * FoVDegreesPerVelocity; | |
} | |
void ShowLink () | |
{ | |
Vector3[] positions; | |
if (StaticData.playersAreLinked) { | |
positions = new Vector3[] { transform.position + Vector3.up, maan.position + Vector3.up }; | |
} else { | |
positions = new Vector3[] { transform.position, transform.position }; | |
} | |
linkRenderer.SetPositions(positions); | |
} | |
void ModelRotation () | |
{ | |
float xRot = _fatigue * modelFatigueForwardsFactor + modelMaxForwardsAngle * XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Right); | |
float yRot = modelMaxSidewaysAngle * XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal); | |
modelAnchor.rotation = transform.rotation * Quaternion.Euler(xRot, yRot, 0); | |
} | |
void Throttle () | |
{ | |
if (_triggerValue > 0) { | |
_speedPoint = Mathf.MoveTowards(_speedPoint, _triggerValue, throttleAcceleration * Time.deltaTime); | |
_throttleSpeed = Mathf.Pow(_speedPoint, .5f) * throttleMaxForwardSpeed; | |
} else { | |
_throttleSpeed = Mathf.MoveTowards(_throttleSpeed, 0, throttleNaturalDecceleration * Time.deltaTime); | |
_speedPoint = Mathf.Pow(_throttleSpeed / throttleMaxForwardSpeed, 2); | |
} | |
ThrottleAudio(); | |
} | |
void ThrottleAudio () | |
{ | |
if (XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Right) == 0 && _fmodHoverPlaying) { | |
_fmodHoverPlaying = false; | |
fmodHoverInstance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); | |
} else if (XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Right) > 0 && !_fmodHoverPlaying) { | |
_fmodHoverPlaying = true; | |
fmodHoverInstance.start(); | |
} | |
float _hoverPitch = 1; | |
if (_fatigue > fmodHoverPitchThreshold) { | |
_hoverPitch = 1 - (_fatigue - fmodHoverPitchThreshold) * 1 / fmodHoverPitchThreshold; | |
} | |
fmodHoverPitch.setValue(_hoverPitch); | |
} | |
void Fatigue () | |
{ | |
if (Input.GetKeyDown(KeyCode.F)) { | |
overrideFatigue = !overrideFatigue; | |
} | |
if (!overrideFatigue && fatigueActive) { | |
if (StaticData.playersAreLinked) { | |
_fatigue = Mathf.MoveTowards(_fatigue, 0, fatigueRecoverRate * Time.deltaTime); | |
} else { | |
_fatigue = Mathf.MoveTowards(_fatigue, 1, (fatigueIncreaseRate + (manager.GetKevinRank() == 0 ? fatigueFirstPlacePenalty : 0)) * Time.deltaTime); | |
} | |
} else { | |
//Debug Fatigue options | |
if (Input.GetKey(KeyCode.LeftArrow)) { | |
_fatigue -= Time.deltaTime * .5f; | |
} else if (Input.GetKey(KeyCode.RightArrow)) { | |
_fatigue += Time.deltaTime * .5f; | |
} | |
if (XInputEX.GetButtonDown(playerIndex, XInputEX.Buttons.X)) { | |
_fatigue -= Time.deltaTime * .5f; | |
} | |
_fatigue = Mathf.Clamp(_fatigue, 0, 1); | |
} | |
if (!_fatigueSmokePlaying && _fatigue > fatigueSmokeThreshold) { | |
fatigueSmokeGO.SetActive(true); | |
_fatigueSmokePlaying = true; | |
} | |
if (_fatigueSmokePlaying && _fatigue < fatigueSmokeThreshold) { | |
fatigueSmokeGO.SetActive(false); | |
_fatigueSmokePlaying = false; | |
} | |
} | |
float FatigueSlowFactor () | |
{ | |
float result; | |
result = 1 - (1 - fatigueSlowFactorMin) * _fatigue; | |
return result; | |
} | |
float Steering () | |
{ | |
float result = 0; | |
float turnRate = Mathf.Clamp(maxTurnRate - Mathf.Abs(turnRateLossPerVelocity * _velocity.z), minTurnRate, maxTurnRate); | |
result = XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal) * turnRate * Time.deltaTime; | |
float trimmedVelocity = Mathf.MoveTowards(_velocity.z, 0, sideDriftMinVelocity); | |
trimmedVelocity = Mathf.Clamp(trimmedVelocity, -sideDriftMaxVelocity + sideDriftMinVelocity, sideDriftMaxVelocity - sideDriftMinVelocity); | |
_steeringSideDrift = -XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal) * trimmedVelocity * sideDriftPerVelocity; | |
if (XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Left) != 0) { | |
_driftingTurnFactor = Mathf.MoveTowards(_driftingTurnFactor, driftingMaxTurnFactor, driftingTurnAcceleration * Time.deltaTime); | |
_driftingSideFactor = Mathf.MoveTowards(_driftingSideFactor, driftingMaxSideFactor, driftingSideAcceleration * Time.deltaTime); | |
} else { | |
_driftingTurnFactor = Mathf.MoveTowards(_driftingTurnFactor, 1, driftingTurnAcceleration * Time.deltaTime); | |
_driftingSideFactor = Mathf.MoveTowards(_driftingSideFactor, 1, driftingSideAcceleration * Time.deltaTime); | |
} | |
result *= _driftingTurnFactor; | |
_steeringSideDrift *= _driftingSideFactor; | |
//To-Do: SideDriftParticles turn themselves off/on seemingly randomly | |
//if (Mathf.Abs(_steeringSideDrift) >= 2.5f) { | |
// sideDriftParticles.Play(); | |
// sideDriftEmissionModule.rateOverTime = sideDriftDefaultEmission; | |
//} else { | |
// sideDriftParticles.Stop(); | |
// sideDriftEmissionModule.rateOverTime = 0; | |
//} | |
return result; | |
} | |
//Loving is disabled and needs to be redesigned | |
void Loving () | |
{ | |
if (!_lovedOnPass && _fatigue > .3f && StaticData.playersAreLinked) { | |
_lovedOnPass = true; | |
ShowLove(); | |
} | |
if (_lovedOnPass && !StaticData.playersAreLinked) | |
_lovedOnPass = false; | |
if (!_goingToLove && _fatigue > .7f && StaticData.playersAreLinked) | |
_goingToLove = true; | |
if (_goingToLove && _fatigue < .2f && !StaticData.playersAreLinked) { | |
_goingToLove = false; | |
ShowLove(); | |
ShowLove(); | |
ShowLove(); | |
} | |
} | |
void ShowLove () | |
{ | |
Love love = Instantiate(lovePrefab, transform.position + new Vector3(Random.Range(-1.0f, 1.0f), 1.5f, Random.Range(-1.0f, 1.0f)), transform.rotation).GetComponent<Love>(); | |
love.Init(maan); | |
} | |
IEnumerator Struggle () | |
{ | |
float struggleTime = Random.Range(0.08f, 0.16f); | |
Vector2 radial = Random.insideUnitCircle; | |
Vector3 velocity = new Vector3(radial.x, 0, Mathf.Abs(radial.y)).normalized * Random.Range(3, 7); | |
float rotation = Random.Range(-88f, 88f); | |
_struggleVelocity = velocity; | |
for (float t = 0; t < struggleTime; t += Time.deltaTime) { | |
transform.Rotate(0, rotation * Time.deltaTime, 0); | |
if (XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal) != 0 | |
|| XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickVertical) != 0 | |
|| XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Left) != 0 | |
|| XInputEX.GetTrigger(playerIndex, XInputEX.Triggers.Right) != 0) { | |
break; | |
} | |
yield return null; | |
} | |
_struggleVelocity = Vector3.zero; | |
} | |
public void ActivateFatigue () | |
{ | |
fatigueActive = true; | |
} | |
public Transform GetTransform () | |
{ | |
return transform; | |
} | |
public float GetFatigue () | |
{ | |
return _fatigue; | |
} | |
} |
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 System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEngine; | |
using UnityEngine.AI; | |
using UnityEngine.UI; | |
using Utility; | |
using FMODUnity; | |
public class KevinManager : MonoBehaviour | |
{ | |
bool firstTimeSetup = true; | |
public GameObject[] enemyDriverPrefabs; | |
public GameObject pickupPrefab, pickupFeedbackPrefab; | |
const int numberOfDrivers = 6; | |
const int numberOfAiDrivers = 5; | |
Transform pickupFeedbackParent; | |
int[] driverTargets = new int[numberOfDrivers]; | |
Kevin _kevin; | |
Transform driverParent; | |
NavMeshAgent[] _driverAgents; | |
Transform[] pickupPool; | |
Transform[] trackPieces; | |
Transform _leaderboard; | |
RectTransform[] leaderboardCards; | |
string[] driverNames = new string[] { "Daniel", "Lenny", "Tim", "Valentijn", "Richard" }; | |
int[] driverStartingScores = new int[] { 52, 44, 36, 17, 8 }; | |
float[] driverBaseSpeeds = new float[] { 16.3f, 14.9f, 10.6f, 9.6f, 8.3f }; | |
Color scoreHightlightColor; | |
int[] _scores; | |
int[] _ranks; | |
Text[][] _scoreDisplays; | |
Image[] _scoreHighlights; | |
const float scoreDownBaseTime = 12, scoreDownTimePerPoint = .075f; | |
float[] _scoreDownTimers = new float[numberOfDrivers]; | |
const float driverSpeedFluxMax = 1.1f; | |
const float driverSpeedFluxWavelength = 50; | |
float[] _driverSpeedFluxTimers; | |
GameObject[] pickupFeedbackPool = new GameObject[numberOfDrivers]; | |
//FMOD | |
const string fmodKevinPickupEvent = "event:/Kevin/Pick-up"; | |
const string fmodDriverPickupEvent = "event:/Kevin/Pick-up_Opponent"; | |
FMOD.Studio.EventInstance fmodPickupInstance; | |
public void Init (Transform[] trackPieces, Kevin _kevin) | |
{ | |
this.trackPieces = trackPieces; | |
this._kevin = _kevin; | |
if (firstTimeSetup) { | |
//Maak alle pickups | |
pickupPool = new Transform[trackPieces.Length]; | |
GameObject pickupParent = new GameObject("PickupParent"); | |
for (int i = 0; i < pickupPool.Length; i++) { | |
pickupPool[i] = Instantiate(pickupPrefab, trackPieces[i].position + Vector3.up * .5f, Quaternion.identity, pickupParent.transform).transform; | |
pickupPool[i].name = i.ToString(); | |
pickupPool[i].gameObject.SetActive(false); | |
} | |
//Pickup feedback pool maken | |
pickupFeedbackParent = new GameObject("PickupFeedbackParent").transform; | |
for (int i = 0; i < pickupFeedbackPool.Length; i++) { | |
pickupFeedbackPool[i] = Instantiate(pickupFeedbackPrefab); | |
pickupFeedbackPool[i].transform.parent = pickupFeedbackParent; | |
pickupFeedbackPool[i].SetActive(false); | |
} | |
//Setup stuff voor leaderboard | |
leaderboardCards = new RectTransform[numberOfDrivers]; | |
_scoreDisplays = new Text[numberOfDrivers][]; | |
_scoreHighlights = new Image[numberOfDrivers]; | |
_ranks = new int[numberOfDrivers]; | |
//Setup een parent voor de drivers en ai driver speed flux | |
driverParent = new GameObject("DriverParent").transform; | |
_driverSpeedFluxTimers = new float[numberOfAiDrivers]; | |
for (int i = 0; i < numberOfAiDrivers; i++) { | |
_driverSpeedFluxTimers[i] = Random.Range(0, driverSpeedFluxWavelength); | |
} | |
firstTimeSetup = false; | |
} | |
//Instantiate alle drivers | |
_driverAgents = new NavMeshAgent[numberOfAiDrivers]; | |
for (int i = 0; i < numberOfAiDrivers; i++) { | |
_driverAgents[i] = Instantiate(Util.PickRandom(enemyDriverPrefabs), Util.PickRandom(trackPieces).position, Quaternion.identity, driverParent.transform).GetComponent<NavMeshAgent>(); | |
_driverAgents[i].name = i.ToString(); | |
_driverAgents[i].speed = driverBaseSpeeds[i]; | |
} | |
//Pickups for everyone | |
for (int i = 0; i < numberOfDrivers; i++) { | |
AssignNewPickup(i, true); | |
} | |
//Geef Kevin een naam die overeenkomt met zijn driverIndex | |
_kevin.name = "5"; | |
//Vul het leaderboard met naampjes en stuff | |
_leaderboard = _kevin.leaderboardFrame; | |
_scores = new int[numberOfDrivers]; | |
for (int i = 0; i < _scoreDownTimers.Length; i++) { | |
_scoreDownTimers[i] = 0; | |
} | |
for (int driver = 0; driver < numberOfDrivers; driver++) { | |
leaderboardCards[driver] = _leaderboard.GetChild(driver).GetComponent<RectTransform>(); | |
_scoreHighlights[driver] = leaderboardCards[driver].GetComponent<LeaderboardCard>().highlightImage; | |
_scoreDisplays[driver] = new Text[3]; | |
for (int i = 0; i < 3; i++) { | |
_scoreDisplays[driver][i] = leaderboardCards[driver].GetComponent<LeaderboardCard>().scoreTexts[i]; | |
} | |
if (driver < numberOfAiDrivers) { | |
_scores[driver] = driverStartingScores[driver]; | |
foreach (Text t in _scoreDisplays[driver]) { | |
t.text = _scores[driver].ToString(); | |
} | |
} else { | |
_scores[driver] = 0; | |
} | |
} | |
scoreHightlightColor = _scoreHighlights[0].color; | |
//Add 1 punt zodat het scoreboard zichzelf formateert. | |
AddPointToScore(0); | |
} | |
public void Deactivate () | |
{ | |
StopAllCoroutines(); | |
foreach (NavMeshAgent agent in _driverAgents) { | |
Destroy(agent.gameObject); | |
} | |
foreach (Transform t in pickupPool) { | |
t.gameObject.SetActive(false); | |
} | |
fmodPickupInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE); | |
_kevin.Destroy(); | |
} | |
void Update () | |
{ | |
if (!StaticData.menuActive) { | |
//Check of een ai driver een pickup bereikt. | |
for (int i = 0; i < numberOfAiDrivers; i++) { | |
if ((_driverAgents[i].transform.position - _driverAgents[i].destination).sqrMagnitude < 1.5f) { | |
PickUpPickup(i, driverTargets[i]); | |
} | |
} | |
ScoreDownTimers(); | |
DriverSpeedFlux(); | |
} | |
} | |
public void PickUpPickup (int driverIndex, int pickupIndex) | |
{ | |
//Verwijder oude pickup. | |
pickupPool[pickupIndex].gameObject.SetActive(false); | |
foreach (GameObject feedbackGO in pickupFeedbackPool) { | |
if (!feedbackGO.activeSelf) { | |
feedbackGO.transform.position = pickupPool[pickupIndex].position; | |
feedbackGO.SetActive(true); | |
if (driverIndex != 5) { | |
StartCoroutine(PickupFeedbackRoutine(feedbackGO, _driverAgents[driverIndex].transform)); | |
if (Vector3.Distance(_kevin.transform.position, _driverAgents[driverIndex].transform.position) < 45) { | |
fmodPickupInstance = RuntimeManager.CreateInstance(fmodDriverPickupEvent); | |
fmodPickupInstance.start(); | |
} | |
} else { | |
StartCoroutine(PickupFeedbackRoutine(feedbackGO, _kevin.transform)); | |
fmodPickupInstance = RuntimeManager.CreateInstance(fmodKevinPickupEvent); | |
fmodPickupInstance.start(); | |
} | |
break; | |
} | |
} | |
AddPointToScore(driverIndex); | |
for (int i = 0; i < numberOfDrivers; i++) { | |
if (driverTargets[i] == pickupIndex) { | |
AssignNewPickup(i); | |
} | |
} | |
} | |
IEnumerator PickupFeedbackRoutine (GameObject feedbackGO, Transform followTrans) | |
{ | |
AnimatorStateInfo _animStateInfo; | |
Animator animator = feedbackGO.GetComponent<Animator>(); | |
animator.enabled = true; | |
animator.Play("PickUpFX", 0, 0); | |
for (float t = 0; t < 3; t += Time.deltaTime) { | |
feedbackGO.transform.position = followTrans.position + Vector3.up; | |
if (animator.enabled) { | |
_animStateInfo = animator.GetCurrentAnimatorStateInfo(0); | |
if (!_animStateInfo.IsName("PickUpFX")) { | |
animator.enabled = false; | |
} | |
} | |
yield return null; | |
} | |
feedbackGO.SetActive(false); | |
} | |
void AssignNewPickup (int driverIndex, bool firstTimeInitialization = false) | |
{ | |
//Zet oude pickup op inactive en maak feedback | |
if (!firstTimeInitialization) { | |
pickupPool[driverTargets[driverIndex]].gameObject.SetActive(false); | |
} | |
//Vind nieuwe target in de pool | |
int targetPickupIndex = Random.Range(0, pickupPool.Length); | |
while (true) { | |
if (!pickupPool[targetPickupIndex].gameObject.activeSelf) { | |
break; | |
} else { | |
targetPickupIndex = Random.Range(0, pickupPool.Length); | |
} | |
} | |
//Set nieuwe target en, if ai, maak dat ook de nav agent's destination | |
driverTargets[driverIndex] = targetPickupIndex; | |
pickupPool[driverTargets[driverIndex]].gameObject.SetActive(true); | |
if (driverIndex < numberOfAiDrivers) | |
_driverAgents[driverIndex].destination = pickupPool[targetPickupIndex].position; | |
} | |
void AddPointToScore (int driverIndex, int score = 1) | |
{ | |
_scores[driverIndex] += score; | |
if (_scores[driverIndex] < 0) | |
_scores[driverIndex] = 0; | |
_scoreDownTimers[driverIndex] = 0; | |
if (score > 0) { | |
StartCoroutine(HighlightScore(driverIndex)); | |
} | |
//Creeer een nieuwe lijst met gesorteerde scores | |
List<int> sortedScores = _scores.ToList(); | |
sortedScores.Sort(new GFG()); | |
//Claimedranks houd bij welke ranks er al bezet zijn om meerdere drivers op dezelfde rank te voorkomen | |
List<int> claimedRanks = new List<int>(); | |
for (int driver = 0; driver < numberOfDrivers; driver++) { | |
for (int rank = 0; rank < numberOfDrivers; rank++) { | |
//Als hun score overeenkomt met een score in de gesorteerde lijst weet ik welke rank ze zouden moeten zijn. Claimedranks voorkomt duplicate ranks | |
if (_scores[driver] == sortedScores[rank] && !claimedRanks.Contains(rank)) { | |
_ranks[driver] = rank; | |
claimedRanks.Add(rank); | |
break; | |
} | |
} | |
} | |
//Update leaderboardCards naar hun juiste posities en vul strings in | |
float distanceBetweenCards = -56, rankTwoBasePosition = -24; | |
for (int driver = 0; driver < numberOfDrivers; driver++) { | |
if (_ranks[driver] == 0) { | |
leaderboardCards[driver].anchoredPosition = new Vector2(0, 0); | |
} else { | |
leaderboardCards[driver].anchoredPosition = new Vector2(0, rankTwoBasePosition + _ranks[driver] * distanceBetweenCards); | |
} | |
foreach (Text t in _scoreDisplays[driver]) { | |
t.text = _scores[driver].ToString(); | |
} | |
} | |
} | |
void ScoreDownTimers () | |
{ | |
for (int i = 0; i < numberOfDrivers; i++) { | |
_scoreDownTimers[i] += Time.deltaTime; | |
if (_scoreDownTimers[i] >= scoreDownBaseTime - _scores[i] * scoreDownTimePerPoint) { | |
AddPointToScore(i, -1); | |
_scoreDownTimers[i] = 0; | |
} | |
} | |
} | |
void DriverSpeedFlux () | |
{ | |
for (int i = 0; i < numberOfAiDrivers; i++) { | |
_driverSpeedFluxTimers[i] += Time.deltaTime; | |
_driverAgents[i].speed = driverBaseSpeeds[i] + Mathf.Sin(_driverSpeedFluxTimers[i] * (Mathf.PI * 2) / driverSpeedFluxWavelength) * driverSpeedFluxMax; | |
} | |
} | |
//Als iemand een puntje haalt licht hun score counter even op | |
IEnumerator HighlightScore (int driverIndex) | |
{ | |
float highlightAlpha = .8f, highlightTime = .9f; | |
for (float t = 0; t < highlightTime * .5f; t += Time.deltaTime) { | |
_scoreHighlights[driverIndex].color = new Color(scoreHightlightColor.r, scoreHightlightColor.g, scoreHightlightColor.b, t * 2 / highlightTime * highlightAlpha); | |
yield return null; | |
} | |
for (float t = highlightTime * .5f; t > 0; t -= Time.deltaTime) { | |
_scoreHighlights[driverIndex].color = new Color(scoreHightlightColor.r, scoreHightlightColor.g, scoreHightlightColor.b, t * 2 / highlightTime * highlightAlpha); | |
yield return null; | |
} | |
_scoreHighlights[driverIndex].color = new Color(scoreHightlightColor.r, scoreHightlightColor.g, scoreHightlightColor.b, 0); | |
} | |
public int GetKevinRank () | |
{ | |
return _ranks[5]; | |
} | |
} | |
class GFG : IComparer<int> | |
{ | |
public int Compare (int x, int y) | |
{ | |
return y.CompareTo(x); | |
} | |
} |
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 System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using XInputDotNetExtended; | |
using Utility; | |
using FMODUnity; | |
public class Maan : MonoBehaviour, ICharacter | |
{ | |
[HideInInspector] | |
public XInputDotNetPure.PlayerIndex playerIndex = PlayerIndex.One; | |
Vector2 _leftStickInput; | |
MaanManager manager; | |
Transform kevin; | |
Rigidbody rig; | |
Transform cameraAnchorTrans, cameraTrans; | |
Vector3 _velocity, _cameraRotation; | |
PauseScreen pauseScreen; | |
bool pauseActive = true; | |
const float movementSpeed = 11; | |
public GameObject cameraPrefab; | |
const float cameraMaxZAngle = 42, cameraMinZAngle = -36; | |
const float cameraXSensitivity = 260, cameraZSensitivity = 150; | |
float _cameraZAngle = 0; | |
public LineRenderer linkRenderer; | |
const float screenShakeIntensityFactor = .17f; | |
Vector3 cameraDefaultPosition; | |
Transform modelTrans; | |
float _modelYAngle = 0; | |
List<Kattoe> _kattoesInRange = new List<Kattoe>(); | |
public GameObject pingExclamation, pingRoseFeedback; | |
const float pingActiveTime = .3f; | |
Transform pingParent; | |
List<GameObject> pingFeedbackPool = new List<GameObject>(); | |
SpriteRenderer pingRenderer; | |
public int KattoesBonded | |
{ | |
get { | |
return occupiedKattoeAnchors.Count; | |
} | |
} | |
public Transform[] kattoeAnchors; | |
List<Transform> occupiedKattoeAnchors = new List<Transform>(); | |
public Image fadeToBlackDisplay; | |
public GameObject lovePrefab; | |
const float loveMinTimebetweenLoveLinked = 2, loveMaxTimeBetweenLoveLinked = 4; | |
const float loveMinTimebetweenLoveUnlinked = 8, loveMaxTimeBetweenLoveUnlinked = 11; | |
float _loveTimer = 0, _loveTime = 0; | |
bool _wasLinked = false; | |
//FMOD | |
const string fmodWhistlePath = "event:/Maan/Calling_Cats_Maan"; | |
const int fmodWhistlePoolSize = 8; | |
FMOD.Studio.EventInstance[] fmodWhistleInstances = new FMOD.Studio.EventInstance[fmodWhistlePoolSize]; | |
int _fmodWhistlePoolIndex = 0; | |
public void Init (MaanManager manager, Transform kevin) | |
{ | |
rig = GetComponent<Rigidbody>(); | |
pauseScreen = GetComponent<PauseScreen>(); | |
ActivatePause(); | |
cameraAnchorTrans = Instantiate(cameraPrefab, transform.position, transform.rotation).transform; | |
cameraTrans = cameraAnchorTrans.GetChild(0); | |
cameraDefaultPosition = cameraTrans.localPosition; | |
modelTrans = transform.GetChild(0); | |
fadeToBlackDisplay.enabled = false; | |
pingParent = new GameObject("PingFeedbackParent").transform; | |
pingRenderer = pingExclamation.GetComponent<SpriteRenderer>(); | |
pingRenderer.color = new Color(1, 1, 1, 0); | |
for (int i = 0; i < fmodWhistlePoolSize; i++) { | |
fmodWhistleInstances[i] = RuntimeManager.CreateInstance(fmodWhistlePath); | |
} | |
this.manager = manager; | |
this.kevin = kevin; | |
} | |
public void Destroy () | |
{ | |
StopAllCoroutines(); | |
Destroy(cameraAnchorTrans.gameObject); | |
Destroy(pingParent.gameObject); | |
foreach (FMOD.Studio.EventInstance instance in fmodWhistleInstances) { | |
instance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE); | |
} | |
Destroy(gameObject); | |
} | |
void ActivatePause () | |
{ | |
pauseScreen.Activate(); | |
pauseActive = true; | |
} | |
public void DeactivatePause () | |
{ | |
pauseActive = false; | |
} | |
private void Update () | |
{ | |
if (!pauseActive) { | |
if (XInputEX.GetButtonDown(playerIndex, XInputEX.Buttons.Start)) { | |
ActivatePause(); | |
} | |
} | |
_leftStickInput = new Vector2(XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal), XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickVertical)); | |
CameraMovement(); | |
ModelRotation(); | |
ShowLink(); | |
//Loving(); Loving is being redesigned | |
if (XInputEX.GetButtonDown(playerIndex, XInputEX.Buttons.A)) { | |
Ping(); | |
} | |
} | |
void FixedUpdate () | |
{ | |
_velocity = transform.rotation * CharacterMovement(); | |
rig.velocity = _velocity; | |
} | |
Vector3 CharacterMovement () | |
{ | |
Vector3 result = Vector3.zero; | |
result.x = XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickHorizontal) * movementSpeed; | |
result.z = XInputEX.GetAxis(playerIndex, XInputEX.Axis.LeftStickVertical) * movementSpeed; | |
if (result.sqrMagnitude > movementSpeed * movementSpeed) { | |
result = result.normalized * movementSpeed; | |
} | |
result = Quaternion.Euler(0, _cameraYAngle, 0) * result; | |
return result; | |
} | |
float _cameraYAngle = 0; | |
void CameraMovement () | |
{ | |
cameraAnchorTrans.position = transform.position; | |
_cameraYAngle += XInputEX.GetAxis(playerIndex, XInputEX.Axis.RightStickHorizontal) * cameraXSensitivity * Time.deltaTime; | |
_modelYAngle -= XInputEX.GetAxis(playerIndex, XInputEX.Axis.RightStickHorizontal) * cameraXSensitivity * Time.deltaTime; | |
if (_cameraYAngle < -180) { | |
_cameraYAngle += 360; | |
} else if (_cameraYAngle > 180) { | |
_cameraYAngle -= 360; | |
} | |
_cameraZAngle = Mathf.Clamp(_cameraZAngle - XInputEX.GetAxis(playerIndex, XInputEX.Axis.RightStickVertical) * cameraZSensitivity * Time.deltaTime, | |
cameraMinZAngle, cameraMaxZAngle); | |
cameraAnchorTrans.rotation = Quaternion.Euler(new Vector3(_cameraZAngle, _cameraYAngle, 0)); | |
cameraTrans.LookAt(transform.position + Quaternion.Euler(_cameraZAngle, _cameraYAngle, 0) * Vector3.forward * 2.5f); | |
} | |
void ModelRotation () | |
{ | |
if (_leftStickInput.magnitude > 0.1f) { | |
_modelYAngle = Vector2.Angle(_leftStickInput, Vector2.up); | |
if (_leftStickInput.x < 0) { | |
_modelYAngle *= -1; | |
} | |
} | |
modelTrans.rotation = Quaternion.Euler(0, _modelYAngle + _cameraYAngle, 0); | |
} | |
void ShowLink () | |
{ | |
Vector3[] positions; | |
if (StaticData.playersAreLinked) { | |
positions = new Vector3[] { transform.position + Vector3.up, kevin.position + Vector3.up }; | |
} else { | |
positions = new Vector3[] { transform.position, transform.position }; | |
} | |
linkRenderer.SetPositions(positions); | |
} | |
void Loving () | |
{ | |
if (_wasLinked && !StaticData.playersAreLinked) { | |
_loveTime = Random.Range(loveMinTimebetweenLoveUnlinked, loveMaxTimeBetweenLoveUnlinked); | |
} else if (!_wasLinked && StaticData.playersAreLinked) { | |
_loveTime = Random.Range(loveMinTimebetweenLoveLinked, loveMaxTimeBetweenLoveLinked); | |
ShowLove(); | |
} | |
_wasLinked = StaticData.playersAreLinked; | |
_loveTimer += Time.deltaTime; | |
if (_loveTimer > _loveTime) { | |
ShowLove(); | |
if (StaticData.playersAreLinked) | |
_loveTime = Random.Range(loveMinTimebetweenLoveLinked, loveMaxTimeBetweenLoveLinked); | |
else | |
_loveTime = Random.Range(loveMinTimebetweenLoveUnlinked, loveMaxTimeBetweenLoveUnlinked); | |
_loveTimer = 0; | |
} | |
} | |
public void ScreenShake (float intensity) | |
{ | |
Vector3 screenShakeResult = new Vector3(Mathf.Sin(Time.time * 100), Mathf.Sin(Time.time * 120 + 1), 0); | |
cameraTrans.localPosition = cameraDefaultPosition + screenShakeResult * intensity * screenShakeIntensityFactor; | |
} | |
public void EngagedByKattoe (Kattoe kattoe, bool engageOrDisengage) | |
{ | |
if (engageOrDisengage) { | |
_kattoesInRange.Add(kattoe); | |
} else { | |
_kattoesInRange.Remove(kattoe); | |
} | |
} | |
void Ping () | |
{ | |
StopCoroutine(PingExclamationRoutine()); | |
StartCoroutine(PingExclamationRoutine()); | |
fmodWhistleInstances[_fmodWhistlePoolIndex].start(); | |
_fmodWhistlePoolIndex++; | |
if (_fmodWhistlePoolIndex >= fmodWhistlePoolSize) | |
_fmodWhistlePoolIndex = 0; | |
//Look for an inactive Pign object. If none are available create a new one | |
for (int i = 0; i < pingFeedbackPool.Count; i++) { | |
if (!pingFeedbackPool[i].activeSelf) { | |
StartCoroutine(PingRoseRoutine(pingFeedbackPool[i])); | |
goto Finish; | |
} | |
} | |
GameObject temp = Instantiate(pingRoseFeedback, transform.position, Quaternion.identity); | |
temp.transform.parent = pingParent; | |
StartCoroutine(PingRoseRoutine(temp)); | |
Finish: | |
for (int i = 0; i < _kattoesInRange.Count; i++) { | |
_kattoesInRange[i].ReceiveLure(); | |
} | |
} | |
IEnumerator PingExclamationRoutine () | |
{ | |
pingRenderer.color = Color.white; | |
float colorFactor = 1 / pingActiveTime; | |
for (float t = pingActiveTime; t > 0; t -= Time.deltaTime) { | |
pingRenderer.color = new Color(1, 1, 1, t * colorFactor); | |
yield return null; | |
} | |
pingRenderer.color = new Color(1, 1, 1, 0); | |
} | |
IEnumerator PingRoseRoutine (GameObject go) | |
{ | |
go.transform.position = transform.position + Vector3.up * .05f; | |
Animator[] temp = go.GetComponentsInChildren<Animator>(); | |
foreach (Animator a in temp) { | |
a.Play("Swirl"); | |
} | |
yield return new WaitForSeconds(2); | |
go.SetActive(false); | |
} | |
void ShowLove () | |
{ | |
Love love = Instantiate(lovePrefab, transform.position + new Vector3(Random.Range(-1.0f, 1.0f), 2.5f, Random.Range(-1.0f, 1.0f)), cameraTrans.rotation).GetComponent<Love>(); | |
love.Init(kevin); | |
} | |
public Transform KattoeRequestFlockAnchor () | |
{ | |
Transform attemptedAnchor = Util.PickRandom(kattoeAnchors); | |
while (occupiedKattoeAnchors.Contains(attemptedAnchor)) { | |
attemptedAnchor = Util.PickRandom(kattoeAnchors); | |
} | |
occupiedKattoeAnchors.Add(attemptedAnchor); | |
return attemptedAnchor; | |
} | |
public void KattoeLeaveFlock (Transform anchor) | |
{ | |
occupiedKattoeAnchors.Remove(anchor); | |
} | |
public IEnumerator FadeToBlack (float totalTime, Color fadeColor, float fadeTime = 1) | |
{ | |
fadeToBlackDisplay.enabled = true; | |
Color _color = fadeToBlackDisplay.color = fadeColor; | |
yield return new WaitForSeconds(totalTime - fadeTime); | |
float transformationValue = 1 / fadeTime; | |
for (float t = fadeTime; t > 0; t -= Time.deltaTime) { | |
_color.a = t * transformationValue; | |
fadeToBlackDisplay.color = _color; | |
yield return null; | |
} | |
fadeToBlackDisplay.enabled = false; | |
} | |
} |
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 System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Rendering.PostProcessing; | |
using Utility; | |
using FMODUnity; | |
public class MaanManager : MonoBehaviour | |
{ | |
Transform[] _trackPieces; | |
Maan maan; | |
bool _firstTimeInit = true; | |
public GameObject[] kattoePrefabs; | |
bool happinessOverride = false; | |
float _happiness = 0; | |
const float happinessGrowthRate = .3f; | |
const float happinessWhenLinked = .5f; | |
const float happinessBadCloudFar = -.3f, happinessBadCloudNear = -1.1f; | |
const float happinessGoodCloudFar = -.1f, happinessGoodCloudNear = -.36f; | |
const float happinessCloudNearDistance = 12, happinessCloudFarDistance = 55; | |
const float happinessPerKattoe = 0.18f; | |
const float happinessScreenShakeThreshold = .3f; | |
const float happinessMusicThreshold = .3f; | |
const float happinessMusicMaxThreshold = .6f; | |
float _happinessMusicVolume = 0; | |
const float happinessMusicVolumeGrowthRate = .4f; | |
PostProcessVolume postProcessingVolume; | |
public PostProcessProfile ppHappyProfile; | |
public PostProcessProfile ppSadProfile; | |
int activeKattoes = 7; | |
Transform kattoeParent; | |
List<Kattoe> kattoes; | |
List<Transform> occupiedPieces; | |
bool cloudActive = false; | |
public GameObject cloudPrefab; | |
Transform _cloudTrans; | |
Cloud cloud; | |
enum CloudStates { Dormant, Waiting, Chasing }; | |
CloudStates cloudState; | |
float cloudSpawnDistance = 72; | |
bool cloudDormantSetup = false; | |
float _cloudDormantTimer = 0, cloudDormantTime; | |
const float cloudMinTimeBeforeSpawn = 54, cloudMaxTimeBeforeSpawn = 92; | |
const float cloudSpawningHeight = 4; | |
bool cloudWaitingSetup = false; | |
float _cloudWaitingTimer = 0, cloudWaitingTime; | |
const float cloudWaitingSpeed = 4, cloudWaitingHeight = 0; | |
const float minTimeBeforeCloudChase = 1.0f, maxTimeBeforeCloudChase = 2.2f; | |
bool cloudChaseSetup = false; | |
float cloudDescendSpeed = 3, _cloudChaseSpeed = 0; | |
float cloudChaseBaseSpeed = 3, cloudChaseAcceleration = .54f; | |
float cloudChasingHeight = 0; | |
float cloudChasingDistanceToImpact = 3; | |
float cloudImpactFadeTimeGood = 0, cloudImpactFadeTimeBad = 4f; | |
//FMOD | |
string fmodCloudPath = "event:/Maan/Stress_Monster"; | |
FMOD.Studio.EventInstance fmodCloudInstance; | |
FMOD.Studio.ParameterInstance fmodCloudStateParameter; //0 == evil, 1 == good | |
bool _fmodCloudPlaying = false; | |
float _fmodCloudState = 1; | |
string fmodKattoeMusicPath = "event:/Maan/Cat_Song"; | |
FMOD.Studio.EventInstance fmodKattoeMusicInstance; | |
public void Init (Transform[] trackPieces, Maan maan) | |
{ | |
if (_firstTimeInit) { | |
_trackPieces = trackPieces; | |
_firstTimeInit = false; | |
} | |
this.maan = maan; | |
postProcessingVolume = maan.transform.GetComponentInChildren<PostProcessVolume>(); | |
kattoeParent = new GameObject("KattoeParent").transform; | |
//Populate the level with kattoes | |
kattoes = new List<Kattoe>(); | |
occupiedPieces = new List<Transform>(); | |
Transform[] spawnPositions = Util.PickRandom(activeKattoes, false, trackPieces); | |
for (int i = 0; i < activeKattoes; i++) { | |
kattoes.Add(CreateKattoe(spawnPositions[i])); | |
occupiedPieces.Add(spawnPositions[i]); | |
} | |
cloudState = CloudStates.Dormant; | |
fmodCloudInstance = RuntimeManager.CreateInstance(fmodCloudPath); | |
fmodCloudInstance.getParameter("Stress", out fmodCloudStateParameter); | |
fmodKattoeMusicInstance = RuntimeManager.CreateInstance(fmodKattoeMusicPath); | |
fmodKattoeMusicInstance.start(); | |
} | |
public void Deactivate () | |
{ | |
StopAllCoroutines(); | |
Destroy(kattoeParent.gameObject); | |
cloudActive = false; | |
if (_cloudTrans != null) | |
Destroy(_cloudTrans.gameObject); | |
maan.Destroy(); | |
} | |
private void Update () | |
{ | |
if (!StaticData.menuActive) { | |
if (cloudActive) { | |
CloudBehaviour(); | |
CloudAudio(); | |
} | |
Happiness(); | |
} | |
} | |
void Happiness () | |
{ | |
//Override happiness for debugging | |
if (Input.GetKeyDown(KeyCode.Space)) | |
happinessOverride = !happinessOverride; | |
if (!happinessOverride) { | |
float targetHappiness = 0; | |
//Kevin | |
if (StaticData.playersAreLinked) | |
targetHappiness += happinessWhenLinked; | |
//Cloud | |
if (cloudState != CloudStates.Dormant) { | |
float distanceMaanToCloud = Vector3.Distance(maan.transform.position, _cloudTrans.position); | |
if (distanceMaanToCloud >= happinessCloudFarDistance) { | |
if (StaticData.playersAreLinked) { | |
targetHappiness += happinessGoodCloudFar; | |
} else { | |
targetHappiness += happinessBadCloudFar; | |
} | |
} else if (distanceMaanToCloud <= happinessCloudNearDistance) { | |
if (StaticData.playersAreLinked) { | |
targetHappiness += happinessGoodCloudNear; | |
} else { | |
targetHappiness += happinessBadCloudNear; | |
} | |
} else { | |
float factor = 1 - (distanceMaanToCloud - happinessCloudNearDistance) / (happinessCloudFarDistance - happinessCloudNearDistance); | |
if (StaticData.playersAreLinked) { | |
targetHappiness += (factor * (happinessGoodCloudNear - happinessGoodCloudFar)) + happinessGoodCloudFar; | |
} else { | |
targetHappiness += (factor * (happinessBadCloudNear - happinessBadCloudFar)) + happinessBadCloudFar; | |
} | |
} | |
} | |
//Kattoes | |
targetHappiness += happinessPerKattoe * maan.KattoesBonded; | |
//Calculate actual happiness | |
_happiness = Mathf.MoveTowards(_happiness, targetHappiness, happinessGrowthRate * Time.deltaTime); | |
_happiness = Mathf.Clamp(_happiness, -1, 1); | |
} | |
//Happiness manual override | |
else { | |
Debug.Log("Happiness override active. Value: " + _happiness.ToString()); | |
if (Input.GetKey(KeyCode.LeftArrow)) { | |
_happiness -= Time.deltaTime * .5f; | |
} else if (Input.GetKey(KeyCode.RightArrow)) { | |
_happiness += Time.deltaTime * .5f; | |
} | |
_happiness = Mathf.Clamp(_happiness, -1, 1); | |
} | |
//Apply happiness | |
//PostProcessing | |
if (_happiness >= 0) { | |
postProcessingVolume.profile = ppHappyProfile; | |
} else { | |
postProcessingVolume.profile = ppSadProfile; | |
} | |
postProcessingVolume.weight = Mathf.Abs(_happiness); | |
//ScreenShake | |
if (_happiness <= -happinessScreenShakeThreshold) { | |
float screenShakeIntensity = (Mathf.Abs(_happiness) - happinessScreenShakeThreshold) / (1 - happinessScreenShakeThreshold); | |
maan.ScreenShake(screenShakeIntensity); | |
} else { | |
maan.ScreenShake(0); | |
} | |
//KattoeMusic | |
float desiredVolume = 0; | |
if (_happiness < happinessMusicThreshold) { | |
desiredVolume = 0; | |
} else if (_happiness > happinessMusicMaxThreshold) { | |
desiredVolume = 1; | |
} else { | |
desiredVolume = .7f; | |
} | |
_happinessMusicVolume = Mathf.MoveTowards(_happinessMusicVolume, desiredVolume, happinessMusicVolumeGrowthRate * Time.deltaTime); | |
fmodKattoeMusicInstance.setVolume(_happinessMusicVolume); | |
} | |
Kattoe CreateKattoe (Transform parentPiece) | |
{ | |
Kattoe newKattoe = Instantiate(Util.PickRandom(kattoePrefabs), parentPiece.position, Quaternion.identity).GetComponent<Kattoe>(); | |
newKattoe.Init(this, maan.transform, parentPiece); | |
newKattoe.transform.parent = kattoeParent; | |
return newKattoe; | |
} | |
public void KattoeRanAway (Kattoe kattoe, Transform parentPiece) | |
{ | |
kattoes.Remove(kattoe); | |
occupiedPieces.Remove(parentPiece); | |
StartCoroutine(ReplaceKattoe()); | |
} | |
IEnumerator ReplaceKattoe () | |
{ | |
yield return new WaitForSeconds(9); | |
Transform pieceAttempt = Util.PickRandom(_trackPieces); | |
while (occupiedPieces.Contains(pieceAttempt)) { | |
pieceAttempt = Util.PickRandom(_trackPieces); | |
} | |
kattoes.Add(CreateKattoe(pieceAttempt)); | |
} | |
void CloudBehaviour () | |
{ | |
switch (cloudState) { | |
case CloudStates.Dormant: | |
if (!cloudDormantSetup) { | |
_cloudDormantTimer = 0; | |
cloudDormantTime = Random.Range(cloudMinTimeBeforeSpawn, cloudMaxTimeBeforeSpawn); | |
cloudDormantSetup = true; | |
} | |
_cloudDormantTimer += Time.deltaTime; | |
if (_cloudDormantTimer > cloudDormantTime) { | |
StartCoroutine(SpawnCloud()); | |
cloudDormantSetup = false; | |
cloudState = CloudStates.Waiting; | |
goto case CloudStates.Waiting; | |
} | |
break; | |
case CloudStates.Waiting: | |
if (!cloudWaitingSetup) { | |
_cloudWaitingTimer = 0; | |
cloudWaitingTime = Random.Range(minTimeBeforeCloudChase, maxTimeBeforeCloudChase); | |
cloudWaitingSetup = true; | |
} | |
_cloudWaitingTimer += Time.deltaTime; | |
if (_cloudWaitingTimer > cloudWaitingTime) { | |
cloudChaseSetup = false; | |
cloudState = CloudStates.Chasing; | |
goto case CloudStates.Chasing; | |
} | |
break; | |
case CloudStates.Chasing: | |
if (!cloudChaseSetup) { | |
_cloudChaseSpeed = cloudChaseBaseSpeed; | |
cloudChaseSetup = true; | |
} | |
_cloudChaseSpeed += cloudChaseAcceleration * Time.deltaTime; | |
float distanceCloudToMaan = Vector3.Distance(maan.transform.position, _cloudTrans.position); | |
Vector3 _cloudPosition = _cloudTrans.position; | |
_cloudPosition.y = Mathf.MoveTowards(_cloudPosition.y, cloudChasingHeight, cloudDescendSpeed * Time.deltaTime); | |
Vector2 lateralCloudPos = new Vector2(_cloudPosition.x, _cloudPosition.z); | |
lateralCloudPos = Vector2.MoveTowards(lateralCloudPos, new Vector2(maan.transform.position.x, maan.transform.position.z), _cloudChaseSpeed * Time.deltaTime); | |
_cloudPosition.x = lateralCloudPos.x; | |
_cloudPosition.z = lateralCloudPos.y; | |
_cloudTrans.position = _cloudPosition; | |
_cloudTrans.LookAt(maan.transform); | |
//Check proximity to Maan and impact if close enough | |
if (distanceCloudToMaan < cloudChasingDistanceToImpact) { | |
if (!StaticData.playersAreLinked) { | |
StartCoroutine(maan.FadeToBlack(cloudImpactFadeTimeBad, Color.black)); | |
} | |
Destroy(_cloudTrans.gameObject); | |
cloudChaseSetup = false; | |
fmodCloudInstance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT); | |
_fmodCloudPlaying = false; | |
cloudState = CloudStates.Dormant; | |
goto case CloudStates.Dormant; | |
} | |
break; | |
} | |
} | |
void CloudAudio () | |
{ | |
if (cloudState != CloudStates.Dormant) { | |
float distanceMaanToCloud = Vector3.Distance(cloud.transform.position, maan.transform.position); | |
if (StaticData.playersAreLinked) { | |
_fmodCloudState = Mathf.MoveTowards(_fmodCloudState, 0, Time.deltaTime * 2); | |
} else { | |
_fmodCloudState = Mathf.MoveTowards(_fmodCloudState, 1, Time.deltaTime * 2); | |
} | |
fmodCloudStateParameter.setValue(_fmodCloudState); | |
} | |
} | |
IEnumerator SpawnCloud () | |
{ | |
Vector2 randomRadius = Random.insideUnitCircle.normalized * cloudSpawnDistance; | |
Vector3 spawnPos = new Vector3(maan.transform.position.x + randomRadius.x, cloudSpawningHeight, maan.transform.position.z + randomRadius.y); | |
_cloudTrans = Instantiate(cloudPrefab, spawnPos, Quaternion.identity).transform; | |
cloud = _cloudTrans.GetComponent<Cloud>(); | |
RuntimeManager.AttachInstanceToGameObject(fmodCloudInstance, _cloudTrans, _cloudTrans.GetComponent<Rigidbody>()); | |
fmodCloudInstance.start(); | |
//Clouse rises up before starting chase | |
float _riseTime = (cloudWaitingHeight - cloudSpawningHeight) / cloudWaitingSpeed; | |
for (float t = 0; t < _riseTime; t += Time.deltaTime) { | |
_cloudTrans.position += Vector3.up * cloudWaitingSpeed * Time.deltaTime; | |
yield return null; | |
} | |
} | |
public void ActivateCloud () | |
{ | |
cloudActive = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment