So I am currently Trying to create a zombies game, where I have a script written that would enable a hitting animation if it was "close" to the player.
The code for this script is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ZombieNavMesh : MonoBehaviour
{
private Transform movePositionTransform;
private NavMeshAgent navMeshAgent;
private Animator animator;
static bool close;
private void Start()
{
movePositionTransform = GameObject.Find("Player").transform;
animator = GetComponent<Animator>();
}
private void Awake()
{
navMeshAgent = GetComponent<NavMeshAgent>();
}
private void Update()
{
if (!close)
{
navMeshAgent.destination = movePositionTransform.position;
animator.SetBool("Close", false);
}
if (close)
{
animator.SetBool("Close", true);
}
}
public void OnTriggerEnter(Collider other)
{
if(other.tag == "Player")
{
Debug.Log("Should hit");
close = true;
}
}
public void OnTriggerExit(Collider other)
{
if(other.tag == "Player")
{
Debug.Log("Should not hit");
close = false;
}
}
}
The problem in here is that, if one zombie Enters Trigger, and another zombie Exit Trigger, the bool value close would be set to false, so both would perform walking animation; it should be the "close" zombie hitting animation, and the far zombie walking animation.
Remove the word static from static bool close;
static means there is only one of that thing shared by all versions and instances of the class.
Related
I'm doing a football game and i want it to play a sound every time i score a goal but i can't hear any sound.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
public class gol : MonoBehaviour
{
public AudioClip audioclip;
public AudioSource audiosource;
public bool golmu = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
if (golmu == true && !audiosource.isPlaying)
{
audiosource.clip = audioclip;
audiosource.Play();
}
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "gol")
{
golmu = true;
}
else
{
golmu = false;
}
}
public void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "gol")
{
golmu = false;
}
}
}
I tried without using AudioClip but it's not working. Putting the AudioSource component in another object too. I tried every code I saw but it didn't work.
So i want to check if a spawned Block (prefab) collides with my trigger collider but what i wrote doesn't seem to work. Anyone knows how to correctly check if the colliding GameObject is a Block?
Thanks in Advance. :)
Check:
using System;
using GameOver;
using UnityEngine;
public class gameOver : MonoBehaviour
{
[SerializeField] public DeathScreen deathScreen;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.gameObject.GetType() == typeof(Block))
{
deathScreen.Setup();
}
}
}
Block:
using System;
using TMPro;
using UnityEngine;
public class Block : MonoBehaviour
{
private int _hitsRemaining = 5;
private SpriteRenderer _spriteRenderer;
private TextMeshPro text;
private void Awake()
{
_spriteRenderer = GetComponent<SpriteRenderer>();
text = GetComponentInChildren<TextMeshPro>();
UpdateVisualState();
}
private void UpdateVisualState()
{
text.SetText(_hitsRemaining.ToString());
_spriteRenderer.color = Color.Lerp(new Color(0.35f, 1f, 0.67f), new Color(0.04f, 1f, 0.96f), _hitsRemaining / 10f);
}
private void OnCollisionEnter2D(Collision2D collision)
{
_hitsRemaining--;
if (_hitsRemaining > 0)
UpdateVisualState();
else
Destroy(gameObject);
}
internal void SetHits(int hits)
{
_hitsRemaining = hits;
UpdateVisualState();
}
}
Block Prefab:
Collider:
To check if the collided object is an instantiated Block (or any Block really), you check for the existence of the Block component:
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.GetComponent<Block>() != null)
{
deathScreen.Setup();
}
}
Additionally, with one of your collides being a trigger, OnCollisionEnter2D will not be called. Either switch both to non-triggers if you can, or use OnTriggerEnter2D - but then one of your objects has to have a Rigidbody2D as well (source), so it is really up to what you are designing.
I'm developing a TopDown 2D game in Unity.
The idea is, when the player steps on a certain tile, a UI with text pops up (already working) and the player stops moving until the player clicks a button (already programmed and working) and the UI disappears.
I was advised to turn the RigidBody2D to kinematic however it doesn't work and it just does what it used to do.
Am I doing something wrong?
Here is the code for the trigger script on the tiles:
public class TriggerScript : MonoBehaviour
{
public string popUp;
public void Start()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
Rigidbody2D Player = GameObject.Find("Player").GetComponent<Rigidbody2D>();
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
if (collision.gameObject.tag == "Player")
{
pop.PopUp(popUp);
Player.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Kinematic;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
Rigidbody2D Player = GameObject.Find("Player").GetComponent<Rigidbody2D>();
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
pop.closeBox();
Player.GetComponent<Rigidbody2D>().bodyType = RigidbodyType2D.Dynamic;
}
}
PopUpSystem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PopUpSystem : MonoBehaviour
{
public GameObject popUpBox;
public Animator popupanimation;
public TMP_Text popUpText;
public PLayerController mb;
public void PopUp(string text)
{
popUpBox.SetActive(true);
popUpText.text = text;
popupanimation.SetTrigger("pop");
}
public void closeBox()
{
popupanimation.SetTrigger("close");
mb.camMove = true;
}
}
PLayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PLayerController : MonoBehaviour
{
private Rigidbody2D MyRB;
private Animator myAnim;
[SerializeField]
private float speed;
public bool camMove = true;
// Start is called before the first frame update
void Start()
{
MyRB = GetComponent<Rigidbody2D>();
myAnim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (camMove)
{
MyRB.velocity = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")) * speed * Time.deltaTime;
myAnim.SetFloat("moveX", MyRB.velocity.x);
myAnim.SetFloat("moveY", MyRB.velocity.y);
if ((Input.GetAxisRaw("Horizontal") == 1) || (Input.GetAxisRaw("Horizontal") == -1) || (Input.GetAxisRaw("Vertical") == 1) || (Input.GetAxisRaw("Vertical") == -1))
{
myAnim.SetFloat("LastMoveX", Input.GetAxisRaw("Horizontal"));
myAnim.SetFloat("LastMoveY", Input.GetAxisRaw("Vertical"));
}
}
if (!camMove)
{
MyRB.velocity = new Vector2(0, 0);
}
}
}
TriggerScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TriggerScript : MonoBehaviour
{
public string popUp;
Animator popAnim;
public PLayerController mb;
private void Start()
{
popAnim = GameObject.FindGameObjectWithTag("PopUpBox").GetComponent<Animator>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
var myp = GameObject.FindGameObjectWithTag("Player").GetComponent<PLayerController>();
if (collision.gameObject.tag == "Player")
{
pop.PopUp(popUp);
mb.camMove = false;
}
if (popAnim.GetCurrentAnimatorStateInfo(1).IsName("close"))
{
mb.camMove = true;
Debug.Log("close");
}
}
private void OnTriggerExit2D(Collider2D collision)
{
PopUpSystem pop = GameObject.FindGameObjectWithTag("GameManager").GetComponent<PopUpSystem>();
pop.closeBox();
}
}
Things to keep in mind:
1- Make a new tag and call it PopUpBox. then assign this tag to the Trigger GameObject.
2- To the button of the PopUpBox GameObject (the one which is disabled) assign GameManager GameObject and in its function select PopUpSystem.closeBox
3- In both Trigger GameObject and GameManager assign Player in Mb field.
Hope this help you. You can play with that more to get better results.
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've been trying to make a sliding door for my unity level and I've managed to set up the animations but the scripting that's supposed to link up the functions with the objects isn't working.
Here's the script for the key card:
using UnityEngine;
using System.Collections;
public class Key_Pickup_1 : MonoBehaviour {
public GameObject player;
private Player_inventory playerinventory;
void Awake ()
{
playerinventory = player.GetComponent<Player_inventory>();
}
// Update is called once per frame
void onTriggerEnter()
{
if (gameObject == player)
{
playerinventory.hasKey_1 = true;
Destroy(gameObject);
}
}
}
Here's the script for the Door animation:
using UnityEngine;
using System.Collections;
public class Door_Animation_1 : MonoBehaviour {
public string Open;
private Animator anim_1;
public GameObject player;
private Player_inventory playerInventory;
void Start()
{
anim_1 = GetComponent<Animator>();
player = GameObject.FindGameObjectWithTag("Player");
playerInventory = player.GetComponent<Player_inventory>();
}
void OntriggerEnter (Collider other)
{
if(other.gameObject == player)
{
if (playerInventory.hasKey_1)
{
anim_1.SetTrigger(Open);
}
}
}
Any Ideas?
You don't have the proper capitalization for the OnTriggerEnter methods in your code. You have two different spellings and they are both wrong. It must be exactly OnTriggerEnter (or OnTriggerEnter2D for objects with a Collider2D instead of a Collider).