using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class Player : Manager { public float ThrustForce = 10; // in m/s^2 public float SteeringFactor = 10.0f; public float UprightMultiplier = 10.0f; public float DragForce = 0.75f; public AnimationCurve SlopeDragCurve; public Vector3 horizontalVelocity = Vector2.zero; private BoxCollider BenchBoxCollider; [SerializeField] private ParticleSystem thrusterParticleSystemLeft; [SerializeField] private ParticleSystem thrusterParticleSystemRight; public ParticleSystem Explosion; [SerializeField] private float dynamiteCountdownStart = 3.0f; private float dynamiteCountDown; private bool disableInput = false; public float DynamiteCountDown => dynamiteCountDown; public float Fuel = 1.0f; public float FuelConsumptionPerSecond = 0.01f; public float FuelConsumptionPerSecondBase = 0.01f; private float score = 0.0f; public float Score => score; public LayerMask RayLayerMask; IEnumerator SecondDelayInterval() { while(true) { yield return new WaitForSeconds(1.0f); if(dynamiteCountDown > 0) { if(horizontalVelocity.magnitude < 0.1f) { dynamiteCountDown -= 1.0f; AudioManager.Instance.GetAudioSource(AudioClip.CountdownBeep).Play(); } else { dynamiteCountDown = dynamiteCountdownStart; } } if(dynamiteCountDown <= 0) { disableInput = true; dynamiteCountDown = 0; if(GameStateManager.Instance.GameState == GameState.Play) { Debug.Log("GameStateChange => Play => GameOver"); GameStateManager.Instance.SetGameState(GameState.GameOver); } } } } private AudioSource audioSourceSledge; private AudioSource audioSourceSpin; private AudioSource audioSourceRoar; protected void Start() { GameStateManager.Instance.OnGameStateChangedEvent.AddListener(OnGameStateChanged); BenchBoxCollider = GetComponentInChildren(); dynamiteCountDown = dynamiteCountdownStart; audioSourceSpin = AudioManager.Instance.GetAudioSource(AudioClip.TurbineSpin); audioSourceRoar = AudioManager.Instance.GetAudioSource(AudioClip.TurbineRoar); audioSourceSledge = AudioManager.Instance.GetAudioSource(AudioClip.SnowSlideSledge); } public void OnGameStateChanged(GameState newState, GameState oldState) { Debug.Log("OnGameStateChanged "+newState); if(newState == GameState.Play) { StartCoroutine(SecondDelayInterval()); } } protected void OnDestroy() { GameStateManager.Instance.OnGameStateChangedEvent.RemoveListener(OnGameStateChanged); } void FixedUpdate() { var gamepad = Gamepad.current; float throttle = 0; float steering = 0; Vector3 localVelocity = this.transform.InverseTransformDirection(horizontalVelocity); if(!disableInput) { throttle += (Keyboard.current.wKey.ReadValue()) + (Keyboard.current.sKey.ReadValue() * -1.0f); steering += (Keyboard.current.dKey.ReadValue()) + (Keyboard.current.aKey.ReadValue() * -1.0f); if(gamepad != null) { float throttleR = gamepad.rightTrigger.ReadValue(); float throttleL = gamepad.leftTrigger.ReadValue() * -1.0f; throttle += throttleL + throttleR; steering += gamepad.leftStick.ReadValue().x; if(Vector3.Dot(Vector3.forward, localVelocity) < -0.1f) steering *= -1.0f; } } audioSourceRoar.volume = Mathf.Abs(throttle) * 0.75f; audioSourceRoar.pitch = 1.05f; audioSourceSledge.volume = Mathf.Clamp(horizontalVelocity.magnitude, 0.0f, 1.0f); Fuel -= (Mathf.Abs(throttle) * FuelConsumptionPerSecond + FuelConsumptionPerSecondBase) * Time.fixedDeltaTime; if(Fuel <= 0) { Fuel = 0; disableInput = true; } if(disableInput) { audioSourceSpin.volume = 0.0f; audioSourceRoar.volume = 0.0f; } float baseEmission = disableInput ? 0 : 0.1f; thrusterParticleSystemLeft.emissionRate = (baseEmission + (1.0f - baseEmission) * (throttle - steering * -1.0f)) * 300.0f; thrusterParticleSystemRight.emissionRate = (baseEmission + (1.0f - baseEmission) * (throttle - steering)) * 300.0f; this.transform.Rotate(this.transform.up, steering * SteeringFactor * Time.fixedDeltaTime, Space.World); Vector3 forward = this.transform.forward; Vector3 horizontalForward = Vector3.Scale(new Vector3(1.0f, 0.0f, 1.0f), forward); score = Mathf.Round(this.transform.position.z * 1000.0f) / 1000.0f; horizontalVelocity += this.transform.forward * throttle * ThrustForce * Time.fixedDeltaTime; horizontalVelocity -= horizontalVelocity * DragForce * Time.fixedDeltaTime; UIManagerGame.Instance.Fuel = Fuel; UIManagerGame.Instance.CountdownSeconds = (int)dynamiteCountDown; UIManagerGame.Instance.Score = score; this.transform.position += horizontalVelocity; float OFFSET = 0.5f; int OFFSET_COUNT_X = 4; int OFFSET_COUNT_Y = 4; // TODO: Find better way to smoothly slide across the terrain without bump distortions int TOTAL_OFFSET_COUNT = OFFSET_COUNT_X * OFFSET_COUNT_Y; Vector3[] floorRaycastOffsets = new Vector3[TOTAL_OFFSET_COUNT]; for(int x=0;x(); if(o != null) { o.OnHit(this.gameObject); if(o.HitRecoilForce != 0.0f) { this.horizontalVelocity += -(collider.transform.position - this.transform.position).normalized * o.HitRecoilForce; } this.Fuel -= o.DamageOnHit; } PickupItem pu = collider.gameObject.GetComponent(); if(pu != null && pu.PickedUp == false) { this.Fuel += pu.Fuel; if(this.Fuel > 1.0f) this.Fuel = 1.0f; pu.OnPickup(); if(disableInput) disableInput = false; } } }