using System.Collections; using System.Collections.Generic; using UnityEngine; public class FrisbieController : MonoBehaviour, IPooledObject{ [System.Serializable] public enum FrisbieType { Default, Explosive, Boomerang } public FrisbieType frisbieType = default; [Space] [SerializeField, Range(0, 3)] float damageVelocityThreshold = 1.5f; [Header("Default")] [SerializeField] float speed = 10f; Rigidbody rb; [SerializeField] Transform frisbie = default; float heightVelocity; public PhysicMaterial defaultMaterial; [Header("Explosive")] [SerializeField] float explosiveSpeed = 5f; private bool canExplode = false; public float explosionSpeedThreshold = 0.5f; public float explosionRad = 1; public float explosionBlastSpeed = 20; public SphereCollider explosionCol; public PhysicMaterial explosiveMaterial; [Header("Boomerang")] [SerializeField] float boomerangSpeed = 5f; public float boomerangReturnStrength = 5; private Vector3 boomerangReturnDir = Vector3.zero; public PhysicMaterial boomerangMaterial; [Space] [SerializeField, Range(0, 1)] float pickUpEnableDelay = .3f; [SerializeField] GameObject pickUpCollider = default; [SerializeField] GameObject[] disks = default; void Awake(){ rb = GetComponent(); if (PlayerPrefs.HasKey("Disk")){ for (int i = 0; i < disks.Length; i++){ if (PlayerPrefs.GetInt("Disk") != i){ disks[i].SetActive(false); } } }else{ PlayerPrefs.SetInt("Disk", 0); for (int i = 0; i < disks.Length; i++){ if(PlayerPrefs.GetInt("Disk") != i){ disks[i].SetActive(false); } } } } void OnValidate() { explosionCol.radius = explosionRad; } public void OnObjectSpawn(){ explosionCol.enabled = false; gameObject.tag = "Disk"; rb.velocity = Vector3.zero; switch (frisbieType) { case FrisbieType.Default: GetComponent().material = defaultMaterial; break; case FrisbieType.Boomerang: GetComponent().material = boomerangMaterial; break; case FrisbieType.Explosive: GetComponent().material = explosiveMaterial; break; } boomerangReturnDir = transform.forward * -1; if(pickUpCollider != null) pickUpCollider.SetActive(false); StartCoroutine(EnablePickUpCollider()); } public void AddForce(Vector3 velocity){ //rb.velocity = velocity / 2; //rb.velocity = new Vector3(velocity.x, 0, velocity.z) / 2; switch (frisbieType){ case FrisbieType.Default: rb.AddForce(transform.forward.normalized * speed, ForceMode.Impulse); break; case FrisbieType.Explosive: rb.AddForce(transform.forward.normalized * explosiveSpeed, ForceMode.Impulse); break; case FrisbieType.Boomerang: rb.AddForce(transform.forward.normalized * boomerangSpeed, ForceMode.Impulse); break; } } void FixedUpdate(){ float velocity = rb.velocity.magnitude; float positionToGo = 0; if(velocity < damageVelocityThreshold) gameObject.tag = "Untagged"; else gameObject.tag = "Disk"; switch (frisbieType) { case FrisbieType.Default: positionToGo = Mathf.SmoothDamp(frisbie.localPosition.y, -1 + velocity / speed, ref heightVelocity, .1f); frisbie.localPosition = new Vector3(0, positionToGo, 0); break; case FrisbieType.Boomerang: if (boomerangReturnDir != Vector3.zero) rb.AddForce(boomerangReturnDir * Mathf.Lerp(0, boomerangReturnStrength, 1), ForceMode.Acceleration); else { positionToGo = Mathf.SmoothDamp(frisbie.localPosition.y, -1 + velocity / speed, ref heightVelocity, .5f); frisbie.localPosition = new Vector3(0, positionToGo, 0); } break; case FrisbieType.Explosive: positionToGo = Mathf.SmoothDamp(frisbie.localPosition.y, -1 + velocity / speed, ref heightVelocity, .1f); frisbie.localPosition = new Vector3(0, positionToGo, 0); if (velocity < explosionSpeedThreshold) Kaboom(); break; } } void Kaboom() { if (canExplode) { explosionCol.enabled = true; ObjectPooler.instance.SpawnFromPool("Explosion", transform.position); //Harm all enemies within explosionCol if (Random.value > 0.5f) { ObjectPooler.instance.SpawnFromPool("DiskBits", transform.position); gameObject.SetActive(false); } else { Vector3 explosionDir = Random.onUnitSphere; explosionDir.y = 1; explosionDir.Normalize(); rb.velocity = Vector3.zero; AddForce(explosionDir * explosionBlastSpeed); } canExplode = false; } } IEnumerator EnablePickUpCollider(){ yield return new WaitForSeconds(pickUpEnableDelay); if (pickUpCollider != null) pickUpCollider.SetActive(true); canExplode = true; } private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Wall")) { switch (frisbieType) { case FrisbieType.Default: break; case FrisbieType.Boomerang: boomerangReturnDir = Vector3.zero; break; case FrisbieType.Explosive: Invoke(nameof(Kaboom), .05f); break; } } } }