'Aight, here’s the situation:
- Enemy patrols, depending on direction, speed and whether it’s hit a wall or not.
- If the player walks inside its range, it stops and STARES O_O…
- It also does some damage and knocks the player back on collision - standard stuff…
What I want it to do:
- Instead of STARING at the player … I want it to trace a raycast, instantiate my laser object and apply force in the direction ( or using the angle ) of the raycast.
- Alternatively … I could make it shorter than the player and make it a dull enemy firing in a straight line … but that wouldn’t be fun now would it.
Here’s my script so far with the note that I already have some working enemies and a boss fight, it’s just this that I’m having an issue with, I don’t want to be spoon fed and would much rather theoretical responses with short examples THANKS!
public class Enemy1 : MonoBehaviour
{
//Public variables
public float moveDistance; //Distance the enemy will move on both sides/aka Patrol distance
public float moveSpeed; //Speed at which the enemy will move
//Private variables
private bool playerInside; //Used to check if the player is inside
private float orgPos; //The enemy's original position
private float useSpeed; //Some more speed variables
private bool wallInTheWay; //Indicates if a wall has been hit
private Animator _anim1; //Used for animation, specifically the shooting one
//Some general logic
void LateUpdate()
{
Debug.DrawRay (transform.position,GameObject.Find ("nyan").transform.position - transform.position , Color.green);
}
//Setting up CoUpdate() and variables
private IEnumerator Start()
{
//Grab the component so that we can animate stuff
//_anim1.gameObject.GetComponent<Animator> ();
//Patrol speed and initial position
useSpeed = -moveSpeed;
orgPos = this.gameObject.transform.position.x;
//Assign bools to false, avoiding any stupid scenarios
wallInTheWay = false;
playerInside = false;
//And finaly start CoUpdate()
yield return StartCoroutine (CoUpdate ());
}
//CoUpdate - Update() with the block functionality
private IEnumerator CoUpdate()
{
//Stuff here happens once
//Update
while (true)
{
//Screem, aim and fire
if(playerInside)
{
yield return StartCoroutine(ScrAimFire());
}
//Or... wait for it... waaaaait for it...
else if(!playerInside)
{
//If there is no wall in the way patrol in regular intervals
if(!wallInTheWay)
{
//Based on position, assign direction
if(orgPos - this.transform.position.x > moveDistance)
useSpeed = moveSpeed;
else if(orgPos - this.transform.position.x < -moveDistance)
useSpeed = -moveSpeed;
//And move...
this.transform.Translate (useSpeed * Time.deltaTime, 0, 0);
}
//If there is a wall there however...
else if(wallInTheWay)
{
//Translate the object accordingly
yield return StartCoroutine(WallMovement());
}
}
//Always - to avoid infinit loops and crashes
yield return null;
}
}
//Check if the player is in range
private void OnTriggerEnter2D(Collider2D plr)
{
if (plr.gameObject.tag == "Player")
playerInside = true;
}
//Make sure to disable the trigger if the player is no longer in range
private void OnTriggerExit2D(Collider2D plr)
{
if (plr.gameObject.tag == "Player")
playerInside = false;
}
//Various collision checks
private void OnCollisionEnter2D(Collision2D obj)
{
//If it's a player...
if (obj.gameObject.tag == "Player")
{
//Knockback and stop the player ... kinda messy due to all the component fetching
if(obj.gameObject.GetComponent<Rigidbody2D>().velocity.x < 0)
{
obj.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0,0);
obj.gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector3(2000.0f,0.0f,0.0f));
}
else if(obj.gameObject.GetComponent<Rigidbody2D>().velocity.x > 0)
{
obj.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0,0);
obj.gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector3(-2000.0f,0.0f,0.0f));
}
//Also remember to do some damage
_Player.curHealth -= 50;
}
//If it's a wall, make sure the rest of the script knows this
if (obj.gameObject.tag == "Wall")
wallInTheWay = true;
if (obj.gameObject.tag == "Lava")
Destroy (this.gameObject);
}
//Make sure you know when you're no longer touching the wall
private void OnCollisionExit2D(Collision2D obj)
{
if (obj.gameObject.tag == "Wall")
wallInTheWay = false;
}
//Wall Logic - simple
private IEnumerator WallMovement()
{
//This should do for now ... Plan on making it float back up later on
RaycastHit2D rightWall = Physics2D.Raycast(this.gameObject.transform.position, Vector2.right, 5.0f);
//If you hit a wall on the right
if (rightWall)
this.transform.Translate (-moveDistance, 0.0f, 0.0f);
//Otherwise...
else
this.transform.Translate (moveDistance, 0.0f, 0.0f);
//And make sure you dont teleport/run back to the wall
orgPos = this.transform.position.x;
//ALWAYS!!
yield return null;
}
//The actual scream, aim and fire logic
private IEnumerator ScrAimFire()
{
yield return null;
}
}