184 lines
6.1 KiB
C#
184 lines
6.1 KiB
C#
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<Rigidbody>();
|
|
|
|
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<Collider>().material = defaultMaterial;
|
|
break;
|
|
case FrisbieType.Boomerang:
|
|
GetComponent<Collider>().material = boomerangMaterial;
|
|
break;
|
|
case FrisbieType.Explosive:
|
|
GetComponent<Collider>().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;
|
|
}
|
|
}
|
|
}
|
|
}
|