I'm having some difficulties with my shooting script. Normally the bullets works just fine but sometimes(totally random) I can't shoot any more.
I can see the sprite right beside my character but it doesn't move. And if that happens it can't be fixed until I restart the game.
The weapon Script is on the player
public class weaponScript : MonoBehaviour {
public Transform shotPrefab;
public float shootingRate = 0.25f;
private float shootCooldown;
public float xtrans;
void Start(){
shootCooldown = 0f;
}
void Update(){
if (shootCooldown > 0){
shootCooldown -= Time.deltaTime;
}
}
public void Attack(bool isEnemy)
{
if (CanAttack){
if(PinkPlayerControler.playerFaceRight == true)
xtrans = transform.position.x + 2f;
else if(PinkPlayerControler.playerFaceRight == false)
xtrans = transform.position.x - 2f;
shootCooldown = shootingRate;
var shotTransform = Instantiate(shotPrefab) as Transform;
//shotTransform.position = transform.position;
shotTransform.position = new Vector3(xtrans, transform.position.y,transform.position.z);
}
}
public bool CanAttack
{
get{
return shootCooldown <= 0f;
}
}
}
And the other two on the bullet
public class bulletMove : MonoBehaviour {
public Vector2 jumpVector;
public int speed;
void Update(){
startMovement ();
}
void startMovement(){
if (PinkPlayerControler.playerFaceRight == true) {
rigidbody2D.velocity = transform.right.normalized * speed;
Destroy(this);
}
else {
rigidbody2D.velocity = -transform.right.normalized * speed;
Destroy(this);
}
}
void OnTriggerEnter2D(Collider2D other){
if (other.tag == "bulletDeath" || other.tag == "groundTrap")
Destroy (this.gameObject);
else if (other.tag == "destroyByBullet") {
Debug.Log("blockHit");
Destroy (other.gameObject);
Destroy(this.gameObject);
}
}
}
Shoot Script
public class shootScript : MonoBehaviour {
public static int damage = 1;
public static bool hit = false;
void Start()
{
Destroy(gameObject, 2);
}
void Update(){
if (hit == true)
Destroy (this.gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "bullet") {
Destroy(other.gameObject);
}
}
}
I don't get why it stops to work so randomly.
Thanks in advance :)
Chrizzly
Related
I am fairly new to C# and am currently trying to expand upon Ruby's Tutorial by adding in an ammo limitation function that controls the amount of Cogs Ruby has at a time as well as her ability to pick up extra ammo. Right now my script is not limiting the number of rounds Ruby can fire and is stuck displaying "Cogs: 4". She is able to pick up the ammo (pickup set to is trigger) but it is not updating the Cogs. Please help, I would love to understand what I am possibly doing wrong as my code is not displaying any errors.
Ruby's Controller Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
public class RubyController : MonoBehaviour
{
public float speed = 3.0f;
public int maxHealth = 5;
public GameObject projectilePrefab;
public int Score;
int Cog;
public static int CogAmount = 4;
public TextMeshProUGUI scoreText;
public TextMeshProUGUI CogText;
public GameObject winTextObject;
public GameObject loseTextObject;
public GameObject BackgroundMusicObject;
public GameObject WinSoundObject;
public GameObject LoseSoundObject;
public AudioClip throwSound;
public AudioClip hitSound;
public AudioClip collectedClip;
public int health { get { return currentHealth; }}
int currentHealth;
public float timeInvincible = 2.0f;
bool isInvincible;
float invincibleTimer;
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
public ParticleSystem HealthIncrease;
public ParticleSystem HealthDecrease;
Animator animator;
Vector2 lookDirection = new Vector2(1,0);
AudioSource audioSource;
// Start is called before the first frame update
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
currentHealth = maxHealth;
audioSource = GetComponent<AudioSource>();
Score = 0;
Cog = 4;
SetCogText();
winTextObject.SetActive(false);
loseTextObject.SetActive(false);
WinSoundObject.SetActive(false);
LoseSoundObject.SetActive(false);
HealthIncrease.Stop();
HealthDecrease.Stop();
}
public void ChangeScore(int scoreAmount)
{
{
Score++;
scoreText.text = "Fixed Robots: " + Score.ToString();
}
}
// Update is called once per frame
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical);
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
{
lookDirection.Set(move.x, move.y);
lookDirection.Normalize();
}
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
if (isInvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
isInvincible = false;
}
if(Input.GetKeyDown(KeyCode.C) && Cog >= 1)
{
Cog = Cog -1;
Launch();
}
else if (Input.GetKeyDown(KeyCode.C) && Cog ==0)
{
return;
}
if (Input.GetKeyDown(KeyCode.X))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
if (hit.collider != null)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
character.DisplayDialog();
}
}
}
if (CogAmount > 0)
{
CogText.text = "Cogs: " + CogAmount;
}
else if (CogAmount <= 0)
{
CogText.text = "Out of Cogs!";
}
if (Score >= 4)
{
winTextObject.SetActive(true);
{
if(Input.GetKeyDown(KeyCode.R))
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
speed = 0;
WinSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
}
}
else if (currentHealth == 0)
{
loseTextObject.SetActive(true);
{
if(Input.GetKeyDown(KeyCode.R))
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
speed = 0;
LoseSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
}
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position.x = position.x + speed * horizontal * Time.deltaTime;
position.y = position.y + speed * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
void SetCogText()
{
CogText.text = "Cogs: " + Cog.ToString();
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Cog"))
{
Cog = Cog + 3;
other.gameObject.SetActive(false);
}
}
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
return;
isInvincible = true;
invincibleTimer = timeInvincible;
GameObject projectileObject = Instantiate(HealthDecrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
PlaySound(hitSound);
}
if (amount < 5)
{
GameObject projectileObject = Instantiate(HealthIncrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UIHealthBar.instance.SetValue(currentHealth / (float)maxHealth);
}
void Launch()
{
GameObject projectileObject = Instantiate(projectilePrefab, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
PlaySound(throwSound);
}
public void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}
}
Projectile Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
Rigidbody2D rigidbody2d;
void Awake()
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
public void Launch(Vector2 direction, float force)
{
rigidbody2d.AddForce(direction * force);
}
void Update()
{
if(transform.position.magnitude > 1000.0f)
{
Destroy(gameObject);
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "Enemy")
{
EnemyController e = other.collider.GetComponent<EnemyController>();
if (e != null)
{
e.Fix();
}
}
else if (other.gameObject.tag == "HardEnemy")
{
HardEnemyController e = other.collider.GetComponent<HardEnemyController>();
if (e != null)
{
e.Fix();
}
}
Destroy(gameObject);
}
}
Ok after a bit of trial and error I believe I have finally fixed the issue. I will post my updated script for anyone wanting to compare and/or learn from my mistakes lol. Basically I utilized a SetCogText(); variable in the start function and throughout my code to update my TextMeshPro; and removed the public static int CogAmount = 0; I initially used in my code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
public class RubyController : MonoBehaviour
{
public float speed = 3.0f;
public int maxHealth = 5;
public GameObject projectilePrefab;
public int Score;
int Cog;
public TextMeshProUGUI scoreText;
public TextMeshProUGUI CogText;
public GameObject winTextObject;
public GameObject loseTextObject;
public GameObject LevelOneTextObject;
public GameObject BackgroundMusicObject;
public GameObject WinSoundObject;
public GameObject LoseSoundObject;
private static int Level;
public AudioClip throwSound;
public AudioClip hitSound;
public AudioClip collectedClip;
public int health { get { return currentHealth; }}
int currentHealth;
public float timeInvincible = 2.0f;
bool isInvincible;
float invincibleTimer;
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
public ParticleSystem HealthIncrease;
public ParticleSystem HealthDecrease;
Animator animator;
Vector2 lookDirection = new Vector2(1,0);
AudioSource audioSource;
// Start is called before the first frame update
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
currentHealth = maxHealth;
audioSource = GetComponent<AudioSource>();
Score = 0;
Cog = 4;
SetCogText();
winTextObject.SetActive(false);
loseTextObject.SetActive(false);
LevelOneTextObject.SetActive(false);
WinSoundObject.SetActive(false);
LoseSoundObject.SetActive(false);
HealthIncrease.Stop();
HealthDecrease.Stop();
}
public void ChangeScore(int scoreAmount)
{
{
Score++;
scoreText.text = "Fixed Robots: " + Score.ToString();
}
if (Level == 1)
{
if (Score == 4)
{
LevelOneTextObject.SetActive(true);
}
}
if (Level == 2)
{
if(Score == 4)
{
winTextObject.SetActive(true);
{
if(Input.GetKeyDown(KeyCode.R))
SceneManager.LoadScene(1);
speed = 0;
WinSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
}
}
}
}
// Update is called once per frame
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical);
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
{
lookDirection.Set(move.x, move.y);
lookDirection.Normalize();
}
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
if (isInvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
isInvincible = false;
}
if(Input.GetKeyDown(KeyCode.C) && Cog >= 1)
{
Cog = Cog -1;
SetCogText();
Launch();
}
else if (Input.GetKeyDown(KeyCode.C) && Cog ==0)
{
return;
}
if (Input.GetKeyDown(KeyCode.X))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
if (hit.collider != null)
{
if (Score >= 4)
{
Level = 2;
SceneManager.LoadScene(2);
Score = 4;
}
else if (Score < 4)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
character.DisplayDialog();
}
}
}
}
if (currentHealth == 0)
{
loseTextObject.SetActive(true);
{
if(Input.GetKeyDown(KeyCode.R))
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
speed = 0;
LoseSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
}
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
void SetCogText()
{
if (Cog > 0)
{
CogText.text = "Cogs: " + Cog.ToString();
}
else if (Cog <= 0)
{
CogText.text = "Out of Cogs!";
SetCogText();
}
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position.x = position.x + speed * horizontal * Time.deltaTime;
position.y = position.y + speed * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Cog"))
{
Cog = Cog + 3;
other.gameObject.SetActive(false);
SetCogText();
}
}
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
return;
isInvincible = true;
invincibleTimer = timeInvincible;
GameObject projectileObject = Instantiate(HealthDecrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
PlaySound(hitSound);
}
if (amount < 5)
{
GameObject projectileObject = Instantiate(HealthIncrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UIHealthBar.instance.SetValue(currentHealth / (float)maxHealth);
}
void Launch()
{
GameObject projectileObject = Instantiate(projectilePrefab, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
PlaySound(throwSound);
}
public void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}
}
I have this code for a Weapon with reloading, and if I start to reload, switch to a different weapon, and the switch back to the weapon that should be reloading, The weapon doesn't reload, can't shoot, and will Display the AmmoDisplay of the previous weapons... any idea why? I tried setting the IEnumerator to public, but that didn't work either.
using UnityEngine;
using System.Collections;
using TMPro;
public class GunScript_SB : MonoBehaviour
{
public float damage = 10f;
public float range = 100f;
public float impactForce = 30f;
public float fireRate = 15f;
public float maxAmmo = 10;
private float currentAmmo;
public float reloadTime = 3f;
private bool isReloading = false;
public Camera fpsCam;
public ParticleSystem muzzleFlash;
public GameObject impactEffect;
public TextMeshProUGUI ammunitionDisplay;
private float nextTimeToFire = 0;
void Start()
{
currentAmmo = maxAmmo;
}
void onEnable()
{
isReloading = false;
AmmoDisplay();
}
// Update is called once per frame
void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
if (Input.GetButtonDown("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
if (ammunitionDisplay != null)
{
AmmoDisplay();
}
if (Input.GetKeyDown(KeyCode.R) && currentAmmo < maxAmmo)
{
StartCoroutine(Reload());
}
}
public IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
yield return new WaitForSeconds(reloadTime);
currentAmmo = maxAmmo;
isReloading = false;
}
void Shoot()
{
muzzleFlash.Play();
currentAmmo--;
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(impactGO, 1f);
}
}
void AmmoDisplay()
{
ammunitionDisplay.SetText(currentAmmo + " / " + maxAmmo);
}
}
Your coroutine could possibly still running after switching weapon. Add a referencing field and stop the coroutine before starting it again:
private Coroutine reloadCoroutine;
if (reloadCoroutine != null){
StopCoroutine(reloadCoroutine);
}
reloadCoroutine = StartCoroutine(Reload());
I am trying to add a double jump to my player but I have this error
and I am having problems with curly Brackets Because In The Begging Of The Code Must Contain = public class PlayerController: MonoBehaviour{
and end in }
the code is this if anyone that sees this knows C# And Can Help You Have My Thanks
using System.Collections;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
private float moveSpeedStore;
public float speedMultiplier;
public float speedIncreaseMilestone;
private float speedIncreaseMilestoneStore;
private float speedMilestoneCount;
private float speedMilestoneCountStore;
public float jumpForce;
public float jumpTime;
private float jumpTimeCounter;
private Rigidbody2D myRigidbody;
private bool canDoubleJump;
public bool grounded;
public LayerMask whatIsGround;
public Transform groundCheck;
public float groundCheckSize;
private Collider2D myCollider;
private Animator myAnimator;
private bool stoppedJumping;
public GameManeger theGameManeger;
void Start()
{
myRigidbody = GetComponent<Rigidbody2D>();
myCollider = GetComponent<Collider2D>();
myAnimator = GetComponent<Animator>();
jumpTimeCounter = jumpTime;
speedMilestoneCount = speedIncreaseMilestone;
moveSpeedStore = moveSpeed;
speedMilestoneCountStore = speedMilestoneCount;
speedIncreaseMilestoneStore = speedIncreaseMilestone;
stoppedJumping = true;
}
void Update()
{
//grounded = Physics2D.IsTouchingLayers(myCollider, whatIsGround);
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckSize, whatIsGround);
if (transform.position.x > speedMilestoneCount)
{
speedMilestoneCount += speedIncreaseMilestone;
speedIncreaseMilestone = speedIncreaseMilestone * speedMultiplier;
moveSpeed = moveSpeed * speedMultiplier;
}
myRigidbody.velocity = new Vector2(moveSpeed, myRigidbody.velocity.y);
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0))
{
if (grounded)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
stoppedJumping = false;
}
}
if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0) && !stoppedJumping)
{
if (jumpTimeCounter > 0)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
jumpTimeCounter -= Time.deltaTime;
}
if (!grounded && canDoubleJump)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
stoppedJumping = false;
canDoubleJump = false;
}
}
if (Input.GetKeyUp(KeyCode.Space) || Input.GetMouseButtonUp(0))
{
jumpTimeCounter = 0;
stoppedJumping = true;
}
if (grounded)
{
jumpTimeCounter = jumpTime;
canDoubleJump = true;
}
myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
myAnimator.SetBool("Grounded", grounded);
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "killbox")
{
theGameManeger.RestartGame();
moveSpeed = moveSpeedStore;
speedMilestoneCount = speedMilestoneCountStore;
speedIncreaseMilestone = speedIncreaseMilestoneStore;
}
}
}
``````
Check for any additional closing brackets } you might have added by mistake, or maybe a missing one, i'd suggest using an IDE as they are made to detect these types of mistakes.
I believe Chris Dunaway is correct. It looks like there's an extra curly brace in your code that pushed the last method out of the class.
So this (SO forced formatting):
[...]
myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
myAnimator.SetBool("Grounded", grounded);
}
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "killbox")
{
theGameManeger.RestartGame();
moveSpeed = moveSpeedStore;
speedMilestoneCount = speedMilestoneCountStore;
speedIncreaseMilestone = speedIncreaseMilestoneStore;
}
}
}
Should be this:
[...]
myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
myAnimator.SetBool("Grounded", grounded);
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "killbox")
{
theGameManeger.RestartGame();
moveSpeed = moveSpeedStore;
speedMilestoneCount = speedMilestoneCountStore;
speedIncreaseMilestone = speedIncreaseMilestoneStore;
}
}
}
I am finding it hard to figure out why my transform is wrong. Can anyone help me on this problem. I am trying to make a FSM for my enemy so it either goes for the player or go for food. But when I try to test it I get a compiler error.
using UnityEngine;
using System.Collections;
public class Enemy : MovingObject
{
public int playerDamage;
private Animator animator;
private Transform target;
private bool skipMove;
private Transform Player;
public AudioClip enemyAttack1;
public AudioClip enemyAttack2;
protected override void Start ()
{
GameManager.instance.AddEnemeyToList(this);
animator = GetComponent<Animator> ();
target = GameObject.FindGameObjectWithTag ("Food").transform;
base.Start ();
AIEnemy();
Player = GameObject.FindWithTag("Player").transform;
}
protected override void AttemptMove<T> (int xDir, int yDir)
{
if (skipMove)
{
skipMove = false;
return;
}
base.AttemptMove <T> (xDir, yDir);
skipMove = true;
}
public void MoveEnemy()
{
int xDir = 0;
int yDir = 0;
if (Mathf.Abs (target.position.x - transform.position.x) < float.Epsilon)
yDir = target.position.y > transform.position.y ? 1 : -1;
else
xDir = target.position.x > transform.position.x ? 1 : -1;
AttemptMove<Player> (xDir, yDir);
}
protected override void OnCantMove <T> (T component)
{
Player hitPlayer = component as Player;
hitPlayer.LoseFood (playerDamage);
animator.SetTrigger("enemyAttack");
SoundManager.instance.RandomizeSfx (enemyAttack1, enemyAttack2);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Food")
{
other.gameObject.SetActive(false);
}
else if (other.tag == "Soda")
{
other.gameObject.SetActive(false);
}
}
void AIEnemy()
{
int State = 0;
if (State == 0)
{
transform.LookAt(Player);
State++;
}
if (State == 1)
transform.LookAt(target);
Debug.Log("State 1");
State++;
if (State == 2)
{
Debug.Log("State 2");
}
}
}
public Transform FindClosetFood()
{
float minDistance = float.PositiveInfinity;
Transform closetFood = null;
GameObject[] foods = GameObject.FindGameObjectsWithTag("Food");
for(int i = 0; i<foods.Length; i++)
{
float distance = Vector2.Distance(transform.position, foods[i].transform.position);
if (distance < minDistance)
{
minDistance = distance;
closetFood = foods[i].transform;
}
}
return closetFood;
}
}
I added a private Transform Player. So my enemy knows what to look at but I still dont get anything in console. And I tried calling it in start. But now I ended up with this compiler error.
The error comes in this line
float distance = Vector2.Distance("transform".position, foods[i].transform.position);
MovingObject script:
using UnityEngine;
using System.Collections;
public abstract class MovingObject : MonoBehaviour
{
public float moveTime = 0.1f;
public LayerMask blockingLayer;
private BoxCollider2D boxCollider;
private Rigidbody2D rb2D;
private float inverseMoveTime;
// Use this for initialization
protected virtual void Start ()
{
boxCollider = GetComponent<BoxCollider2D> ();
rb2D = GetComponent<Rigidbody2D> ();
inverseMoveTime = 1f / moveTime;
}
protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
{
Vector2 start = transform.position;
Vector2 end = start + new Vector2 (xDir, yDir);
boxCollider.enabled = false;
hit = Physics2D.Linecast (start, end, blockingLayer);
boxCollider.enabled = true;
if (hit.transform == null)
{
StartCoroutine(SmoothMovement (end));
return true;
}
return false;
}
protected IEnumerator SmoothMovement (Vector3 end)
{
float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
while (sqrRemainingDistance > float.Epsilon)
{
Vector3 newPosition = Vector3.MoveTowards (rb2D.position, end, inverseMoveTime * Time.deltaTime);
rb2D.MovePosition(newPosition);
sqrRemainingDistance = (transform.position - end).sqrMagnitude;
yield return null;
}
}
protected virtual void AttemptMove <T> (int xDir, int yDir) where T : Component
{
RaycastHit2D hit;
bool canMove = Move (xDir, yDir, out hit);
if (hit.transform == null)
return;
T hitComponent = hit.transform.GetComponent<T> ();
if(!canMove && hitComponent != null)
OnCantMove (hitComponent);
}
protected abstract void OnCantMove <T> (T component) where T : Component;
}
It can't find transform.position because transform is a variable undeclared under Component. MonoBehaviour drives from Behaviour and Behaviour derives from Component. To get access to the transform variable, your script must derive from one of these. Although MonoBehaviour is what the script should derive from.
In code, your Enemy script already derive from MovingObject script which derives from MonoBehaviour so that should give you access to the transform variable but there is a problem. There is an extra } at the end of the AIEnemy() function in your Enemy script. That extra } at the end of the AIEnemy() function closes or marks the end of the Enemy script therefore making the transform variable unavailable to you. Remove the extra } at the end of the AIEnemy() function and your problem should be fixed.
If you can't find it, use the new Enemy script below:
public class Enemy : MovingObject
{
public int playerDamage;
private Animator animator;
private Transform target;
private bool skipMove;
private Transform Player;
public AudioClip enemyAttack1;
public AudioClip enemyAttack2;
protected override void Start()
{
GameManager.instance.AddEnemeyToList(this);
animator = GetComponent<Animator>();
target = GameObject.FindGameObjectWithTag("Food").transform;
base.Start();
AIEnemy();
Player = GameObject.FindWithTag("Player").transform;
}
protected override void AttemptMove<T>(int xDir, int yDir)
{
if (skipMove)
{
skipMove = false;
return;
}
base.AttemptMove<T>(xDir, yDir);
skipMove = true;
}
public void MoveEnemy()
{
int xDir = 0;
int yDir = 0;
if (Mathf.Abs(target.position.x - transform.position.x) < float.Epsilon)
yDir = target.position.y > transform.position.y ? 1 : -1;
else
xDir = target.position.x > transform.position.x ? 1 : -1;
AttemptMove<Player>(xDir, yDir);
}
protected override void OnCantMove<T>(T component)
{
Player hitPlayer = component as Player;
hitPlayer.LoseFood(playerDamage);
animator.SetTrigger("enemyAttack");
SoundManager.instance.RandomizeSfx(enemyAttack1, enemyAttack2);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Food")
{
other.gameObject.SetActive(false);
}
else if (other.tag == "Soda")
{
other.gameObject.SetActive(false);
}
}
void AIEnemy()
{
int State = 0;
if (State == 0)
{
transform.LookAt(Player);
State++;
}
if (State == 1)
transform.LookAt(target);
Debug.Log("State 1");
State++;
if (State == 2)
{
Debug.Log("State 2");
}
}
public Transform FindClosetFood()
{
float minDistance = float.PositiveInfinity;
Transform closetFood = null;
GameObject[] foods = GameObject.FindGameObjectsWithTag("Food");
for (int i = 0; i < foods.Length; i++)
{
float distance = Vector2.Distance(transform.position, foods[i].transform.position);
if (distance < minDistance)
{
minDistance = distance;
closetFood = foods[i].transform;
}
}
return closetFood;
}
}
So I have enemy gameobjects attacking a user in a small base. The enemies have an OnCollisionEnter method where it checks to see what it collides with. If it's tagged as the base, it sets an attack boolean to true, where the fixedupdate is supposed to check for that flag. When true, it calls a coroutine in which I try and call the method that removes health from the wall (this script is attached to the wall). The walls health is then displayed on a HUD I have elsewhere in the room Code Below
Problem is, enemies can't do damage to the base and the HUD remains unchanging. Any tips/help? Here is the enemy behaviour script
public class EnemyBehaviour : MonoBehaviour {
private GameObject target;
private Vector3 targetPos;
private WallBehaviour wallBehaviour;
public GameObject collisionObject;
private bool attackMode;
public float speed = 0.1f;
public int hp = 100;
public float attackCooldown = 1.0f;
public int attackPoints = 1;
public float killThreshhold = 1.5f;
public Color defaultColor;
//Use this for initialization
void Start() {
target = GameObject.FindGameObjectWithTag("MainCamera");
targetPos = target.transform.position;
attackMode = false;
}
void FixedUpdate() {
targetPos = target.transform.position;
transform.LookAt(target.transform);
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
if (attackMode)
{
StartCoroutine("attemptAttack");
}
else
{
GetComponent<Renderer>().material.color = defaultColor;
}
}
void OnCollisionEnter(Collision collision)
{
collisionObject = collision.gameObject;
if (collision.gameObject.tag == "Bunker") {
wallBehaviour = collision.gameObject.GetComponent<WallBehaviour>();
attackMode = true;
}
}
public IEnumerator Attack()
{
attackMode = false;
GetComponent<Renderer>().material.color = Color.red;
wallBehaviour.ProcessDamage(attackPoints);
yield return new WaitForSeconds(attackCooldown);
attackMode = true;
}
void ProcessDamage(int attackPoints)
{
hp -= attackPoints;
if (hp <= 0)
{
Die();
}
}
public int getHitPoints()
{
return hp;
}
public void Damage(DamageInfo info)
{
hp -= info.damage;
if (hp <= 0) {
Die();
}
}
public void Die()
{
Destroy(gameObject);
}