using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public enum PowerLevelLabel { Low, Mid, High } public class Player : MonoBehaviour { [SerializeField] private float powerLevel; private Color _powerLevelLow = Color.red; private Color _powerLevelMid = new Color(255, 165, 0); private Color _powerLevelHigh = Color.green; private GameObject[] _powerUp = new GameObject[3]; private GameObject[] _powerDown = new GameObject[3]; public static AudioSource AudioSource; public AudioClip shootSound; public float PowerLevel { get { return powerLevel; } set { float offset = value - powerLevel; powerLevel = value; powerLevel = Mathf.Clamp(powerLevel, 0, powerLevelMax); UpdatePowerBar(); UpdatePowerIndicator(offset); } } public float PowerFactor { get { return powerLevel / powerLevelMax; } } public PowerLevelLabel PowerLevelName { get { if (PowerFactor >= 0 && PowerFactor < 1.0f / 3.0f) { return PowerLevelLabel.Low; } if (PowerFactor >= 1.0f / 3.0f && PowerFactor < 2.0f / 3.0f) { return PowerLevelLabel.Mid; } if (PowerFactor >= 2.0f / 3.0f && PowerFactor <= 1.0f) { return PowerLevelLabel.High; } return PowerLevelLabel.Low; } } private Color _powerLevelColor { get { switch (PowerLevelName) { case PowerLevelLabel.Low: { return _powerLevelLow; }; case PowerLevelLabel.Mid: { return _powerLevelMid; }; case PowerLevelLabel.High: { return _powerLevelHigh; }; } return Color.white; } } private void UpdatePowerBar() { gauge.Find("PowerBar").transform.localScale = new Vector3(1, PowerFactor, 1); gauge.GetComponentInChildren().material.color = _powerLevelColor; } float goodIndicatorTimeOut = 0; float badIndicatorTimeOut = 0; private void UpdatePowerIndicator(float offset) { if (offset < 0) { if (Mathf.Abs(offset) > 0) _powerDown[2].SetActive(true); if (Mathf.Abs(offset) >= bulletDegenRate) _powerDown[1].SetActive(true); if (Mathf.Abs(offset) >= 0.95) _powerDown[0].SetActive(true); badIndicatorTimeOut = 1.5f; } else { if (Mathf.Abs(offset) > 0) _powerUp[2].SetActive(true); if (Mathf.Abs(offset) > 0.45) _powerUp[1].SetActive(true); if (Mathf.Abs(offset) > 0.95) _powerUp[0].SetActive(true); goodIndicatorTimeOut = 1.5f; } } private void UpdatePowerIndicatorTimeout(ref float timeOut, GameObject[] powerIndicators) { if (timeOut > 0) { timeOut -= Time.deltaTime; } if (timeOut < 0) { for (int i = 0; i < 3; i++) { powerIndicators[i].SetActive(false); } timeOut = 0; } } private float walkingDegenTimer = 1.5f; private void UpdateWalkingDegen(float speed) { if (speed > 0.1) { if (walkingDegenTimer == 0) { PowerLevel -= movementDegenRate; walkingDegenTimer = 1.5f; } if (walkingDegenTimer > 0) { walkingDegenTimer -= Time.deltaTime; } if (walkingDegenTimer < 0) { walkingDegenTimer = 0f; } } if (speed <= 0.1) { walkingDegenTimer = 0; } //Debug.Log(speed + ", " + walkingDegenTimer); } public float movementDegenRate = 0.1f; public float bulletDegenRate = 0.2f; public float startSpeed = 5f; public float lookSmoothingSeconds = 0.05f; public float cameraSmoothingSeconds = 1; public float bulletUpBias = 0.1f; public float bulletForce = 10f; public float powerLevelMax = 8.0f; public Transform gunTransform; public Rigidbody bulletPrefab; public Light muzzleLight; public Light headLight; public Transform gauge; public DayTimeManager dayTimeManager; private Vector3 inputDirection; private float speed; private Vector3 lookDirection; private float deadZone = 0.1f; private Vector3 lookVelocity; private Vector3 cameraOffset; private Vector3 cameraVelocity; private bool shooting = false; private float lightIntensity; private bool useMouseLook; // Use this for initialization void Start() { speed = startSpeed; cameraOffset = Camera.main.transform.position - transform.position; lightIntensity = muzzleLight.intensity; muzzleLight.intensity = 0; var joystickNames = Input.GetJoystickNames(); useMouseLook = joystickNames.Length == 0 || string.IsNullOrEmpty(joystickNames[0]); //if (useMouseLook) //{ // lookSmoothingSeconds = 0; //} _powerUp[0] = gauge.Find("PowerUp1").gameObject; _powerUp[1] = gauge.Find("PowerUp2").gameObject; _powerUp[2] = gauge.Find("PowerUp3").gameObject; _powerDown[0] = gauge.Find("PowerDown1").gameObject; _powerDown[1] = gauge.Find("PowerDown2").gameObject; _powerDown[2] = gauge.Find("PowerDown3").gameObject; for (int i = 0; i < 3; i++) { _powerUp[i].SetActive(false); _powerDown[i].SetActive(false); } AudioSource = GetComponent(); } // Update is called once per frame void Update() { // TODO lerp movement direction GetInput(); if (lookDirection.magnitude > deadZone) transform.forward = Vector3.SmoothDamp(transform.forward, lookDirection, ref lookVelocity, lookSmoothingSeconds); transform.position += inputDirection * speed * Time.deltaTime; UpdatePowerBar(); UpdatePowerIndicatorTimeout(ref goodIndicatorTimeOut, _powerUp); UpdatePowerIndicatorTimeout(ref badIndicatorTimeOut, _powerDown); UpdateWalkingDegen(inputDirection.magnitude); Camera.main.transform.position = Vector3.SmoothDamp(Camera.main.transform.localPosition, TargetCameraPosition(), ref cameraVelocity, cameraSmoothingSeconds); if (shooting) { Shoot(); StartCoroutine(FlashMuzzle()); } headLight.intensity = (dayTimeManager.dayTimeLabel == DayTimeLabel.Night || dayTimeManager.dayTimeLabel == DayTimeLabel.Evening) ? .5f : 0; } private IEnumerator FlashMuzzle() { float start = .1f; float initial = UnityEngine.Random.Range(.5f, 2f) * lightIntensity; for (float left = start; left > 0; left -= Time.deltaTime) { muzzleLight.intensity = Mathf.Lerp(initial, 0, left / start); yield return null; } muzzleLight.intensity = 0; } public float fidgetSpin = 30.0f; int bulletCounter = 5; private float chargingStart; public float maxChargingTime; public float maxBulletForce; private void Shoot() { var rb = Instantiate(bulletPrefab); rb.transform.position = gunTransform.position; rb.transform.forward = gunTransform.forward; rb.maxAngularVelocity = 300; rb.AddTorque(transform.up * fidgetSpin, ForceMode.VelocityChange); rb.AddForce( Mathf.Lerp(bulletForce, maxBulletForce, (Time.time - chargingStart) / maxChargingTime) * (transform.forward + Vector3.up * bulletUpBias), ForceMode.VelocityChange); Destroy(rb.gameObject, 2f); if (bulletCounter == 5) { PowerLevel -= bulletDegenRate; } if (bulletCounter >= 0) { bulletCounter--; } if (bulletCounter < 0) { bulletCounter = 5; } AudioSource.pitch = 1.5f; AudioSource.clip = shootSound; AudioSource.Play(); AudioSource.pitch = 1.0f; } private Vector3 TargetCameraPosition() { return transform.position + cameraOffset; } void GetInput() { if (Input.GetButtonDown("Fire1")) { chargingStart = Time.time; } shooting = Input.GetButtonUp("Fire1"); var padLook = new Vector3( Input.GetAxis("LookX"), 0, -Input.GetAxis("LookY") ); if (useMouseLook) { var mouseLook = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position); mouseLook.Normalize(); lookDirection = new Vector3(mouseLook.x, 0, mouseLook.y); } else if (padLook.magnitude > 0.2f) { lookDirection = padLook.normalized; } inputDirection = new Vector3( Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical") ).normalized; } }