In Unity I Wrote a code to make a collider sphere that detects an enemy if detected it will go to the enemy but when I run the code it only look at the enemy.
Is there any solution to this problem? it will be greatly appreciated
Here is the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class choclatemilkscirpt : MonoBehaviour
{
NavMeshAgent Agent;
public Patrol patrol;
public Transform MilkSpawner;
public bool chasing;
public Transform[] Points;
[SerializeField]
LayerMask layermask;
public Transform[] Samurais;
public Transform view;
public Transform Point;
public float raydistance = 10f;
public Attack1 attack;
public takingdamage enemyhealth;
public float LookRadius = 10f;
public Transform[] Milk;
public Transform point;
public float enemyview = 5f;
// Start is called before the first frame update
void Start()
{
Agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
Collider[] collider = Physics.OverlapSphere(point.transform.position, LookRadius);
foreach(Collider troops in collider)
{
Debug.Log(transform.name);
if(troops.transform.tag == "Milk")
{
Chaseing(troops.transform);
}
}
void Chaseing(Transform target)
{
Agent.SetDestination(target.position);
}
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(point.transform.position, LookRadius);
}
public void ChasePlayer(Transform target)
{
Agent.SetDestination(target.position);
transform.LookAt(target.position);
}
public void resetView()
{
transform.LookAt(view);
}
void GettingtoGoal()
{
Agent.SetDestination(MilkSpawner.transform.position);
}
}
I try to expand the NavMesh Agent radius, and lift the offset up a bit bit it did not work
Related
I'm a newbie in unity and game development. I'm trying to build a combat 2d game, but I can't damage enemies and I'm banging my head against a wall for 1 week, because I can't see where is the error.
This is my Player script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAttack : MonoBehaviour
{
//[SerializeField] private float attackCooldown;
[SerializeField] private float range;
[SerializeField] private int damage;
[SerializeField] private LayerMask enemyLayer;
public Transform AttackPoint;
//private float cooldownTimer = Mathf.Infinity;
private Animator anim;
private Enemy enemyHealth;
private void Awake()
{
anim = GetComponent<Animator>();
enemyHealth = GetComponent<Enemy>();
}
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
anim.SetTrigger("Attack");
Attack();
Debug.Log("attacking");
}
}
private void OnDrawGizmos()
{
if (AttackPoint == null)
return;
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(AttackPoint.position, range);
}
public void Attack()
{
Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(AttackPoint.position, range, enemyLayer);
foreach (Collider2D Enemy in hitEnemies)
{
if (Enemy.CompareTag("Enemy"))
Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);
Debug.Log("Enemy Hit!");
}
}
}
And this is the Enemy script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
[SerializeField] private float startingHealth;
public float currentHealth;
public Animator anim;
private bool dead;
void Start()
{
currentHealth = startingHealth;
}
public void TakeDamage(float _damage)
{
//currentHealth = Mathf.Clamp(currentHealth - _damage, 0, startingHealth);
if (currentHealth > 0)
{
//hurt anim
Debug.Log("damage taken");
}
if (!dead)
{
//dead anim
GetComponent<EnemyPatrol>().enabled = false; //enemy cannot move while he is dead
GetComponent<EnemyMelee>().enabled = false; //enemy cannot attack
dead = true;
}
}
private void Update() //for testing
{
if (Input.GetKeyDown(KeyCode.P))
TakeDamage(1);
}
}
I tried testing it with the debug, and unity tells me that I'm hitting the enemy but without damaging him.
I tried also to damage the enemy pressing P for testing, and this works.
Thank you guys in advance for your help,
Federico.
Built Player and Enemy scripts. The player can be damaged by enemies but the player cannot damage the enemies.
In your attack function, here:
if (Enemy.CompareTag("Enemy"))
Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);
Debug.Log("Enemy Hit!");
Only the TakeDamage line is inside the if statement, the log is not so it always executes. YOu need to change it look like this:
if (Enemy.CompareTag("Enemy"))
{
Enemy.transform.GetComponent<Enemy>().TakeDamage(damage);
Debug.Log("Enemy Hit!");
}
So the issue is therefore that CompareTag is returning false, if you're seeing the enemy hit log and not the take damage log. The enemy does not have the correct tag.
I'm new to Unity and together with a few friends, I try to make a game. I was trying to connect the healthbar I made to the damage u can deal by shooting knifes. First to test this I used:
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse1))
{
TakeDamage(25);
}
}
Everything worked fine and when I pressed Mouse1 the healthbar worked.My goal was, that when a knife hits the enemy 25 damage is dealt and the healthbar shows that the enemy lost health. However, when the knifes hit the enemy nothing happens. Can you please help me because I tried fixing this for like 3 hours and I'm getting kinda frustrated. Thank you.
Here's the code for the healthbar:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class healthbar : MonoBehaviour
{
public Slider slider;
public void SetMaxHealth(int health)
{
slider.maxValue = health;
slider.value = health;
}
public void SetHealth(int health)
{
slider.value = health;
}
}
And here's the code for the enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy_Follow : MonoBehaviour
{
public float speed;
public Transform target;
public int damage = 25;
public int maxHealth = 100;
public int currentHealth;
public healthbar healthBar;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse1))
{
TakeDamage(25);
}
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
public void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Knife")
{
TakeDamage(25);
}
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
}
After finding out that your colliders are not triggers it should rather be OnCollisionEnter2D like e.g.
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Knife"))
{
TakeDamage(25);
}
}
See also Colliders -> Collision Action Matrix
You may try this code to look if the slider works at all. If this code does work (You can change things with the inspector) then it should be an error with the collision/trigger detection and nothing else.
public class SliderTest : MonoBehaviour {
public Slider slider;
public int maxHealth = 100;
private int currentHealth = 100;
public bool resetHealth = false;
public bool damage = false;
void Start() {
slider = GetComponent<Slider>();
SetMaxHealth(maxHealth);
}
void Update() {
if(resetHealth) {
resetHealth = false;
SetHealth(maxHealth);
}
if(damage) {
damage = false;
SetHealth(currentHealth-10);
}
}
public void SetMaxHealth(int health) {
slider.maxValue = health;
slider.value = 100;
}
public void SetHealth(int health) {
currentHealth = health;
slider.value = currentHealth;
}
}
}
Hey guys I have a made two scripts to handle door opening.
Script 1 - Raycast
Script 2 - The door opening script
I have the raycast on the player camera and I have script 2 on the door.
But there is a problem.
In script 2, I have code that makes UI active and inactive and code that does the door animation
SCRIPT 1 -
using System.Collections.Generic;
using UnityEngine;
public class PlayerCasting : MonoBehaviour
{
public Camera FPScam;
public float range = 6;
public static float ToTarget;
void Update()
{
RaycastHit Hit;
if (Physics.Raycast(FPScam.transform.position, FPScam.transform.forward, out Hit, range))
{
ToTarget = Hit.distance;
}
}
}
SCRIPT 2 -
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DoorOpen : MonoBehaviour
{
public float Distance;
public GameObject key;
public GameObject reason;
public GameObject Hinge;
public AudioSource DoorCreak;
// Update is called once per frame
void Update()
{
Distance = PlayerCasting.ToTarget;
}
private void OnMouseOver()
{
if (Distance <= 3.5f)
{
key.SetActive(true);
reason.SetActive(true);
}
if (Input.GetButtonDown("Action"))
{
if (Distance <= 3.5f)
{
key.SetActive(false);
reason.SetActive(false);
this.GetComponent<BoxCollider>().enabled = false;
Hinge.GetComponent<Animation>().Play("DoorOpenAnim");
DoorCreak.Play();
}
}
}
private void OnMouseExit()
{
key.SetActive(false);
reason.SetActive(false);
}
}
But, the UI doesn't activate nor does the animation plays when I click 'E' and when the Raycast distance <= 3.5.
I have the raycast on the player camera
Since you're using OnMouseOver() and OnMouseExit() your methods will only work when the player's mouse is on the thing you want to raycast.
Make sure that the raycast is actually pointing the same direction the mouse cursor is. You use use Debug.Raycast() to visually see where the raycast is going.
If the raycast is going in the direction you want it to and it's still not working try a different way of communicating through the scripts and avoid using OnMouseOver().
For example you could try something like this:
public class PlayerCasting : MonoBehaviour
{
public Camera FPScam;
public float range = 6;
public static float ToTarget = 0f;
public static GameObject HoveredObject = null; // <----
void Update()
{
RaycastHit Hit;
if (Physics.Raycast(FPScam.transform.position, FPScam.transform.forward, out Hit, range))
{
ToTarget = Hit.distance;
HoveredObject = Hit.collider.gameObject; // <----
}
}
}
public class DoorOpen : MonoBehaviour
{
public float Distance;
public GameObject key;
public GameObject reason;
public GameObject Hinge;
public AudioSource DoorCreak;
// Update is called once per frame
void Update()
{
if (PlayerCasting.HoveredObject == gameObject)
{
Distance = PlayerCasting.ToTarget;
CheckDistance();
}
}
private void CheckDistance()
{
if (Distance <= 3.5f)
{
key.SetActive(true);
reason.SetActive(true);
if (Input.GetButtonDown("Action"))
{
key.SetActive(false);
reason.SetActive(false);
this.GetComponent<BoxCollider>().enabled = false;
Hinge.GetComponent<Animation>().Play("DoorOpenAnim");
DoorCreak.Play();
}
}
else
{
key.SetActive(false);
reason.SetActive(false);
}
}
private void OnMouseExit()
{
key.SetActive(false);
reason.SetActive(false);
}
}
I am creating this flappy bird style game in unity with C#.
I have a scored function in the Game Controller script. Here it is...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameController : MonoBehaviour
{
private int score = 0;
public float starScrollSpeed;
public float groundScrollSpeed;
public float skyScrollSpeed;
public GameObject gameOverText;
public GameObject playAgain;
public bool gameOver = false;
public static GameController instance;
public Text scoreText;
// Start is called before the first frame update
void Awake()
{
if(instance == null)
{
instance = this;
}
else if(instance != this)
{
Destroy(gameObject);
}
}
// Update is called once per frame
void Start()
{
}
void Update()
{
}
public void BirdScored()
{
if (gameOver)
{
return;
}
score++;
scoreText.text = "SCORE " + score.ToString();
}
public void PlaneDestroyed()
{
gameOverText.SetActive(true);
playAgain.SetActive(true);
gameOver = true;
}
}
Actually Bird and Plane is the same thing.
What I want to do is to make the bird score/run the BirdScored() function when the Plane overlaps with a star. The Plane has a Rigidbody2D and a collider and stars have a Rigidbody2D but no collider because In the bird script if the plane collide, it destroys.
Here is the Bird Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bird : MonoBehaviour
{
private bool isDead = false;
private Rigidbody2D rb2d;
public float upforce = 200f;
private Animator anim;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (isDead == false)
{
if (Input.GetMouseButtonDown(0))
{
rb2d.velocity = Vector2.zero;
rb2d.AddForce(new Vector2(0, upforce));
}
}
anim.SetTrigger("Flap");
}
void OnCollisionEnter2D()
{
isDead = true;
anim.SetTrigger("Die");
GameController.instance.PlaneDestroyed();
}
}
And here is the star script...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Stars : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.name == "Plane")
{
GameController.instance.BirdScored();
}
}
}
What is wrong and what should I do?
Put a Colider2D on the star, and check the Is Trigger option in the inspector.
The Is Trigger is disable the collision with any other collider2d so your plane wont be destroyed by the OnCollisionEnter2D, but the OnTriggerEnter2D will trigger properly.
I can see in your screenshot that the collider isn't set to "is trigger", which makes it unable to register trigger collisions.
I'm trying to create a platform that will move player with itself. Both horizontally, as well as vertically. I tried to do this by setting the player's parent to be the platform, but the player doesn't stick to it. This is the code I'm trying to use:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Platform : MonoBehaviour
{
public GameObject player;
public GameObject platformAnchor;
public float movementSpeed;
void Update()
{
transform.position = Vector3.Lerp(transform.position, platformAnchor.transform.position, (Time.deltaTime * movementSpeed));
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject == player)
{
other.transform.parent = transform;
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject == player)
{
other.transform.parent = null;
}
}
}