Why is my player not taking damage from an enemy? - unity3d

I'm working on simple battle system in Unity and I want to make my enemy attack player when he reaches him. After the attack I want the player health to get reduced by damage. The problem is that when my enemy reaches player he doesn't give him any damage despite the fact that console displaying "attacking" information.
Player Script
public class MovementController : MonoBehaviour
{
public int maxHealth = 20;
public int currentHealth;
public HealthBarScript healthBar;
private void Awake()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
}
public void PlayerTakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
public void PlayerHeal(int addHealth)
{
if(currentHealth < maxHealth)
{
currentHealth += addHealth;
}
else if(currentHealth > maxHealth)
{
currentHealth = maxHealth;
}
healthBar.SetHealth(currentHealth);
}
}
Enemy Script
public class EnemyScript : MonoBehaviour
{
private Transform target;
public float speed = 5f;
public float stoppingDistance;
private float timeBtwAttack;
public float startTimeBtwAttack;
public int damage = 1;
public MovementController _player;
void Awake()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
timeBtwAttack = startTimeBtwAttack;
}
void Update()
{
Vector3 dir = target.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(dir);
transform.rotation = rotation;
if (Vector3.Distance(transform.position, target.position) > stoppingDistance)
{
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
else if (Vector3.Distance(transform.position, target.position) < stoppingDistance)
{
transform.position = this.transform.position;
Attack();
}
}
public void Attack()
{
if(timeBtwAttack <= 0)
{
_player.PlayerTakeDamage(damage);
Debug.Log("Attacking");
timeBtwAttack = startTimeBtwAttack;
}
else
{
timeBtwAttack -= Time.deltaTime;
}
}
}
The game is in 3D

Your code looks fine, I think you are just not updating the healthbar in the UI, put this code in attacking and see
Debug.Log("Current Health: ", _player.currentHealth);

Related

How to fix the code, attack the bot and damage the player

I got an error when I finished writing the code
The type or namespace name 'Player' could not be found (are you
missing a using directive or an assembly reference ?)
An error pops up, I checked everything, nothing works, here is the code, I installed everything and the tag on the player does not work. I checked the name of the player, rewrote the code, but it doesn't work. I wanted the bot to turn on the attack animation and deal damage to the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
private float timeBtwAttack;
public float startTimeBtwAttack;
public int health;
public float speed;
public GameObject deathEffect;
public int damage;
private float stopTime;
public float startStopTime;
public float normalSpeed;
private Player player;
private Animator anim;
private void Start()
{
anim = GetComponent<Animator>();
player = FindObjectOfType<Player>();
normalSpeed = speed;
}
private void Update()
{
if(stopTime <= 0)
{
speed = normalSpeed;
}
else
{
speed = 0;
stopTime -= Time.deltaTime;
}
if(health <= 0)
{
Destroy(gameObject);
}
transform.Translate(Vector2.left * speed * Time.deltaTime);
}
public void TakeDamage(int damage)
{
Instantiate(deathEffect, transform.position, Quaternion.identity);
health -= damage;
}
public void OnTriggerStay2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
if(timeBtwAttack <= 0)
{
anim.SetTrigger("attack");
}
else
{
timeBtwAttack -= Time.deltaTime;
}
}
}
public void OnEnemyAttack()
{
}
}

How to remove sticking to the edges of the platform in Unity3d?

I'd like to know how I can get rid of wall sticking in my movement code. I believe the reason is that I implemented it via AddForce, however, I don't know how to fix it. I will be grateful for any help.
Attaching the code:
public class PlayerMovement : MonoBehaviour
{
[Header("Movement")]
public float moveSpeed;
public float walkSpeed;
public float sprintSpeed;
public float groundDrag;
public float jumpForce;
public float jumpCooldown;
public float airMultiplier;
[Header("Keybinds")]
public KeyCode sprintKey = KeyCode.LeftShift;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
public Transform orientation;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
air
}
private void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
}
private void Update()
{
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
SpeedControl();
StateHandler();
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
}
private void StateHandler()
{
if(grounded && Input.GetKey(sprintKey))
{
state = MovementState.sprinting;
moveSpeed = sprintSpeed;
}
else if (grounded)
{
state = MovementState.walking;
moveSpeed = walkSpeed;
}
else
{
state = MovementState.air;
}
}
void MovePlayer()
{
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
if(grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
else if(!grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
}
private void SpeedControl()
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if(flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
}
I left the sprint in the code, because, perhaps, he also looked at something
Addition:
The error occurs when I walk facing the wall (W). If I change direction, then the walk goes fine. I would like to change it to something like sliding like in most games
Ad:
I mean -
enter image description here
The solution is to set the Friction Combine value to Minimum when using the Physic Material

How to do Damage During Animation When Enemy Enters Range?

2D Top Down style game. I’m trying to figure out how to hit an enemy whenever he enters the range of my attack point and get hit every, say, 3 frames if he is still within my attack point. here's my script.
public Animator animator;
public Transform AttackPoint;
public float attackRange = 0.5f;
public LayerMask enemyLayers;
public int attackDamage = 40;
public float attackRate = 1f;
float nextAttackTime = 0f;
// Update is called once per frame
void Update()
{
if(Time.time >= nextAttackTime)
{
if (Input.GetKeyDown(KeyCode.Space))
{
Attack();
nextAttackTime = Time.time + 1f / attackRate;
}
}
}
void Attack()
{
animator.SetTrigger("Attack");
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, attackRange, enemyLayers);
foreach(Collider2D enemy in hitEnemies)
{
enemy.GetComponent<Enemy>().TakeDamage(attackDamage);
}
}
void OnDrawGizmosSelected()
{
if (AttackPoint == null)
return;
Gizmos.DrawWireSphere(AttackPoint.position, attackRange);
}
foreach enemys and check distance with you , and attack it.
and you need a Manager to handle all enemys.
List<Transform> enemys = new List<Transform>();
public void Update()
{
for (int i = 0; i < enemys.Count; i++)
{
float distance = Vector3.Distance(enemys[i].position, transform.position);
if (distance < 10)// in range
{
//todo attack
}
}
}

Problem with my object that does not stop moving

I made a script for moving an object to the position indicated by the mouse click. If I don't choose to click to another location to move towards, I would like to stop my object if it reaches the previously mentioned position. However, the object doesn't stop when reaching the position and it continues moving.
Here is the code I wrote. I would be grateful if somebody knows how to fix this issue.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
private Vector3 targetPos;
private Rigidbody2D rb;
private bool isMoving;
private Vector2 direction;
public float changeDirCooldown;
private float changeCool;
private bool canChangeDir;
void Start()
{
rb = GetComponent<Rigidbody2D>();
changeCool=changeDirCooldown;
canChangeDir =true;
}
void Update()
{
if (Input.GetMouseButton(0) && canChangeDir)
{
changeDirCooldown = changeCool;
SetTargetPosition();
}
if (changeDirCooldown<=0)
{
canChangeDir = true;
}
else
{
changeDirCooldown -= Time.deltaTime;
}
}
private void FixedUpdate()
{
if (isMoving)
{
Move();
}
if (this.transform.position == this.targetPos)
{
isMoving = false;
rb.velocity = Vector2.zero;
}
}
private void SetTargetPosition()
{
targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
targetPos.z = transform.position.z;
direction = targetPos - this.transform.position;
direction = direction.normalized;
isMoving = true;
}
private void Move()
{
rb.velocity = direction * moveSpeed;
canChangeDir = false;
}
}
It's probabily a problem with float number tolerance. This line
this.transform.position == this.targetPos
will almost never result to true, so instead you should do something like this:
Mathf.Abs(this.transform.position.x - this.targetPos.x) < float.Epsilon &&
Mathf.Abs(this.transform.position.y - this.targetPos.y) < float.Epsilon

Unity3D Character Controller set speed through script?

How would I be able to set the speed for going forward and back in the Void FixedUpdate? Or is there a better way for doing this? I need to use the character controller though.
using UnityEngine;
using System.Collections;
public class CharacterControllerz : MonoBehaviour {
public float speed;
private CharacterController playerController;
void Start()
{
playerController = GetComponent<CharacterController>();
}
void Update()
{
}
void FixedUpdate()
{
if (Input.GetKey("right"))
{
playerController.Move (Vector3.forward);
Debug.Log ("RIGHT");
}
if (Input.GetKey("left"))
{
playerController.Move (Vector3.back);
Debug.Log ("LEFT");
}
playerController.Move (Vector3.left);
}
}
public float speed = 5f;
public float jumpStrenght = 8f;
public float gravity = 20f;
private Vector3 moveDirections = new Vector3();
private Vector3 inputs = new Vector3();
void FixedUpdate()
{
CharacterController cc = GetComponent<CharacterController>();
if (cc.isGrounded)
{
if (Input.GetKey("right"))
inputs.z = 1;
if (Input.GetKey("left"))
inputs.z = -1;
if (Input.GetKey("up"))
inputs.y = jumpStrenght;
moveDirections = transform.TransformDirection(inputs.x, 0, inputs.z) * speed;
}
moveDirections.y = inputs.y - gravity;
cc.Move(moveDirections * Time.deltaTime);
}
I think that's what you want but you may have to switch the axis.
Edit: Why is TransformDirection used? Because we want to move the object in a direction which shouldn't be relativ to the object's rotation.