problems with enemy melee - c#

I've been working on a 2d game for weeks and nothing works. I'm not the best coder out there I'm still learning! In my game I have a player and then an enemy. I need the enemy to behave by itself so I've been following many youtube tutorials, however, it seems that all of them have some sort of problem. I have checked for spelling and everything but still no result. I followed this tutorial (https://www.youtube.com/watch?v=waj6i9cQ6rM) lately but it doesn't work for me. My enemy just plays the attack animation over and over when the player is not even close and it doesn't move from its position.
This is my code:
void EnemyLogic()
{
distance = Vector2.Distance(transform.position, target.transform.position);
if(distance > attackDistance)
{
Move();
StopAttack();
}
else if (attackDistance >= distance && cooling == false)
{
Attack();
}
if (cooling)
{
Cooldown();
Animator.SetBool("Attack", false);
}
}
void Move()
{
Animator.SetBool("canWalk", false);
if(!Animator.GetCurrentAnimatorStateInfo(0).IsName("LightBandit_Attack"))
{
Vector2 targetPosition = new Vector2(target.transform.position.x, transform.position.y);
transform.position = Vector2.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
}
}
void Attack()
{
timer = intTimer; // reset time when player is in rnge
attackMode = true; // check if enemy can still attack or not
Animator.SetBool("canWalk", false);
Animator.SetBool("attack", true);
//Player.GetComponent<HeroKnight>()?.TakeDamage(attackDamage);
}
void Cooldown()
{
timer -= Time.deltaTime;
if(timer <= 0 && cooling && attackMode)
{
cooling = false;
timer = intTimer;
}
}
void StopAttack()
{
cooling = false;
attackMode = false;
Animator.SetBool("attack", false);
}
void RaycastDebugger()
{
if(distance > attackDistance)
{
Debug.DrawRay(rayCast.position, Vector2.left * rayCastLength, Color.red);
}
else if (attackDistance > distance)
{
Debug.DrawRay(rayCast.position, Vector2.left * rayCastLength, Color.green );
}
}
public void TriggerCooling()
{
cooling = true;
}

You have written a condition here that does not allow movement to occur. Eliminate this condition and limit the enemy logic to distances only.
if (!Animator.GetCurrentAnimatorStateInfo(0).IsName("LightBandit_Attack"))

Related

Unity Simple Sliding Door. Collider moving but not the actual object

I have been trying to make an automatic door when the player walks close to the door it will automatically open and then close after leaving that area. I have tried it different ways with having a different object as a collision sensor to move the door to even using a box collider on the door itself but it doesn't work. The Collider will move but you will be phasing through the door after.
public float maximumOpening = 3;
public float maximumClosing = 0;
public float movementSpeed = 1;
bool playerIsHere;
bool opening;
void Start()
{
playerIsHere = false;
opening = false;
}
void Update()
{
if(playerIsHere)
{
if (movingDoor.transform.position.x < maximumOpening)
{
movingDoor.transform.position += Vector3.forward * Time.deltaTime;
}
else
{
if (movingDoor.transform.position.x > maximumClosing)
{
movingDoor.transform.position += -Vector3.forward * Time.deltaTime;
}
}
}
}
private void OnTriggerEnter(Collider col)
{
if(col.gameObject.tag == "Player")
{
playerIsHere = true;
}
}
private void OnTriggerExit(Collider col)
{
if (col.gameObject.tag == "Player")
{
playerIsHere = false;
}
}
!https://imgur.com/a/C4AmoUl
Shouldn't it be more like the following:
if (playerIsHere && movingDoor.transform.position.x < maximumOpening)
{
movingDoor.transform.position += Vector3.forward * Time.deltaTime;
}
else if (movingDoor.transform.position.x > maximumClosing)
{
movingDoor.transform.position += -Vector3.forward * Time.deltaTime;
}
since otherwise the door will only do anything when the player is actually in it, and otherwise do nothing, hope it helps :)

The enemy flies through the walls

I wrote a code for an enemy that, when he sees my character, will chase him. But when he sees my character and chases him, he goes through objects.There is a box collider 2D on it, but it moves with it. I've already tried everything, I don't know how to fix it. Can you please help fix
Here is my code:
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
idleSpeed = speed;
barDelta = Vector3.Distance(parent.position, barPoint.position);
bar = UIManager.AddEnemy(this);
}
void Update()
{
if (Vector2.Distance(transform.position, point.position) < positionOfPatrol && angry == false)
{
idle = true;
}
if (Vector2.Distance(transform.position, player.position) < stoppingDistance)
{
angry = true;
idle = false;
goBack = false;
}
if (Vector2.Distance(transform.position, player.position) > stoppingDistance)
{
goBack = true;
angry = false;
}
if (idle == true)
{
Idle();
}
else if (angry == true)
{
Angry();
}
else if (goBack == true)
{
GoBack();
}
}
void Idle()
{
if (transform.position.x > point.position.x + positionOfPatrol)
{
moveingRight = false;
}
else if (transform.position.x < point.position.x - positionOfPatrol)
{
moveingRight = true;
}
if (moveingRight)
{
if (!facingRight) Flip();
facingRight = true;
transform.position = new Vector2(transform.position.x + speed * Time.deltaTime, transform.position.y);
}
else
{
if (facingRight) Flip();
facingRight = false;
transform.position = new Vector2(transform.position.x - speed * Time.deltaTime, transform.position.y);
}
}
void Angry()
{
transform.position = Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
speed = idleSpeed + 1;
}
void GoBack()
{
transform.position = Vector2.MoveTowards(transform.position, point.position, speed * Time.deltaTime);
speed = idleSpeed;
}
}
You should try to use a rigidbody with the collider. The collider does not actually do physics, that is what the rigidbody is for. If you add a rigidbody and set its velocity instead of setting the transform's position, it will not only detect collisions with walls but it will stop moving and do all of the physics you would expect.

I'm having an issue properly having the proper particle effect play when I hold the left mouse button down

I'm working on a third person shooter and as the title states I'm having an issue having the particle effect for the muzzle flash play when I hold the left mouse button down. Even though I'm using Input.GetButton the particle effect only seems to play whenever I let go of the mouse. The basic shooting works correctly and I've tried using another particle effect which only led to the same issue so I believe the problem is somewhere within the code. This code is mostly from Brackeys' tutorial on Shooting with Raycasts if that narrows down the issue. I'd also appreciate alternatives to implementing a muzzle flash effect with the particle system.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class FullAuto : MonoBehaviour
{
public int damage = 10;
public float range = 100f;
public float impactForce = 30f;
public float fireRate = 15f;
public int maxAmmo = 10;
public int currentAmmo;
public float reloadTime = 1f;
private bool isReloading = false;
public Camera fpsCam;
public ParticleSystem muzzleFlash;
public GameObject impactEffect;
private float nextTimeToFire = 0f;
public Text ammoCount;
public Animator animator;
void Start()
{
currentAmmo = maxAmmo;
}
void OnEnable()
{
isReloading = false;
animator.SetBool("Reloading", false);
}
void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0 || Input.GetKeyDown(KeyCode.R))
{
StartCoroutine(Reload());
return;
}
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
muzzleFlash.Play();
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
ammoCount.text = "Ammo: " + currentAmmo.ToString();
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
animator.SetBool("Reloading", true);
yield return new WaitForSeconds(reloadTime - .25f);
animator.SetBool("Reloading", false);
yield return new WaitForSeconds(.25f);
currentAmmo = maxAmmo;
isReloading = false;
}
void Shoot()
{
currentAmmo--;
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Enemy enemy = hit.transform.GetComponent<Enemy>();
if (enemy != null)
{
enemy.TakeDamage(damage);
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(impactGO, 2f);
}
}
}
Not sure but afaik Play has only an effect if the particle system was stopped/paused before → It doesn't actually restart the particle effect.
If the Particle System has been paused, then this resumes playing from the previous time.
If the Particle System has stopped, then the system starts from time 0, and, if it is relevant, the startDelay is applied.
I think you could rather use Emit and pass in how many particles to spawn each time
Emit count particles immediately
public float particleAmount = 20;
void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0 || Input.GetKeyDown(KeyCode.R))
{
StartCoroutine(Reload());
return;
}
if (Input.GetButton("Fire1"))
{
nextTimeToFire -= Time.deltaTime;
if(nextTimeToFire <= 0)
{
muzzleFlash.Emit(particleAmount);
nextTimeToFire = 1f / fireRate;
Shoot();
}
}
ammoCount.text = "Ammo: " + currentAmmo.ToString();
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
animator.SetBool("Reloading", true);
yield return new WaitForSeconds(reloadTime - .25f);
animator.SetBool("Reloading", false);
yield return new WaitForSeconds(.25f);
currentAmmo = maxAmmo;
isReloading = false;
nextTimeToFire = 0;
}

How to prevent any player Input if the object is moving

I am creating a clone of Billiards and I cannot work out how to stop the player from interacting with and launching the ball while it is still moving; below is my attempt. I have placed an if statement that checks whether the ball is moving on both the mouseDrag and mouseUp functions. I have also tried using isSleeping() but this caused the ball to not move at all.
If possible I would like to apply this method to all of the balls and not just the cue ball; so that all balls have to have stopped before any actions may happen. This is currently in my "player" script, if I should move it a GameManager script please let me know.
private void Update()
{
speed = rb.velocity.magnitude;
if (speed < 0.5)
{
rb.velocity = new Vector3(0, 0, 0);
}
}
void OnMouseDrag()
{
if (speed == 0)
{
mousePointB.GetComponent<SpriteRenderer>().enabled = true;
currDistance = Vector3.Distance(mousePointA.transform.position, transform.position);
if (currDistance <= 3f)
{
spaceLimit = currDistance;
}
else
{
spaceLimit = maxDistance;
}
shootPower = Mathf.Abs(spaceLimit) * shootPowervar;
Vector3 dimxy = mousePointA.transform.position - transform.position;
float difference = dimxy.magnitude;
mousePointB.transform.position = transform.position + ((dimxy / difference) * currDistance * -1);
mousePointB.transform.position = new Vector3(mousePointB.transform.position.x, mousePointB.transform.position.y, -0.8f);
shootDirection = Vector3.Normalize(mousePointA.transform.position - transform.position);
}
else
{
}
}
void OnMouseUp()
{
if (speed == 0)
{
mousePointB.GetComponent<SpriteRenderer>().enabled = false;
arrow.GetComponent<SpriteRenderer>().enabled = false;
circle.GetComponent<SpriteRenderer>().enabled = false;
Vector3 push = shootDirection * shootPower * -1;
GetComponent<Rigidbody2D>().AddForce(push, ForceMode2D.Impulse);
}
else
{
}
}
if your test speed == 0 is not functional, you could record the last position of the ball, and set a boolean isMoving = true, if actual position of ball is different thant the last, then record the lastposition and so on
Vector3 LastPosition;
bool isMoving;
void Update()
{
isMoving = BallPosition == LastPosition;
:
:
}
void OnMOuseDrag()
{
if(!isMoving) return;
}
void OnMOuseUp()
{
if(!isMoving) return;
}

How do I stop the player partly going through ground

I made a controller for a 2d character, I fixed the issue of the player jittering through the wall but I cant fix the player jittering through the ground. Got this code from multiple tutorials and tweaking stuff. If you have any tips that would be greatly appreciated I'm new to this stuff and working on my first game (had to ramble cuz I put too much code) thanks.
{
public float speed, height;
Rigidbody2D rb;
private bool horizontalRight = false;
private bool horizontalLeft = false;
private bool verticalMove = false;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetAxisRaw("Horizontal") > 0)
{
horizontalRight = true;
}
else if (Input.GetAxisRaw("Horizontal") < 0)
{
horizontalLeft = true;
}
if (Input.GetButton("Jump") && rb.velocity.y == 0)
{
verticalMove = true;
}
}
private void FixedUpdate()
{
if (horizontalRight == true)
{
transform.Translate(Vector2.right * Time.deltaTime * speed);
horizontalRight = false;
}
else if (horizontalLeft == true)
{
transform.Translate(Vector2.left * Time.deltaTime * speed);
horizontalLeft = false;
}
if (verticalMove == true)
{
rb.velocity = new Vector2(0, height);
verticalMove = false;
}
}
}
Activate continuous collision detection on your rigid bodies, it'll keep them from phasing through things so long as they're being moved via their velocity.
A typical jump in unity would look like:
void Jump()
{
if (_isGrounded == true)
{
rb.AddForce(Vector2.up * _jumpSpeed);
_isGrounded = false;
}
}
and in collision event
void OnCollisionEnter (Collision hit)
{
_isGrounded = true;
}
this would limit when you can use a jump.

Categories

Resources