init
This commit is contained in:
commit
341a877b4a
2338 changed files with 1346408 additions and 0 deletions
246
Assets/Scripts/Enemies/BossBehaviour.cs
Normal file
246
Assets/Scripts/Enemies/BossBehaviour.cs
Normal file
|
@ -0,0 +1,246 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
[System.Serializable]
|
||||
public class BossState
|
||||
{
|
||||
[Range(0, 101)]
|
||||
public float healthActivation;
|
||||
public float activityTime;
|
||||
public float recoverTime;
|
||||
public ShootingPattern.ShootingStyle[] turretStyle=new ShootingPattern.ShootingStyle[7];
|
||||
public BulletMovement.BulletMovementType[] bulletStyle=new BulletMovement.BulletMovementType[7];
|
||||
|
||||
[HideInInspector]
|
||||
public bool used = false;
|
||||
|
||||
|
||||
public BossState()
|
||||
{
|
||||
turretStyle = new ShootingPattern.ShootingStyle[7];
|
||||
bulletStyle = new BulletMovement.BulletMovementType[7];
|
||||
}
|
||||
}
|
||||
|
||||
public class BossBehaviour : MonoBehaviour
|
||||
{
|
||||
[Header("Imperative references")]
|
||||
public SkinnedMeshRenderer myMesh;
|
||||
public TurretCoil_Behaviour[] turrets;
|
||||
public Image sheenImage;
|
||||
public UnityEvent harmEv;
|
||||
public UnityEvent dieEv;
|
||||
|
||||
[Header("General settings")]
|
||||
public float HP = 100;
|
||||
public int damageTaken = 2;
|
||||
public bool startPassive = false;
|
||||
public BossState[] states;
|
||||
|
||||
public Transform pantalla;
|
||||
|
||||
private BossState currentState;
|
||||
public BossState CurrentState
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentState;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (flashInProcess)
|
||||
{
|
||||
myMesh.material.SetColor("EmissiveCol", Color.black);
|
||||
flashInProcess = false;
|
||||
}
|
||||
StopAllCoroutines();
|
||||
currentState = value;
|
||||
for(int i=0; i<turrets.Length; ++i)
|
||||
{
|
||||
turrets[i].Pattern = ShootingPattern.styleToPattern(currentState.turretStyle[i]);
|
||||
turrets[i].bulletMovementType = currentState.bulletStyle[i];
|
||||
|
||||
turrets[i].Deploy(currentState.turretStyle[i] != ShootingPattern.ShootingStyle.None);
|
||||
}
|
||||
|
||||
StartCoroutine(setTurretsState(false, currentState.activityTime));
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator setTurretsState(bool state, float time)
|
||||
{
|
||||
yield return new WaitForSeconds(time);
|
||||
if (HP > 0)
|
||||
{
|
||||
foreach (TurretCoil_Behaviour tc in turrets)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
tc.startShooting();
|
||||
}
|
||||
else
|
||||
{
|
||||
tc.stopShooting();
|
||||
}
|
||||
}
|
||||
StartCoroutine(setTurretsState(!state, !state ? currentState.recoverTime : currentState.activityTime));
|
||||
}
|
||||
}
|
||||
|
||||
bool musicStarted = false;
|
||||
private void Start()
|
||||
{
|
||||
AudioManager.instance.StopAll();
|
||||
currentState = new BossState();
|
||||
if (!startPassive)
|
||||
{
|
||||
Invoke(nameof(checkStateChange), 0.2f);
|
||||
|
||||
musicStarted = true;
|
||||
AudioManager.instance.Play("boss2");
|
||||
AudioManager.instance.PlayMuted("boss3");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (TurretCoil_Behaviour tc in turrets)
|
||||
{
|
||||
tc.Deploy(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Application.isEditor)
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
Harm(33);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCollisionEnterChild(Collision collision)
|
||||
{
|
||||
if (collision.gameObject.CompareTag("Disk"))
|
||||
Harm(damageTaken);
|
||||
}
|
||||
|
||||
bool modoDiablo = false;
|
||||
void Harm(int damage= 2)
|
||||
{
|
||||
if (HP > 0)
|
||||
{
|
||||
if (!musicStarted)
|
||||
{
|
||||
musicStarted = true;
|
||||
AudioManager.instance.Play("boss2");
|
||||
AudioManager.instance.PlayMuted("boss3");
|
||||
}
|
||||
HP -= damage;
|
||||
ScreenShakeCall.instance.ShakeCamera(2, .25f);
|
||||
if (HP > 0)
|
||||
checkStateChange();
|
||||
else
|
||||
Die();
|
||||
StartCoroutine(bodyFlash());
|
||||
harmEv.Invoke();
|
||||
|
||||
if (HP < 35 && !modoDiablo)
|
||||
{
|
||||
modoDiablo = true;
|
||||
AudioManager.instance.FadeMutedIn("boss3", 2, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool flashInProcess = false;
|
||||
IEnumerator bodyFlash()
|
||||
{
|
||||
flashInProcess = true;
|
||||
myMesh.material.SetColor("EmissiveCol", Color.white * .75f);
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
flashInProcess = false;
|
||||
myMesh.material.SetColor("EmissiveCol", Color.black);
|
||||
}
|
||||
|
||||
void Die()
|
||||
{
|
||||
GameMaster.Instance.player.GetComponent<PlayerController>().invencible = true;
|
||||
StartCoroutine(keepSpawningExplosions(.15f));
|
||||
dieEv.Invoke();
|
||||
LeanTween.color(sheenImage.GetComponent<RectTransform>(), Color.white, 3).setOnComplete(resetSheen).setDelay(.5f);
|
||||
Invoke(nameof(wipeAllBullets), 3.5f);
|
||||
GameMaster.Instance.player.GetComponent<PlayerController>().bossKilled = true;
|
||||
|
||||
StartCoroutine(AudioManager.instance.FadeOut("boss2", 1));
|
||||
StartCoroutine(AudioManager.instance.FadeOut("boss3", 1));
|
||||
Invoke(nameof(StopAllSongs), 1);
|
||||
}
|
||||
|
||||
void StopAllSongs()
|
||||
{
|
||||
AudioManager.instance.StopAll();
|
||||
}
|
||||
|
||||
IEnumerator keepSpawningExplosions(float t)
|
||||
{
|
||||
spawnExplosion();
|
||||
yield return new WaitForSeconds(t);
|
||||
StartCoroutine(keepSpawningExplosions(t));
|
||||
}
|
||||
|
||||
void spawnExplosion()
|
||||
{
|
||||
ObjectPooler.instance.SpawnFromPool("BossExplosion", pantalla.position+new Vector3(Random.Range(-2, 2), Random.Range(-1.5f, 1.5f), 0));
|
||||
|
||||
ScreenShakeCall.instance.ShakeCamera(3, .25f);
|
||||
}
|
||||
|
||||
void wipeAllBullets()
|
||||
{
|
||||
foreach (BulletMovement bm in FindObjectsOfType<BulletMovement>())
|
||||
{
|
||||
Destroy(bm.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
void resetSheen()
|
||||
{
|
||||
StopCoroutine(keepSpawningExplosions(.5f));
|
||||
foreach (TurretCoil_Behaviour tc in turrets)
|
||||
{
|
||||
tc.stopShooting();
|
||||
tc.Deploy(false);
|
||||
}
|
||||
LeanTween.color(sheenImage.GetComponent<RectTransform>(), new Color(1, 1, 1, 0), .15f).setDelay(.5f);
|
||||
Invoke(nameof(playerWin), 2);
|
||||
}
|
||||
void playerWin()
|
||||
{
|
||||
GameMaster.Instance.player.GetComponent<PlayerController>().Win();
|
||||
}
|
||||
|
||||
|
||||
void checkStateChange()
|
||||
{
|
||||
BossState auxNewState = null;
|
||||
foreach(BossState bs in states)
|
||||
{
|
||||
if (auxNewState == null || (bs.healthActivation>=HP && !bs.used))
|
||||
{
|
||||
auxNewState = bs;
|
||||
}
|
||||
}
|
||||
|
||||
if (auxNewState != currentState)
|
||||
{
|
||||
if(currentState!=null)
|
||||
currentState.used = true;
|
||||
CurrentState = auxNewState;
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/BossBehaviour.cs.meta
Normal file
11
Assets/Scripts/Enemies/BossBehaviour.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5893a09a179d412479ff172ea1ecd3a9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
217
Assets/Scripts/Enemies/BossFaceController.cs
Normal file
217
Assets/Scripts/Enemies/BossFaceController.cs
Normal file
|
@ -0,0 +1,217 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum Expression
|
||||
{
|
||||
Idle, Talk, Angry, Laugh
|
||||
}
|
||||
|
||||
public class BossFaceController : MonoBehaviour
|
||||
{
|
||||
public BossBehaviour boss;
|
||||
|
||||
[MinMaxCustomSlider]
|
||||
public ValueRange moodChangeTime;
|
||||
|
||||
public Expression startExpression;
|
||||
|
||||
public Texture Idle;
|
||||
public Texture IdleGlitch;
|
||||
public Texture Angry;
|
||||
public Texture AngryGlitch;
|
||||
public Texture Talk;
|
||||
public Texture TalkGlitch;
|
||||
public Texture Laugh;
|
||||
public Texture Damage;
|
||||
|
||||
private Material mat;
|
||||
private Texture Tex
|
||||
{
|
||||
set
|
||||
{
|
||||
mat.SetTexture("_FaceTexture", value);
|
||||
if (value == Talk || value == TalkGlitch)
|
||||
{
|
||||
mat.SetFloat("_Cols", 10);
|
||||
StartCoroutine(playQuote());
|
||||
}
|
||||
else
|
||||
mat.SetFloat("_Cols", 5);
|
||||
|
||||
currentTex = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Texture currentTex;
|
||||
|
||||
private float MoodDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return Random.Range(moodChangeTime.MinValue, moodChangeTime.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
Texture RegularToGlitch(Texture _tex)
|
||||
{
|
||||
if (_tex == Idle)
|
||||
return IdleGlitch;
|
||||
else if (_tex == Angry)
|
||||
return AngryGlitch;
|
||||
else if (_tex == Talk)
|
||||
return TalkGlitch;
|
||||
else
|
||||
{
|
||||
Debug.LogError("Unexpected texture at RegularToGlitch method in BossFaceController.cs");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Texture ExpressionToTexture(Expression _exp)
|
||||
{
|
||||
switch (_exp)
|
||||
{
|
||||
default:
|
||||
case Expression.Idle:
|
||||
return Idle;
|
||||
case Expression.Angry:
|
||||
return Angry;
|
||||
case Expression.Laugh:
|
||||
return Laugh;
|
||||
case Expression.Talk:
|
||||
return Talk;
|
||||
}
|
||||
}
|
||||
|
||||
Texture GlitchIfNeeded(Texture tex)
|
||||
{
|
||||
return (Random.value * 100 > boss.HP) ? RegularToGlitch(tex) : tex;
|
||||
}
|
||||
|
||||
string PlayRandomQuote()
|
||||
{
|
||||
string name = null;
|
||||
switch((int)Random.Range(0, 4))
|
||||
{
|
||||
case 0:
|
||||
name = "steve4";
|
||||
break;
|
||||
case 1:
|
||||
name = "steve5";
|
||||
break;
|
||||
case 2:
|
||||
name = "steve6";
|
||||
break;
|
||||
case 3:
|
||||
name = "steve8";
|
||||
break;
|
||||
}
|
||||
|
||||
AudioManager.instance.Play(name);
|
||||
return name;
|
||||
}
|
||||
void StopAllQuotes()
|
||||
{
|
||||
StopCoroutine(playQuote());
|
||||
AudioManager.instance.Stop("steve4");
|
||||
AudioManager.instance.Stop("steve5");
|
||||
AudioManager.instance.Stop("steve6");
|
||||
AudioManager.instance.Stop("steve8");
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
mat = GetComponent<SkinnedMeshRenderer>().material;
|
||||
boss.harmEv.AddListener(setDamagedFace);
|
||||
GameMaster.Instance.player.GetComponent<PlayerController>().damageEv.AddListener(setLaughFace);
|
||||
|
||||
Tex = ExpressionToTexture(startExpression);
|
||||
}
|
||||
|
||||
void decideTexture()
|
||||
{
|
||||
StopAllQuotes();
|
||||
|
||||
//Idling
|
||||
int idlingTexture = Random.Range(0, 3);
|
||||
|
||||
if (((currentTex == Idle || currentTex == IdleGlitch) && idlingTexture == 0) ||
|
||||
((currentTex == Angry || currentTex == AngryGlitch) && idlingTexture == 1) ||
|
||||
((currentTex == Talk || currentTex == TalkGlitch) && idlingTexture == 2))
|
||||
idlingTexture = (++idlingTexture % 3);
|
||||
|
||||
switch (idlingTexture)
|
||||
{
|
||||
case 0:
|
||||
Tex = GlitchIfNeeded(Idle);
|
||||
break;
|
||||
case 1:
|
||||
Tex = GlitchIfNeeded(Angry);
|
||||
break;
|
||||
case 2:
|
||||
Tex = GlitchIfNeeded(Talk);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (boss.HP > 0)
|
||||
Invoke(nameof(decideTexture), MoodDelay);
|
||||
}
|
||||
|
||||
void setDamagedFace()
|
||||
{
|
||||
CancelInvoke(nameof(decideTexture));
|
||||
StopAllQuotes();
|
||||
|
||||
if (boss.HP > 0)
|
||||
{
|
||||
Tex = Damage;
|
||||
mat.SetFloat("_Index", 1);
|
||||
|
||||
Invoke(nameof(decideTexture), .45f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tex = Angry;
|
||||
AudioManager.instance.PlayOneShot("bossDie");
|
||||
}
|
||||
}
|
||||
|
||||
void setLaughFace()
|
||||
{
|
||||
if (boss.HP > 0)
|
||||
{
|
||||
CancelInvoke(nameof(decideTexture));
|
||||
|
||||
Tex = Laugh;
|
||||
|
||||
Invoke(nameof(decideTexture), .5f);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator playQuote()
|
||||
{
|
||||
float delay = 0;
|
||||
switch (PlayRandomQuote())
|
||||
{
|
||||
default:
|
||||
case "steve4":
|
||||
delay = 1.8f;
|
||||
break;
|
||||
case "steve5":
|
||||
delay = 2.7f;
|
||||
break;
|
||||
case "steve6":
|
||||
delay = 2.3f;
|
||||
break;
|
||||
case "steve8":
|
||||
delay = 2.9f;
|
||||
break;
|
||||
}
|
||||
yield return new WaitForSeconds(delay);
|
||||
Tex = Idle;
|
||||
//StartCoroutine(playQuotes());
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/BossFaceController.cs.meta
Normal file
11
Assets/Scripts/Enemies/BossFaceController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ae6cdab16fcbd6e419d8233e7c363e68
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
21
Assets/Scripts/Enemies/BossJointsIK.cs
Normal file
21
Assets/Scripts/Enemies/BossJointsIK.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[ExecuteAlways]
|
||||
public class BossJointsIK : MonoBehaviour
|
||||
{
|
||||
public float angleThreshold = 0;
|
||||
public Transform joint1;
|
||||
public Transform joint2;
|
||||
public Transform endEffector;
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
joint2.localEulerAngles = new Vector3(0, 0, 180-angleThreshold)-new Vector3(joint1.localEulerAngles.x, joint1.localEulerAngles.x,
|
||||
Utils.remap(Mathf.Abs(joint1.localEulerAngles.z), 0, 90, angleThreshold, 180))+new Vector3(.066f, 3.421f, 0);
|
||||
endEffector.rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up)*Quaternion.Euler(new Vector3(0, 90, 0));
|
||||
endEffector.localEulerAngles += new Vector3(1.066f, 3.421f, 0);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/BossJointsIK.cs.meta
Normal file
11
Assets/Scripts/Enemies/BossJointsIK.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 756e1a68ba2f9e543af6b5a063d19f42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
123
Assets/Scripts/Enemies/BulletMovement.cs
Normal file
123
Assets/Scripts/Enemies/BulletMovement.cs
Normal file
|
@ -0,0 +1,123 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BulletMovement : MonoBehaviour
|
||||
{
|
||||
public enum BulletMovementType
|
||||
{
|
||||
Linear, ZigZag, Wave
|
||||
}
|
||||
|
||||
[Header("General settings")]
|
||||
public BulletMovementType movementType;
|
||||
public int damage = 1;
|
||||
public float speed=1;
|
||||
public float lifetime = 5;
|
||||
|
||||
//Wave data
|
||||
[Header("Wave settings")]
|
||||
[DrawIf("movementType", BulletMovementType.Linear, DrawIfAttribute.DisablingType.ReadOnly, DrawIfAttribute.Comparator.NotEqual)]
|
||||
public float waveLength = 1;
|
||||
[DrawIf("movementType", BulletMovementType.Linear, DrawIfAttribute.DisablingType.ReadOnly, DrawIfAttribute.Comparator.NotEqual)]
|
||||
public float waveAmplitude = 1;
|
||||
|
||||
[Space(3)]
|
||||
public GameObject father = null;
|
||||
|
||||
[Header("Materials")]
|
||||
public Material regularMat;
|
||||
public Material waveMat;
|
||||
public Material zigzagMat;
|
||||
|
||||
[Header("VFX")]
|
||||
public GameObject explosionParticle;
|
||||
|
||||
private float timestamp = 0;
|
||||
private Vector3 lastPosition;
|
||||
private Vector3 startPosition;
|
||||
|
||||
private void setUp()
|
||||
{
|
||||
lastPosition = transform.position;
|
||||
startPosition = transform.position;
|
||||
|
||||
gameObject.LeanScale(transform.localScale, .75f).setFrom(Vector3.zero).setEaseOutElastic();
|
||||
timestamp = Time.time;
|
||||
|
||||
switch (movementType)
|
||||
{
|
||||
case BulletMovementType.Linear:
|
||||
GetComponent<ParticleSystemRenderer>().material = regularMat;
|
||||
break;
|
||||
case BulletMovementType.Wave:
|
||||
GetComponent<ParticleSystemRenderer>().material = waveMat;
|
||||
break;
|
||||
case BulletMovementType.ZigZag:
|
||||
GetComponent<ParticleSystemRenderer>().material = zigzagMat;
|
||||
break;
|
||||
}
|
||||
|
||||
CancelInvoke();
|
||||
InvokeRepeating(nameof(hitScan), 0, .25f);
|
||||
Invoke(nameof(shutDown), lifetime);
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
setUp();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
setUp();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
Vector3 frameOffset = Vector3.zero;
|
||||
frameOffset += transform.position+transform.forward * speed * Time.deltaTime;
|
||||
|
||||
if (movementType == BulletMovementType.Wave)
|
||||
{
|
||||
float sinFunc = Mathf.Asin(Mathf.Sin((Time.time - timestamp) * 1 / waveLength + Mathf.PI*.67f)) * waveAmplitude * Time.deltaTime;
|
||||
frameOffset += sinFunc * transform.right;
|
||||
}
|
||||
else if (movementType == BulletMovementType.ZigZag)
|
||||
{
|
||||
float sinFunc = (Utils.step(Mathf.Sin((Time.time - timestamp) * 1 / waveLength + Mathf.PI*.67f ), 0)*2-1)*waveAmplitude*Time.deltaTime;
|
||||
frameOffset += sinFunc * transform.right;
|
||||
}
|
||||
|
||||
|
||||
transform.position = frameOffset;
|
||||
}
|
||||
|
||||
void hitScan()
|
||||
{
|
||||
RaycastHit[] rayHits=Physics.RaycastAll(lastPosition, (transform.position - lastPosition), (transform.position - lastPosition).magnitude, ~LayerMask.GetMask("Bullet"));
|
||||
Debug.DrawLine(lastPosition, transform.position, Color.magenta, .1f);
|
||||
|
||||
foreach (RaycastHit rh in rayHits)
|
||||
{
|
||||
if (rh.collider != null && !rh.collider.isTrigger && rh.collider.gameObject!=gameObject && !rh.collider.gameObject.CompareTag("Player"))
|
||||
bulletHit();
|
||||
}
|
||||
|
||||
lastPosition = transform.position;
|
||||
}
|
||||
|
||||
public int bulletHit()
|
||||
{
|
||||
GetComponent<ParticleSystem>().Stop();
|
||||
ObjectPooler.instance.SpawnFromPool("BulletExplosion", transform.position);
|
||||
Invoke(nameof(shutDown), .1f);
|
||||
return damage;
|
||||
}
|
||||
void shutDown()
|
||||
{
|
||||
if (GameMaster.Instance.Pooler != null)
|
||||
gameObject.SetActive(false);
|
||||
else
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/BulletMovement.cs.meta
Normal file
11
Assets/Scripts/Enemies/BulletMovement.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a178e7c0607b2194983a9f6e15481885
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
69
Assets/Scripts/Enemies/CookieController.cs
Normal file
69
Assets/Scripts/Enemies/CookieController.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class CookieController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField] float speed = 5f;
|
||||
[SerializeField, Range(0, 5)] float timeToAttack = 2f;
|
||||
|
||||
bool canMove;
|
||||
PlayerController player;
|
||||
Rigidbody rb;
|
||||
|
||||
[HideInInspector] public EnemySpawner spawner;
|
||||
[HideInInspector] public RoomTrigger room;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
StartCoroutine(TimeToAttack());
|
||||
canMove = false;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void FixedUpdate(){
|
||||
if (canMove)
|
||||
rb.MovePosition(rb.position + transform.forward * speed * Time.fixedDeltaTime);
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision col){
|
||||
if (col.gameObject.CompareTag("Wall")){
|
||||
transform.LookAt(new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z));
|
||||
}
|
||||
|
||||
if (col.gameObject.CompareTag("Disk")){
|
||||
gameObject.SetActive(false);
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if(Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
col.gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Disk")){
|
||||
gameObject.SetActive(false);
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
col.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
|
||||
if (col.gameObject.CompareTag("Player")){
|
||||
player.Damage(1);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator TimeToAttack(){
|
||||
yield return new WaitForSeconds(timeToAttack);
|
||||
transform.LookAt(new Vector3(player.transform.position.x, transform.position.y, player.transform.position.z));
|
||||
canMove = true;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/CookieController.cs.meta
Normal file
11
Assets/Scripts/Enemies/CookieController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b1924e580c7b9be4cb7c00c93f84697c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
45
Assets/Scripts/Enemies/EnemyFrisbie.cs
Normal file
45
Assets/Scripts/Enemies/EnemyFrisbie.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyFrisbie : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField, Range(0, 5f)] float damageVelocityThreshold = 1.5f;
|
||||
|
||||
[Space]
|
||||
[SerializeField] float speed = 10;
|
||||
Rigidbody rb;
|
||||
[SerializeField] Transform frisbie = default;
|
||||
float heightVelocity;
|
||||
float velocity;
|
||||
|
||||
PlayerController player;
|
||||
|
||||
void Awake(){
|
||||
rb = GetComponent<Rigidbody>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
public void OnObjectSpawn(){
|
||||
rb.velocity = Vector3.zero;
|
||||
rb.AddForce(transform.forward.normalized * speed, ForceMode.Impulse);
|
||||
}
|
||||
|
||||
void FixedUpdate(){
|
||||
velocity = rb.velocity.magnitude;
|
||||
|
||||
float positionToGo = Mathf.SmoothDamp(frisbie.localPosition.y, -1 + velocity / speed, ref heightVelocity, .1f);
|
||||
frisbie.localPosition = new Vector3(0, positionToGo, 0);
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision col){
|
||||
if (col.gameObject.CompareTag("Player")){
|
||||
if(velocity > damageVelocityThreshold){
|
||||
player.Damage(1);
|
||||
gameObject.SetActive(false);
|
||||
ObjectPooler.instance.SpawnFromPool("EnemyDiskBreak", transform.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/EnemyFrisbie.cs.meta
Normal file
11
Assets/Scripts/Enemies/EnemyFrisbie.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8e935a8b1b0290b42b23105146e8bc1f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
140
Assets/Scripts/Enemies/FolderController.cs
Normal file
140
Assets/Scripts/Enemies/FolderController.cs
Normal file
|
@ -0,0 +1,140 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class FolderController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField] Animator anim = default;
|
||||
[SerializeField] Transform container = default;
|
||||
Rigidbody rb;
|
||||
[SerializeField] float speed = 2;
|
||||
PlayerController player;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 15)] float detectionDistance = 10;
|
||||
[SerializeField] LayerMask whatIsPlayer = 8;
|
||||
bool playerDetected;
|
||||
|
||||
bool patroling;
|
||||
bool rotationSelected;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 2)] float movementRegainTime = 1f;
|
||||
[SerializeField, Range(0, 10)] float attackForce = 5f;
|
||||
bool walking;
|
||||
float currentTime;
|
||||
Vector3 force;
|
||||
Vector3 posToGo;
|
||||
|
||||
NavMeshAgent agent;
|
||||
|
||||
[HideInInspector] public EnemySpawner spawner;
|
||||
[HideInInspector] public RoomTrigger room;
|
||||
|
||||
[Space]
|
||||
[SerializeField] int percentageAmmount = 1;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
agent = GetComponent<NavMeshAgent>();
|
||||
rb = GetComponent<Rigidbody>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
agent.speed = speed;
|
||||
}
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
rb.isKinematic = true;
|
||||
playerDetected = patroling = rotationSelected = walking = false;
|
||||
currentTime = 0;
|
||||
force = posToGo = Vector3.zero;
|
||||
agent.Warp(transform.position);
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if(!playerDetected && Physics.CheckSphere(transform.position, detectionDistance, whatIsPlayer)){
|
||||
rb.isKinematic = false;
|
||||
playerDetected = true;
|
||||
walking = true;
|
||||
}
|
||||
|
||||
if (playerDetected){
|
||||
if (walking){
|
||||
agent.SetDestination(player.transform.position);
|
||||
agent.isStopped = false;
|
||||
}else{
|
||||
currentTime += 1 / movementRegainTime * Time.deltaTime;
|
||||
container.transform.localPosition = new Vector3(0, 0, 0);
|
||||
rb.velocity = Vector3.Lerp(force, Vector3.zero, currentTime);
|
||||
}
|
||||
}else{
|
||||
if (!patroling && !rotationSelected){
|
||||
posToGo = transform.position + new Vector3(Random.Range(-5f, 5f), 0, Random.Range(-5f, 5f));
|
||||
StartCoroutine(Patrol());
|
||||
rotationSelected = true;
|
||||
patroling = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FixedUpdate(){
|
||||
if(walking && playerDetected){
|
||||
rb.velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Patrol(){
|
||||
agent.isStopped = false;
|
||||
agent.SetDestination(posToGo);
|
||||
yield return new WaitForSeconds(Random.Range(1f, 2f));
|
||||
rb.velocity = Vector3.zero;
|
||||
patroling = false;
|
||||
rotationSelected = false;
|
||||
agent.isStopped = !playerDetected;
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision col){
|
||||
if (col.gameObject.CompareTag("Player")){
|
||||
anim.SetTrigger("Hit");
|
||||
walking = false;
|
||||
currentTime = 0;
|
||||
agent.isStopped = true;
|
||||
rb.velocity = -container.forward * attackForce;
|
||||
force = rb.velocity;
|
||||
StartCoroutine(RegainMobility());
|
||||
player.Damage(1);
|
||||
}
|
||||
|
||||
if (col.gameObject.CompareTag("Disk")){
|
||||
gameObject.SetActive(false);
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
player.percentage += percentageAmmount;
|
||||
col.gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Disk")){
|
||||
gameObject.SetActive(false);
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
player.percentage += percentageAmmount;
|
||||
col.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator RegainMobility(){
|
||||
yield return new WaitForSeconds(movementRegainTime);
|
||||
rb.velocity = Vector3.zero;
|
||||
walking = true;
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected(){
|
||||
Gizmos.DrawWireSphere(transform.position, detectionDistance);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/FolderController.cs.meta
Normal file
11
Assets/Scripts/Enemies/FolderController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: da1508f13deaad745b99607eafc321d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
147
Assets/Scripts/Enemies/GusilightController.cs
Normal file
147
Assets/Scripts/Enemies/GusilightController.cs
Normal file
|
@ -0,0 +1,147 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class GusilightController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[Header("Lifes")]
|
||||
[SerializeField] GameObject life1 = default;
|
||||
[SerializeField] GameObject life2 = default;
|
||||
[SerializeField] GameObject life3 = default;
|
||||
int life;
|
||||
Rigidbody rb;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 1)] float rotationSpeed = .5f;
|
||||
[SerializeField, Range(0, 3)] float attackRotationSpeed = 1.5f;
|
||||
[SerializeField] float regainMobilityDelay = 1f;
|
||||
[SerializeField] float patrolingSpeed = 2f;
|
||||
[SerializeField] float speed = 4f;
|
||||
[SerializeField] Animator anim = default;
|
||||
|
||||
bool patroling, rotationSelected, playerDetected, walking;
|
||||
Vector3 posToGo;
|
||||
PlayerController player;
|
||||
BoxCollider boxCollider;
|
||||
|
||||
[HideInInspector] public EnemySpawner spawner;
|
||||
[HideInInspector] public RoomTrigger room;
|
||||
|
||||
NavMeshAgent agent;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
boxCollider = GetComponent<BoxCollider>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
agent = GetComponent<NavMeshAgent>();
|
||||
agent.speed = speed;
|
||||
rb = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
life1.SetActive(false);
|
||||
life2.SetActive(false);
|
||||
life3.SetActive(false);
|
||||
|
||||
rb.isKinematic = true;
|
||||
boxCollider.isTrigger = false;
|
||||
agent.Warp(transform.position);
|
||||
playerDetected = false;
|
||||
life = 3;
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if (playerDetected){
|
||||
if (walking){
|
||||
agent.SetDestination(player.transform.position);
|
||||
agent.isStopped = false;
|
||||
}
|
||||
}else{
|
||||
if (!patroling && !rotationSelected){
|
||||
posToGo = transform.position + new Vector3(Random.Range(-5f, 5f), 0, Random.Range(-5f, 5f));
|
||||
StartCoroutine(Patrol());
|
||||
rotationSelected = true;
|
||||
patroling = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnCollisionEnter(Collision col){
|
||||
if (col.gameObject.CompareTag("Disk")){
|
||||
if (!playerDetected){
|
||||
rb.isKinematic = false;
|
||||
playerDetected = true;
|
||||
walking = true;
|
||||
}else{
|
||||
switch (life){
|
||||
case 3:
|
||||
life3.SetActive(true);
|
||||
break;
|
||||
case 2:
|
||||
life2.SetActive(true);
|
||||
break;
|
||||
case 1:
|
||||
life1.SetActive(true);
|
||||
agent.isStopped = true;
|
||||
break;
|
||||
}
|
||||
life--;
|
||||
if (life == 0){
|
||||
gameObject.SetActive(false);
|
||||
player.percentage += Utils.RAM_cleanseBig;
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
col.gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Disk")){
|
||||
if (!playerDetected){
|
||||
rb.isKinematic = false;
|
||||
playerDetected = true;
|
||||
walking = true;
|
||||
}else{
|
||||
switch (life){
|
||||
case 3:
|
||||
life3.SetActive(true);
|
||||
break;
|
||||
case 2:
|
||||
life2.SetActive(true);
|
||||
break;
|
||||
case 1:
|
||||
life1.SetActive(true);
|
||||
agent.isStopped = true;
|
||||
break;
|
||||
}
|
||||
life--;
|
||||
if(life == 0){
|
||||
player.percentage += Utils.RAM_cleanseBig;
|
||||
gameObject.SetActive(false);
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
col.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Patrol(){
|
||||
agent.isStopped = false;
|
||||
agent.SetDestination(posToGo);
|
||||
yield return new WaitForSeconds(Random.Range(1f, 2f));
|
||||
rb.velocity = Vector3.zero;
|
||||
patroling = false;
|
||||
rotationSelected = false;
|
||||
agent.isStopped = !playerDetected;
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/GusilightController.cs.meta
Normal file
11
Assets/Scripts/Enemies/GusilightController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a7ae8b5397c24ca4eb5d63abe64b6da3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
124
Assets/Scripts/Enemies/HardDriveController.cs
Normal file
124
Assets/Scripts/Enemies/HardDriveController.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class HardDriveController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField, Min(0)] float speed = 2f;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 10)] float playerDetectionRange = 3.5f;
|
||||
[SerializeField] LayerMask whatIsPlayer = 8;
|
||||
[SerializeField] LayerMask whatIsWall = -1;
|
||||
PlayerController player;
|
||||
bool followingPlayer;
|
||||
|
||||
bool walking;
|
||||
bool rotationSelected;
|
||||
|
||||
[Header("Attack")]
|
||||
[SerializeField, Min(0)] Vector3 playerHitRange = Vector3.one;
|
||||
[SerializeField] Transform playerHitPos = default;
|
||||
bool attacking;
|
||||
[SerializeField, Range(0, 1)] float particleDelay = .25f;
|
||||
[SerializeField, Range(0, 2)] float attackDuration = .5f;
|
||||
|
||||
[Space]
|
||||
[SerializeField] Animator anim = default;
|
||||
[SerializeField, Range(1, 5)] int damageAmount = 2;
|
||||
|
||||
NavMeshAgent agent;
|
||||
Vector3 posToGo;
|
||||
|
||||
[HideInInspector] public EnemySpawner spawner;
|
||||
[HideInInspector] public RoomTrigger room;
|
||||
|
||||
[SerializeField] Transform explosionPos = default;
|
||||
[SerializeField, Range(0, 1)] float disappearDelay = .5f;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 5)] float explosionRange;
|
||||
|
||||
void Awake(){
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
agent = GetComponent<NavMeshAgent>();
|
||||
agent.speed = speed;
|
||||
}
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
walking = rotationSelected = followingPlayer = attacking = false;
|
||||
posToGo = transform.position;
|
||||
agent.Warp(transform.position);
|
||||
agent.isStopped = true;
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if (Physics.CheckSphere(transform.position, playerDetectionRange, whatIsPlayer) && !followingPlayer){
|
||||
followingPlayer = true;
|
||||
}
|
||||
|
||||
if (followingPlayer && !attacking){
|
||||
if (Physics.CheckBox(playerHitPos.position, playerHitRange / 2, playerHitPos.rotation, whatIsPlayer)){
|
||||
attacking = true;
|
||||
agent.isStopped = true;
|
||||
StartCoroutine(Attack());
|
||||
}else{
|
||||
agent.isStopped = false;
|
||||
agent.SetDestination(player.transform.position);
|
||||
}
|
||||
}else if (!attacking){
|
||||
if (!walking && !rotationSelected){
|
||||
posToGo = transform.position + new Vector3(Random.Range(-5f, 5f), 0, Random.Range(-5f, 5f));
|
||||
StartCoroutine(Patrol());
|
||||
walking = true;
|
||||
rotationSelected = true;
|
||||
}else if (!Physics.CheckBox(playerHitPos.position, playerHitRange / 2, playerHitPos.rotation, whatIsWall)){
|
||||
agent.isStopped = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator Patrol(){
|
||||
agent.isStopped = false;
|
||||
agent.SetDestination(posToGo);
|
||||
yield return new WaitForSeconds(Random.Range(1f, 2f));
|
||||
walking = false;
|
||||
rotationSelected = false;
|
||||
agent.isStopped = !followingPlayer;
|
||||
}
|
||||
|
||||
IEnumerator Attack(){
|
||||
anim.SetTrigger("Attack");
|
||||
yield return new WaitForSeconds(particleDelay);
|
||||
ObjectPooler.instance.SpawnFromPool("HDDExplosion", explosionPos.position);
|
||||
AudioManager.instance.PlayOneShot("electro1");
|
||||
AudioManager.instance.PlayOneShot("explo1");
|
||||
yield return new WaitForSeconds(attackDuration - particleDelay);
|
||||
if (Physics.CheckBox(playerHitPos.position, playerHitRange / 2, playerHitPos.rotation, whatIsPlayer)){
|
||||
player.Damage(damageAmount);
|
||||
}
|
||||
yield return new WaitForSeconds(disappearDelay);
|
||||
if(Physics.CheckSphere(explosionPos.position, explosionRange, whatIsPlayer)){
|
||||
player.Damage(1);
|
||||
}
|
||||
player.percentage += Utils.RAM_cleanseSmall;
|
||||
room.Die(gameObject);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected(){
|
||||
Gizmos.DrawWireSphere(transform.position, playerDetectionRange);
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawWireSphere(explosionPos.position, explosionRange);
|
||||
}
|
||||
|
||||
void OnDrawGizmos(){
|
||||
Gizmos.color = Color.red;
|
||||
if (playerHitPos != null){
|
||||
Gizmos.DrawWireCube(playerHitPos.position, playerHitRange);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/HardDriveController.cs.meta
Normal file
11
Assets/Scripts/Enemies/HardDriveController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 03a0203063a5494449f541d22bdc5c76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
272
Assets/Scripts/Enemies/TurretCoil_Behaviour.cs
Normal file
272
Assets/Scripts/Enemies/TurretCoil_Behaviour.cs
Normal file
|
@ -0,0 +1,272 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class ShootingPattern
|
||||
{
|
||||
public enum ShootingStyle
|
||||
{
|
||||
None, All, Cross, Cardinal, CW_Loop, CCW_Loop, ChrisCross
|
||||
}
|
||||
|
||||
public ShootingPattern(float _initialDelay, float _repeatDelay)
|
||||
{
|
||||
initialDelay = _initialDelay;
|
||||
repeatDelay = _repeatDelay;
|
||||
}
|
||||
|
||||
public static ShootingPattern operator *(ShootingPattern a, float b) => new ShootingPattern(a.initialDelay * b, a.repeatDelay * b);
|
||||
|
||||
public float initialDelay = 0;
|
||||
public float repeatDelay = 1;
|
||||
|
||||
public static readonly ShootingPattern[] chrissCross = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(.5f, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(.5f, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(.5f, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(.5f, 1)};
|
||||
public static readonly ShootingPattern[] cross = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1)};
|
||||
public static readonly ShootingPattern[] cardinal = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 0)};
|
||||
public static readonly ShootingPattern[] ccwLoop = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0.125f, 1),
|
||||
new ShootingPattern(0.25f, 1),
|
||||
new ShootingPattern(0.375f, 1),
|
||||
new ShootingPattern(0.5f, 1),
|
||||
new ShootingPattern(0.625f, 1),
|
||||
new ShootingPattern(0.75f, 1),
|
||||
new ShootingPattern(0.875f, 1)};
|
||||
public static readonly ShootingPattern[] cwLoop = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0.875f, 1),
|
||||
new ShootingPattern(0.75f, 1),
|
||||
new ShootingPattern(0.625f, 1),
|
||||
new ShootingPattern(0.5f, 1),
|
||||
new ShootingPattern(0.375f, 1),
|
||||
new ShootingPattern(0.25f, 1),
|
||||
new ShootingPattern(0.125f, 1)};
|
||||
public static readonly ShootingPattern[] all = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1),
|
||||
new ShootingPattern(0, 1)};
|
||||
public static readonly ShootingPattern[] none = new ShootingPattern[8] {
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0),
|
||||
new ShootingPattern(0, 0)};
|
||||
|
||||
public static ShootingPattern[] styleToPattern(ShootingStyle a)
|
||||
{
|
||||
switch (a)
|
||||
{
|
||||
default:
|
||||
case ShootingStyle.None:
|
||||
return (ShootingPattern[])ShootingPattern.none.Clone();
|
||||
case ShootingStyle.All:
|
||||
return (ShootingPattern[])ShootingPattern.all.Clone();
|
||||
case ShootingStyle.Cross:
|
||||
return (ShootingPattern[])ShootingPattern.cross.Clone();
|
||||
case ShootingStyle.Cardinal:
|
||||
return (ShootingPattern[])ShootingPattern.cardinal.Clone();
|
||||
case ShootingStyle.CW_Loop:
|
||||
return (ShootingPattern[])ShootingPattern.cwLoop.Clone();
|
||||
case ShootingStyle.CCW_Loop:
|
||||
return (ShootingPattern[])ShootingPattern.ccwLoop.Clone();
|
||||
case ShootingStyle.ChrisCross:
|
||||
return (ShootingPattern[])ShootingPattern.chrissCross.Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TurretCoil_Behaviour : MonoBehaviour
|
||||
{
|
||||
[Header("Necesary fields")]
|
||||
public GameObject bulletPrefab;
|
||||
public string bulletKey="Bullet";
|
||||
public Transform[] shootingSockets = new Transform[8];
|
||||
|
||||
[Header("Turret settings")]
|
||||
public ShootingPattern.ShootingStyle shootingStyle = ShootingPattern.ShootingStyle.ChrisCross;
|
||||
public float shootFrequency = 1;
|
||||
|
||||
[Header("Bullet settings")]
|
||||
public float bulletSpeed = 3;
|
||||
private float bulletSpawnOffset=.15f;
|
||||
public BulletMovement.BulletMovementType bulletMovementType= BulletMovement.BulletMovementType.Linear;
|
||||
[DrawIf("bulletMovementType", BulletMovement.BulletMovementType.Linear, DrawIfAttribute.DisablingType.ReadOnly, DrawIfAttribute.Comparator.NotEqual)]
|
||||
public float waveLength = 1;
|
||||
[DrawIf("bulletMovementType", BulletMovement.BulletMovementType.Linear, DrawIfAttribute.DisablingType.ReadOnly, DrawIfAttribute.Comparator.NotEqual)]
|
||||
public float waveAmplitude = 1;
|
||||
|
||||
[Header("VFX")]
|
||||
public GameObject muzzle;
|
||||
|
||||
private ShootingPattern[] pattern = new ShootingPattern[8];
|
||||
public ShootingPattern[] Pattern
|
||||
{
|
||||
get
|
||||
{
|
||||
return pattern;
|
||||
}
|
||||
set
|
||||
{
|
||||
pattern = value;
|
||||
if (pattern != ShootingPattern.styleToPattern(ShootingPattern.ShootingStyle.None))
|
||||
{
|
||||
for (int i = 0; i < pattern.Length; ++i)
|
||||
{
|
||||
pattern[i] = pattern[i] * (1f / shootFrequency);
|
||||
}
|
||||
Invoke(nameof(startShooting), .5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Material mat;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
initialHeight = transform.position.y;
|
||||
mat = GetComponentInChildren<MeshRenderer>().material;
|
||||
DeployHard(false);
|
||||
}
|
||||
|
||||
public float initialHeight;
|
||||
private void Start()
|
||||
{
|
||||
if(FindObjectOfType<BossBehaviour>()==null)
|
||||
Deploy(true);
|
||||
|
||||
|
||||
Pattern = ShootingPattern.styleToPattern(shootingStyle);
|
||||
}
|
||||
|
||||
private float height = .51f;
|
||||
private bool deployed = true;
|
||||
[ContextMenu("Deploy_Conceal")]
|
||||
public void Deploy(bool newState)
|
||||
{
|
||||
if (deployed != newState)
|
||||
{
|
||||
deployed = newState;
|
||||
transform.LeanMoveLocalY(!deployed ? -height : initialHeight, .5f).setFrom(transform.position.y).setEaseInOutBack();
|
||||
if (!deployed)
|
||||
stopShooting();
|
||||
}
|
||||
}
|
||||
public void DeployHard(bool newState)
|
||||
{
|
||||
if (deployed != newState)
|
||||
{
|
||||
deployed = newState;
|
||||
transform.position = new Vector3(transform.position.x, (!deployed ? -height : initialHeight), transform.position.z);
|
||||
}
|
||||
}
|
||||
private void shoot(int socket)
|
||||
{
|
||||
StartCoroutine(updateLEDshader(0.25f, socket, 1));
|
||||
|
||||
GameObject bullet;
|
||||
if (GameMaster.Instance.Pooler != null && GameMaster.Instance.Pooler.poolDictionary.ContainsKey("Bullet"))
|
||||
bullet=GameMaster.Instance.Pooler.SpawnFromPool(bulletKey, shootingSockets[socket].position+shootingSockets[socket].forward*bulletSpawnOffset, shootingSockets[socket].rotation);
|
||||
else
|
||||
bullet=Instantiate(bulletPrefab, shootingSockets[socket].position, shootingSockets[socket].rotation);
|
||||
bullet.GetComponent<BulletMovement>().speed = bulletSpeed;
|
||||
bullet.GetComponent<BulletMovement>().father = gameObject;
|
||||
bullet.GetComponent<BulletMovement>().movementType = bulletMovementType;
|
||||
//wave
|
||||
bullet.GetComponent<BulletMovement>().waveAmplitude = waveAmplitude;
|
||||
bullet.GetComponent<BulletMovement>().waveLength = waveLength;
|
||||
|
||||
Instantiate(muzzle, shootingSockets[socket].position, shootingSockets[socket].rotation);
|
||||
}
|
||||
|
||||
private IEnumerator updateLEDshader(float time, int socket, float glow)
|
||||
{
|
||||
mat.SetFloat("LED_"+(socket+1).ToString()+"_Glow", glow);
|
||||
yield return new WaitForSeconds(time);
|
||||
mat.SetFloat("LED_" + (socket + 1).ToString() + "_Glow", 0);
|
||||
}
|
||||
|
||||
public void stopShooting()
|
||||
{
|
||||
StopAllCoroutines();
|
||||
|
||||
for(int i=0; i<shootingSockets.Length; ++i)
|
||||
{
|
||||
mat.SetFloat("LED_" + (i + 1).ToString() + "_Glow", 0);
|
||||
}
|
||||
//StopCoroutine(shootFromPos(0, 0));
|
||||
//StopCoroutine(shootFromPos(0, 0, 0));
|
||||
}
|
||||
|
||||
private bool canStartShooting = true;
|
||||
private void reenableCanStartShooting()
|
||||
{
|
||||
canStartShooting = true;
|
||||
}
|
||||
public void startShooting()
|
||||
{
|
||||
if (canStartShooting)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
if (shootFrequency != 0)
|
||||
{
|
||||
for (int i = 0; i < pattern.Length; ++i)
|
||||
{
|
||||
StartCoroutine(shootFromPos(i, pattern[i].initialDelay, pattern[i].repeatDelay));
|
||||
}
|
||||
}
|
||||
|
||||
canStartShooting = false;
|
||||
Invoke(nameof(reenableCanStartShooting), .35f);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator shootFromPos(int index, float startDelay, float repeatDelay)
|
||||
{
|
||||
if (!(startDelay == 0 && repeatDelay == 0))
|
||||
{
|
||||
yield return new WaitForSeconds(startDelay);
|
||||
shoot(index);
|
||||
StartCoroutine(shootFromPos(index, repeatDelay));
|
||||
}
|
||||
}
|
||||
IEnumerator shootFromPos(int index, float repeatDelay)
|
||||
{
|
||||
yield return new WaitForSeconds(repeatDelay);
|
||||
shoot(index);
|
||||
StartCoroutine(shootFromPos(index, repeatDelay));
|
||||
}
|
||||
|
||||
}
|
11
Assets/Scripts/Enemies/TurretCoil_Behaviour.cs.meta
Normal file
11
Assets/Scripts/Enemies/TurretCoil_Behaviour.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f6e1b4c4815648d4bbfda026da7db6df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
167
Assets/Scripts/Enemies/TurretController.cs
Normal file
167
Assets/Scripts/Enemies/TurretController.cs
Normal file
|
@ -0,0 +1,167 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public class TurretController : MonoBehaviour, IPooledObject{
|
||||
|
||||
[SerializeField] float speed = 1f;
|
||||
[SerializeField] Animator anim = default;
|
||||
[SerializeField] GameObject head = default;
|
||||
[SerializeField] GameObject headObj = default;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 3f)] float firstAttackDelay = 1f;
|
||||
[SerializeField] int numberOfDisks = 10;
|
||||
int currentDisk;
|
||||
[SerializeField] float maxHeigth = 1f;
|
||||
[SerializeField] float minHeigth = 0f;
|
||||
[SerializeField] GameObject turretObject = default;
|
||||
[SerializeField] Transform shootPos = default;
|
||||
|
||||
[Space]
|
||||
[SerializeField, Range(0, 15)] float shootingDistance = 7f;
|
||||
[SerializeField, Range(0, 5)] float aimingTime = 2f;
|
||||
[SerializeField, Range(0, 1)] float attackDelay = .25f;
|
||||
[SerializeField] LayerMask whatIsPlayer = default;
|
||||
[SerializeField] LayerMask whatIsWall = default;
|
||||
PlayerController player;
|
||||
float rotationVelocity;
|
||||
bool canAttack;
|
||||
bool aiming;
|
||||
bool prepareShooting;
|
||||
bool playerDetected;
|
||||
|
||||
NavMeshAgent agent;
|
||||
|
||||
[HideInInspector] public EnemySpawner spawner;
|
||||
[HideInInspector] public RoomTrigger room;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Awake(){
|
||||
agent = FindObjectOfType<NavMeshAgent>();
|
||||
player = FindObjectOfType<PlayerController>();
|
||||
agent.speed = speed;
|
||||
}
|
||||
|
||||
public void OnObjectSpawn(){
|
||||
currentDisk = numberOfDisks;
|
||||
turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0);
|
||||
playerDetected = aiming = prepareShooting = canAttack = false;
|
||||
agent.Warp(transform.position);
|
||||
agent.isStopped = true;
|
||||
StartCoroutine(FirstAttackDelay());
|
||||
}
|
||||
|
||||
IEnumerator FirstAttackDelay(){
|
||||
yield return new WaitForSeconds(firstAttackDelay);
|
||||
canAttack = true;
|
||||
}
|
||||
|
||||
void Update(){
|
||||
if(!playerDetected && Physics.CheckSphere(transform.position, shootingDistance, whatIsPlayer)){
|
||||
agent.isStopped = false;
|
||||
playerDetected = true;
|
||||
}
|
||||
|
||||
Vector3 dire = (player.transform.position - (transform.position + Vector3.up * .3f)).normalized;
|
||||
//Ray rayx = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position));
|
||||
//Debug.DrawRay(rayx.origin, rayx.direction * Vector3.Distance(transform.position + Vector3.up, player.transform.position));
|
||||
|
||||
if (Physics.CheckSphere(transform.position, shootingDistance, whatIsPlayer) && canAttack && currentDisk > 0){
|
||||
Ray ray = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position));
|
||||
if (!Physics.Raycast(ray, Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position), whatIsWall)){
|
||||
StartCoroutine(Shoot());
|
||||
canAttack = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Physics.CheckSphere(transform.position + Vector3.up, shootingDistance, whatIsPlayer) && canAttack && currentDisk == 0){
|
||||
Ray ray = new Ray(transform.position + Vector3.up * .3f, dire * Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position));
|
||||
if (!Physics.Raycast(ray, Vector3.Distance(transform.position + Vector3.up * .3f, player.transform.position), whatIsWall)){
|
||||
StartCoroutine(ShootHead());
|
||||
canAttack = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aiming){
|
||||
if (!prepareShooting){
|
||||
agent.SetDestination(player.transform.position);
|
||||
}else{
|
||||
Vector3 pos = player.transform.position - transform.position;
|
||||
float rotY = Mathf.Atan2(-pos.z, pos.x) * Mathf.Rad2Deg;
|
||||
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, rotY + 90, ref rotationVelocity, .1f);
|
||||
transform.rotation = Quaternion.Euler(0f, angle, 0f);
|
||||
}
|
||||
}else if (playerDetected && !prepareShooting){
|
||||
agent.SetDestination(player.transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator ShootHead(){
|
||||
aiming = true;
|
||||
yield return new WaitForSeconds(aimingTime);
|
||||
agent.isStopped = true;
|
||||
prepareShooting = true;
|
||||
yield return new WaitForSeconds(attackDelay);
|
||||
agent.isStopped = false;
|
||||
aiming = false;
|
||||
prepareShooting = false;
|
||||
anim.SetTrigger("Shoot");
|
||||
currentDisk--;
|
||||
//turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0);
|
||||
headObj.SetActive(false);
|
||||
//FrisbieController frisbie = ObjectPooler.instance.SpawnFromPool("Disk", shootPos.position, transform.rotation).GetComponent<FrisbieController>();
|
||||
ObjectPooler.instance.SpawnFromPool("TurretHead", shootPos.position, transform.rotation);
|
||||
canAttack = true;
|
||||
gameObject.SetActive(false);
|
||||
player.percentage += Utils.RAM_cleanseSmall;
|
||||
room.Die(gameObject);
|
||||
}
|
||||
|
||||
IEnumerator Shoot(){
|
||||
aiming = true;
|
||||
yield return new WaitForSeconds(aimingTime);
|
||||
agent.isStopped = true;
|
||||
prepareShooting = true;
|
||||
yield return new WaitForSeconds(attackDelay);
|
||||
agent.isStopped = false;
|
||||
aiming = false;
|
||||
prepareShooting = false;
|
||||
anim.SetTrigger("Shoot");
|
||||
currentDisk--;
|
||||
turretObject.transform.localPosition = new Vector3(minHeigth + (maxHeigth - minHeigth) / numberOfDisks * currentDisk, 0, 0);
|
||||
ObjectPooler.instance.SpawnFromPool("EnemyDisk", shootPos.position, transform.rotation);
|
||||
//FrisbieController frisbie = Instantiate(bullet, transform.position + Vector3.up, transform.rotation).GetComponent<FrisbieController>();
|
||||
canAttack = true;
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider col){
|
||||
if (col.CompareTag("Disk")){
|
||||
player.percentage += Utils.RAM_cleanseSmall;
|
||||
gameObject.SetActive(false);
|
||||
col.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
StopAllCoroutines();
|
||||
}
|
||||
}
|
||||
void OnCollisionEnter(Collision col){
|
||||
if (col.gameObject.CompareTag("Disk")){
|
||||
player.percentage += Utils.RAM_cleanseSmall;
|
||||
gameObject.SetActive(false);
|
||||
col.gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;
|
||||
room.Die(gameObject);
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("EnemyExplosion", transform.position);
|
||||
if (Utils.spawnDisk())
|
||||
GameMaster.Instance.Pooler.SpawnFromPool("DiskPickup", transform.position);
|
||||
StopAllCoroutines();
|
||||
}
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected(){
|
||||
Gizmos.DrawWireSphere(transform.position, shootingDistance);
|
||||
}
|
||||
}
|
11
Assets/Scripts/Enemies/TurretController.cs.meta
Normal file
11
Assets/Scripts/Enemies/TurretController.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f3ad027a84e9ef64783582634e6163ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue