How to do Damage During Animation When Enemy Enters Range? - unity3d

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
}
}
}

Related

Unity Making a Board

i'm trying to make a board, that have 12 site. i tried to detect one of them with Overlapsphere, but i'm looking for a method to check the 12 site at the same time. so i can know how many object are in each site. anyone can help ? maybe its possible to create an array of overlapSphere ?
here is the code:enter code here
public int count;
[SerializeField]Vector3 position = new Vector3 (0,0,0);
float radius = 2f;
[SerializeField] public Text counter;
// Start is called before the first frame update
void Start()
{
//detectedball();
}
// Update is called once per frame
void Update()
{
detectedball();
}
void detectedball()
{
Collider[] hitColliders = Physics.OverlapSphere(position, radius);
foreach (var hitCollider in hitColliders)
{
// hitCollider.SendMessage("Detected");
if(gameObject.tag == "Ball")
{
count++;
}
Debug.Log(count);
// counter.text = hitCollider.ToString();
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere( position , radius);
}
}

Why is my player not taking damage from an enemy?

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);

unity2d, trajectory prediction shaking

I'm making a mobile game that uses trajectory to find out the next path from my player. When the player is silent the trajectory works very well, but when the player is moving the trajectory sometimes moves on its own even though it returns to its proper position later, but this is very disturbing.
Here's the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PlayerMovement : MonoBehaviour
{
public static PlayerMovement Instance;
Rigidbody2D rb;
Vector3 startPos;
Vector3 endPos;
[HideInInspector] public Vector3 initPos;
[HideInInspector] public Vector3 direction;
public static Vector3 anotherSpeed; // Only for trajectory
float speedMultiplier = 1.5f;
public GameObject trajectoryDot;
GameObject[] trajectoryDots;
public int numbersOfTrajectory;
float trajectoryDotsDistance = 0.001f;
public static float energy = 100f;
public Slider energyBar;
float slowDownFactor = 0.3f;
private void Start()
{
if (!Instance)
Instance = this;
rb = GetComponent<Rigidbody2D>();
trajectoryDots = new GameObject[numbersOfTrajectory];
}
void Update()
{
anotherSpeed = direction;
if (!Pause.isPaused)
{
// Get Start Position
if (Input.GetMouseButtonDown(0))
{
// Instansiate The Trajectory
for (int i = 0; i < numbersOfTrajectory; i++)
{
trajectoryDots[i] = Instantiate(trajectoryDot,gameObject.transform.position, gameObject.transform.rotation);
}
}
// Get Position When Dragging
if (Input.GetMouseButton(0))
{
EnableSlowMotion();
// Get Drag Position
endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition) + new Vector3(0, 0, 10);
startPos = gameObject.transform.position;
// Get The Speed
direction = endPos - startPos;
direction = direction.normalized;
direction = Vector3.Lerp(transform.position, direction, 500 * Time.deltaTime);
direction = direction * 18;
// Update The Trajectory Position
for (int i = 0; i < numbersOfTrajectory; i++)
{
trajectoryDots[i].transform.position = calculatePosition(i * trajectoryDotsDistance);
}
}
// Get Position When Realeasing
if (Input.GetMouseButtonUp(0))
{
DisableSlowMotion();
// enable Gravity
rb.gravityScale = 1f;
// Move The Player
rb.velocity = new Vector2(direction.x * speedMultiplier, direction.y * speedMultiplier);
// Destroy The Trajectory When Player Release
for (int i = 0; i < numbersOfTrajectory; i++)
{
Destroy(trajectoryDots[i]);
}
}
}
CameraZoom();
ControlsChecker();
}
// Calculate The Trajectory Prediction
Vector2 calculatePosition(float elapsedTime)
{
return new Vector2(startPos.x, startPos.y) +
new Vector2(anotherSpeed.x * speedMultiplier, anotherSpeed.y * speedMultiplier) * elapsedTime +
0.5f * Physics2D.gravity * elapsedTime * elapsedTime;
}
// Check Controls Is pull or push
void ControlsChecker()
{
if (PlayerPrefs.GetInt("Controls") == 1)
{
direction = direction;
anotherSpeed = anotherSpeed;
}
else
{
direction = -direction;
anotherSpeed = -anotherSpeed;
}
}
void EnableSlowMotion()
{
Time.timeScale = slowDownFactor;
Time.fixedDeltaTime = 0.02f * Time.timeScale;
}
void DisableSlowMotion()
{
Time.timeScale = 1f;
Time.fixedDeltaTime = 0.02F;
}
}
void CameraZoom()
{
if (Input.GetMouseButton(0))
{
vcam.m_Lens.OrthographicSize += 0.1f;
if (vcam.m_Lens.OrthographicSize >= maxZoom)
{
vcam.m_Lens.OrthographicSize = maxZoom;
}
}
else if (Input.GetMouseButtonUp(0))
{
zoomIn = true;
}
if (zoomIn)
{
vcam.m_Lens.OrthographicSize -= 0.2f;
if (vcam.m_Lens.OrthographicSize <= minZoom)
{
vcam.m_Lens.OrthographicSize = minZoom;
zoomIn = false;
}
}
}
so I get the player's movement direction from the calculation based on the point where I touch and the point when I release touch (dragging). Did I make a mistake in the code that caused my trajectory to vibrate often? I really need help here, thanks in advance.

animation with transition don't start in unity scene

I have made a fighting game and I don't know where I should integrate my animation in the script. I have 4 actions : Idle , Walk , Kick One , Kick 2 . My script is for phone controllers , where should I put the animations? https://imgur.com/a/dcIevbn and this are some settings to them https://imgur.com/a/v5gJGCa
public class Move : MonoBehaviour
{
private Animator anim;
public float moveSpeed = 300;
public GameObject character;
private Rigidbody characterBody;
private float ScreenWidth;
private Rigidbody rb2d;
public bool isDead = false;
public Vector2 jumpHeight;
public int jumpCount = 0;
internal static object instance;
// Use this for initialization
void Start()
{
ScreenWidth = Screen.width;
characterBody = character.GetComponent<Rigidbody>();
rb2d = this.GetComponent<Rigidbody>();
rb2d.freezeRotation = true;
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (isDead) { return; }
if (jumpCount < 3 && (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))) //makes player jump
{
GetComponent<Rigidbody>().AddForce(jumpHeight, ForceMode.Impulse);
jumpCount++;
}
jumpCount = 0;
int i = 0;
while (i < Input.touchCount)
{
if (Input.GetTouch(i).position.x > ScreenWidth / 2)
{
RunCharacter(1.0f);
}
if (Input.GetTouch(i).position.x < ScreenWidth / 2)
{
RunCharacter(-1.0f);
}
++i;
}
}
void FixedUpdate()
{
#if UNITY_EDITOR
RunCharacter(Input.GetAxis("Horizontal"));
#endif
}
private void RunCharacter(float horizontalInput)
{
characterBody.AddForce(new Vector2(horizontalInput * moveSpeed * Time.deltaTime, 0));
}
}

Make objects between camera and character transparent

I'm working on a script for my camera to make objects between itself and the character transparent.
I managed to make it work with RayCast however I don't know how to restablish objects alpha value after they escape the ray.
This is my current code:
private void XRay() {
float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;
if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {
// Add transparence
Color color = hit.transform.gameObject.renderer.material.color;
color.a = 0.5f;
hit.transform.gameObject.renderer.material.SetColor("_Color", color);
}
}
This is my final code. Note it only makes transparent one object at a time, but the same implementation can easily be done with RaycastAll and using an array for oldHits.
public class Camara : MonoBehaviour {
RaycastHit oldHit;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void FixedUpdate() {
XRay ();
}
// Hacer a los objetos que interfieran con la vision transparentes
private void XRay() {
float characterDistance = Vector3.Distance(transform.position, GameObject.Find("Character").transform.position);
Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;
if (Physics.Raycast(transform.position, fwd, out hit, characterDistance)) {
if(oldHit.transform) {
// Add transparence
Color colorA = oldHit.transform.gameObject.renderer.material.color;
colorA.a = 1f;
oldHit.transform.gameObject.renderer.material.SetColor("_Color", colorA);
}
// Add transparence
Color colorB = hit.transform.gameObject.renderer.material.color;
colorB.a = 0.5f;
hit.transform.gameObject.renderer.material.SetColor("_Color", colorB);
// Save hit
oldHit = hit;
}
}
}
I did attach this script to my simple camera following the player. It might help you.
It can actually manage more than one obstructing the view and also you see I pass it a mask which I target with its name instead of checking for the collider name tag. Have fun.
using UnityEngine;
public class followPlayer : MonoBehaviour
{
public Transform player;
public Vector3 offset;
public Transform[] obstructions;
private int oldHitsNumber;
void Start()
{
oldHitsNumber = 0;
}
private void LateUpdate()
{
viewObstructed();
}
void Update()
{
transform.position = player.TransformPoint(offset);
transform.LookAt(player);
}
void viewObstructed()
{
float characterDistance = Vector3.Distance(transform.position, player.transform.position);
int layerNumber = LayerMask.NameToLayer("Walls");
int layerMask = 1 << layerNumber;
RaycastHit[] hits = Physics.RaycastAll(transform.position, player.position - transform.position, characterDistance, layerMask);
if (hits.Length > 0)
{ // Means that some stuff is blocking the view
int newHits = hits.Length - oldHitsNumber;
if (obstructions != null && obstructions.Length > 0 && newHits < 0)
{
// Repaint all the previous obstructions. Because some of the stuff might be not blocking anymore
for (int i = 0; i < obstructions.Length; i++)
{
obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
}
obstructions = new Transform[hits.Length];
// Hide the current obstructions
for (int i = 0; i < hits.Length; i++)
{
Transform obstruction = hits[i].transform;
obstruction.gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;
obstructions[i] = obstruction;
}
oldHitsNumber = hits.Length;
}
else
{ // Mean that no more stuff is blocking the view and sometimes all the stuff is not blocking as the same time
if (obstructions != null && obstructions.Length > 0)
{
for (int i = 0; i < obstructions.Length; i++)
{
obstructions[i].gameObject.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
}
oldHitsNumber = 0;
obstructions = null;
}
}
}
}