using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Lemon.GenericLib.VFX { public class CameraController : MonoBehaviour { public static CameraController instanceCC; [SerializeField] Camera cam; [SerializeField] Transform player; [SerializeField] float shootshakeDuration = 0.2f; private Vector2 originalPosition; Vector3 target, mousePos, refVel, shkeOffset; float cameraDist = 2.5f; float smoothTime = 0.2f; [SerializeField] float shootShakeMagnitude = 2; Vector3 shootShakeDirection = Vector3.zero; float shootShakeTimeEnd = 0; bool shootshake = false; [SerializeField] float shakePower; [SerializeField] float smallShakeMultiplier; [SerializeField] Vector2 screenshakeOffset = Vector2.zero; //private Game_Manager gameManager; //singleton pattern private void Awake() { if (instanceCC == null) { instanceCC = this; } if (instanceCC != this) { Destroy(gameObject); } } public void SetPlayer(Transform playerTransform) { player = playerTransform; } // Start is called before the first frame update void Start() { //cb = GetComponent(); //gameManager = Game_Manager.instanceGM; cam = Camera.main; originalPosition = transform.position; //player = FindObjectOfType()?.transform; screenshakeOffset = Vector2.zero; //gameManager.ChangeGameStateEvent += HandleGameStateChanges; } ////not working currently for some reason //private void HandleGameStateChanges(object sender, Game_Manager.ChangeGameStateArgs e) //{ // //Debug.Log("finding player"); // if (e.newState == Game_Manager.GameState.gameplay) { // Invoke("FindPlayer", 0.01f); // } //} void FindPlayer() { Debug.Log("finding player"); //player = FindObjectOfType()?.transform; } Vector3 shootShakeOffset = Vector3.zero; // Update is called once per frame void Update() { Vector3 destinationPos = originalPosition; //Vector3 destinationPos = transform.position; //if (player != null) //{ // mousePos = GetMousePos(); // target = UpdateTargetPos(); // Vector3 tempPos; // tempPos = Vector3.SmoothDamp(transform.position, target, ref refVel, smoothTime); // transform.position = tempPos; // //mouse distance thing // Vector2 playerPos = Vector3.zero; // destinationPos = Vector2.Lerp(originalPosition, playerPos, 0.2f); // Vector2 MousePos = cam.ScreenToWorldPoint(Input.mousePosition); // Vector3 mouseDistance = MousePos - playerPos; // mouseDistance = Vector3.Lerp(Vector3.zero, mouseDistance, 0.05f); // mouseDistance.z = 0; if (!shootshake || Time.time >= shootShakeTimeEnd) { shootshake = false; //Debug.Log("not shaking"); shootShakeOffset = Vector3.Lerp(shootShakeOffset, Vector3.zero, 15 * Time.deltaTime); } else { //Debug.Log(" shaking"); shootShakeOffset = Vector3.Lerp(shootShakeOffset, shootShakeDirection * shootShakeMagnitude, 15 * Time.deltaTime); } destinationPos.z = -10; transform.position = destinationPos + (Vector3)screenshakeOffset + shootShakeOffset; //} //else //{ // destinationPos = Vector2.Lerp(transform.position, originalPosition, 0.2f); // destinationPos.z = -10; // transform.position = destinationPos + (Vector3)screenshakeOffset; //} } public Vector3 UpdateTargetPos() { Vector3 mouseOffset = mousePos * cameraDist; Vector3 ret = player.position + mouseOffset; ret.z = -10; return ret; } public Vector3 GetMousePos() { Vector2 ret = cam.ScreenToViewportPoint(Input.mousePosition); ret *= 2; ret -= Vector2.one; float max = 0.9f; if (Mathf.Abs(ret.x) > max || Mathf.Abs(ret.y) > max) { ret = ret.normalized; } return ret; } public void ApplyShootShake(float duration, Vector3 direction) { shootshake = true; shootShakeDirection = direction; //yield return new WaitForSeconds(duration); shootShakeTimeEnd = Time.time + duration; } public void ApplyShootShake(float angle, float power) { shootshake = true; shootShakeDirection = (new Vector3((float)Mathf.Cos(angle * Mathf.Deg2Rad), (float)Mathf.Sin(angle * Mathf.Deg2Rad))).normalized; //yield return new WaitForSeconds(duration); shootShakeTimeEnd = Time.time + shootshakeDuration; } public void ApplyShootShake(float angle) { shootshake = true; shootShakeDirection = (new Vector3((float)Mathf.Cos(angle * Mathf.Deg2Rad), (float)Mathf.Sin(angle * Mathf.Deg2Rad))).normalized; //yield return new WaitForSeconds(duration); shootShakeTimeEnd = Time.time + shootshakeDuration; } public void ApplyShootShake(Vector3 direction) { shootshake = true; shootShakeDirection = direction; //yield return new WaitForSeconds(duration); shootShakeTimeEnd = Time.time + shootshakeDuration; } public void ApplyScreenShake(float duration = 0.1f, bool isSmall = false) { StopCoroutine("Screenshake"); StartCoroutine(Screenshake(duration, isSmall)); } public void ApplyScreenShake(float duration, float newShakePower, bool isSmall = false) { //cb.enabled = false; StopCoroutine("Screenshake"); StartCoroutine(Screenshake(duration, newShakePower, isSmall)); } IEnumerator Screenshake(float duration, bool isSmall = false) { screenshakeOffset = Vector2.zero; //originalPosition = transform.position; //cb.enabled = false; //Debug.Log("shake " + cb.enabled); float currentShakePower = shakePower; if (isSmall) currentShakePower *= smallShakeMultiplier; float shakeFadeTime = currentShakePower / duration; while (duration > 0) { float xOffset = Random.Range(-1f, 1f) * currentShakePower; float yOffset = Random.Range(-1f, 1f) * currentShakePower; screenshakeOffset.x = xOffset; screenshakeOffset.y = yOffset; duration -= Time.deltaTime; currentShakePower = Mathf.MoveTowards(shakePower, 0f, shakeFadeTime * Time.deltaTime); yield return null; } screenshakeOffset = Vector2.zero; // cb.enabled = true; } IEnumerator Screenshake(float duration, float thisShakePower, bool isSmall = false) { screenshakeOffset = Vector2.zero; float currentShakePower = thisShakePower; if (isSmall) currentShakePower *= smallShakeMultiplier; float shakeFadeTime = currentShakePower / duration; while (duration > 0) { float xOffset = Random.Range(-1f, 1f) * currentShakePower; float yOffset = Random.Range(-1f, 1f) * currentShakePower; screenshakeOffset.x = xOffset; screenshakeOffset.y = yOffset; duration -= Time.deltaTime; currentShakePower = Mathf.MoveTowards(shakePower, 0f, shakeFadeTime * Time.deltaTime); yield return null; } screenshakeOffset = Vector2.zero; } public void HitPause(float duration = 0.05f) { Time.timeScale = 1; StopCoroutine("HitPauseRoutine"); StartCoroutine(HitPauseRoutine(duration)); } IEnumerator HitPauseRoutine(float duration) { // Debug.LogError("FUCK"); Time.timeScale = 0; yield return new WaitForSecondsRealtime(duration); Time.timeScale = 1; } } }