I'm trying to have an if condition to do something if the sprite renderer of another object is enabled, but it won't work.
Here's the code I tried:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUpReCharge : MonoBehaviour
{
public Animator anim;
public Animator animc;
public Animator anime;
public GameObject neon;
public GameObject chargesprite;
public AudioSource recharge;
public BoxCollider2D collision;
public SpriteRenderer blackout;
public AudioSource ambient;
public AudioSource music;
void Start()
{
anime.Play("Pickup", 0, 1f);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
neon.GetComponent<PlayerMovement>().enabled = true;
chargesprite.GetComponent<SpriteRenderer>().enabled = false;
collision.GetComponent<BoxCollider2D>().enabled = false;
anim.SetBool("IsDead", false);
anim.Rebind();
animc.Rebind();
anime.Rebind();
recharge.Play();
Destroy(gameObject, 3.0f);
//activate blackout
blackout.GetComponent<SpriteRenderer>().enabled = false;
if (blackout.enabled)
{
ambient.Play();
music.Play();
}
}
}
}
The public blackout has a sprite renderer that is disabled. When enabled, I want the last bit of code to run but it won't.
What's wrong with it?
Prodian asked if I tried gameobject.activeself, and I want to thank you for the advice. It works perfectly! I changed the reference type to gameobject and reaasigned it and made the necessary and it works like a charm now!
Here's the full new code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUpReCharge : MonoBehaviour
{
public Animator anim;
public Animator animc;
public Animator anime;
public GameObject neon;
public GameObject chargesprite;
public AudioSource recharge;
public BoxCollider2D collision;
public GameObject blackout;
public AudioSource ambient;
public AudioSource music;
void Start()
{
anime.Play("Pickup", 0, 1f);
}
void Update()
{
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
neon.GetComponent<PlayerMovement>().enabled = true;
chargesprite.GetComponent<SpriteRenderer>().enabled = false;
collision.GetComponent<BoxCollider2D>().enabled = false;
anim.SetBool("IsDead", false);
anim.Rebind();
animc.Rebind();
anime.Rebind();
recharge.Play();
Destroy(gameObject, 3.0f);
if (blackout.gameObject.activeSelf)
{
ambient.Play();
music.Play();
}
blackout.gameObject.SetActive(false);
}
}
}
EDIT: One more thing to note! The location of the if statement WAS important. It should have been before the code that makes the sprite false. This means the previous code would've worked if that had been done, but the gameobject code is much better for me because the blackout layer is one that I need to be OFF all the time.
Basically, my old code works! Just move the if statement before the "getcomponent......enabled = false" because the script is read in order.
Your blackout is SpriteRenderer so calling GetComponent on it is invalid. Change that to:
blackout.enabled = true;
Or use:
anotherGameObject.GetComponent<SpriteRenderer>().enabled = true;
Calling SetActive on a GameObject will disable not only the SpriteRenderer component! In some cases this changes your desired behaviour.
Related
I want to move multiple characters using a single animation. I tried to use loop for this but failed. Can you help? I want to return the characters I added under GameObject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ses : MonoBehaviour
{
AudioSource audioSource;
public Animator animator;
public GameObject[] karakul;
void Start()
{
audioSource = GetComponent<AudioSource>();
//animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
}
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "sayiCollider")
{
audioSource.Play();
foreach (var item in karakul)
{
animator.SetBool("clap", true);
}
}
else
{
animator.SetBool("clap", false);
}
}
}
enter image description here
enter image description here
enter image description here
You are iterating through the GameObjects, and every time set a param on an animator, which is nothing to do with those GameObjects.
Usually, the crowd has solved another way for performance, but to answer your question, you need to add an Animator component to all GameObject you want to animate and call the SetBool on them, something like that:
[SerializeField] private Animator[] _animators;
private void OnTiggerEnter(Collider other)
{
bool isSayi = other.CompareTag("sayiCollider");
if (isSayi) audioSource.Play();
else audioSource.Stop();
for (int i = 0; i < _animators.Length; i++) _animators[i].SetBool("clap", isSayi);
}
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 was trying to find the answer for the last 3 hours and I couldn't find anything that would help me. It shows that the camera already has constraints when it enters the cube, so it works, but it doesn't because it's not freezing the camera. I don't know what to do already.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LCOE : MonoBehaviour
{
public GameObject cam;
Rigidbody rig;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
cam.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
}
}
private void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
cam.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
}
}
}
Changing constrains or isKinematic on Rigidbody will only disable physics movement, but it will still move together with parent object. Your camera should not be child of player and script attached to camera should look like that:
class MyCamera : MonoBehaviour{
public Transform target;
public Vector3 offset;
public bool isMovementDisabled;
void LateUpdate(){
if(isMovementDisabled)
return;
transform.position = target.position + offset;
}
}
Or use cinemachine
The idea is to add a Rigidbody to some doors and use Is Kinematic so when a npc/enemy will walk through the doors they will open/close.
But when I'm running the game the doors open automatic without anything triggering it.
Maybe I didn't add the Rigidbody to the right place in the door the right object/child ?
A screenshot of a door one of few I have:
Each Collision (1) to Collision(11) have attached a Box Collider. On each one the Is Trigger is unchecked !
The Horizontal_Doors_Kit have attached a Box Collider and the Is Trigger is check enabled ! And also attached to it a script Hori Door Manager:
using UnityEngine;
using System.Collections;
public class HoriDoorManager : MonoBehaviour
{
public DoorHori door1;
public DoorHori door2;
public static bool doorLockState;
void OnTriggerEnter()
{
if (doorLockState == false)
{
if (door1 != null)
{
door1.OpenDoor();
}
if (door2 != null)
{
door2.OpenDoor();
}
}
}
}
Wall_Door_Long_01 have attached a Mesh Renderer.
Door_Left and Door_Right have a Mesh Renderer , Audio Source , a script and a Box Collider where Is Trigger unchecked !
The script is attached to door left and to door right:
using UnityEngine;
using System.Collections;
public class DoorHori : MonoBehaviour {
public float translateValue;
public float easeTime;
public OTween.EaseType ease;
public float waitTime;
private Vector3 StartlocalPos;
private Vector3 endlocalPos;
private void Start(){
StartlocalPos = transform.localPosition;
gameObject.isStatic = false;
}
public void OpenDoor(){
OTween.ValueTo( gameObject,ease,0.0f,-translateValue,easeTime,0.0f,"StartOpen","UpdateOpenDoor","EndOpen");
GetComponent<AudioSource>().Play();
}
private void UpdateOpenDoor(float f){
Vector3 pos = transform.TransformDirection( new Vector3( 1,0,0));
transform.localPosition = StartlocalPos + pos*f;
}
private void UpdateCloseDoor(float f){
Vector3 pos = transform.TransformDirection( new Vector3( -f,0,0)) ;
transform.localPosition = endlocalPos-pos;
}
private void EndOpen(){
endlocalPos = transform.localPosition ;
StartCoroutine( WaitToClose());
}
private IEnumerator WaitToClose(){
yield return new WaitForSeconds(waitTime);
OTween.ValueTo( gameObject,ease,0.0f,translateValue,easeTime,0.0f,"StartClose","UpdateCloseDoor","EndClose");
GetComponent<AudioSource>().Play();
}
}
When I added the Rigidbody it was to the parent Wall_Door_Long_01 also added to it a Box Collider.
Then when running the game the door/s opened automatic without anything to trigger it like a npc enemy character.
The doors are working fine and when I'm moving my FPSController through the doors they open and close fine. My problem is when a npc/character that move automatic when the game start through the doors I could not find to make the character walking fine with a Rigidbody so I decided to add a Rigidbody to the doors. But now the doors open automatic when running the game.
This script I'm using to check if the doors are locked or unlocked using the public static doorLockState variable:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DoorsLockManager : MonoBehaviour
{
public bool locked;
public bool lockStateRealTime = false;
public Renderer rend;
private Shader unlitcolor;
private GameObject[] doorPlanes;
private void Start()
{
doorPlanes = GameObject.FindGameObjectsWithTag("DoorPlane");
ChangeColors(new Color32(255, 0, 0, 255), new Color32(0, 255, 0, 255));
}
private void ChangeMaterialSettings()
{
unlitcolor = Shader.Find("Unlit/Color");
rend.material.shader = unlitcolor;
rend.material.SetFloat("_Metallic", 1);
}
private void ChangeColors(Color32 lockedColor, Color32 unlockedColor)
{
for (int i = 0; i < doorPlanes.Length; i++)
{
rend = doorPlanes[i].GetComponent<Renderer>();
ChangeMaterialSettings();
if (locked)
{
HoriDoorManager.doorLockState = true;
rend.material.color = lockedColor;
}
else
{
HoriDoorManager.doorLockState = false;
rend.material.color = unlockedColor;
}
}
}
// Update is called once per frame
void Update()
{
if (lockStateRealTime)
{
ChangeColors(new Color32(255, 0, 0, 255), new Color32(0, 255, 0, 255));
lockStateRealTime = false;
}
}
}
I think your problem is in your collision detection for the door. A rigidbody on the door itself should have no effect.
First: Your OnTriggerEnterfunction does not have the correct pattern to work since it is missing the Collider collidername parameter.
private void OnTriggerEnter(Collider other)
{
}
You can call you collider whatever you want (IntelliSense defaults to other) but your method has to have a parameter like this to be recognized as a OnTriggerEnterfunction by Unity.
Second: You never check if the object triggering your collider is actually the object you want to open the door.
Try tagging your player and NPCs with some kind of tag like Playeror something like that.
Then you check if the colliding object has this tag attatched to it and only then you open the door.
Something like this:
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
//do stuff
}
if(other.CompareTag("NPC"))
{
//do other stuff
}
}
Or if there is only one action for every tag:
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player") || other.CompareTag("NPC"))
{
//do stuff
}
}
Note that for OnTriggerEnterto detect a collision one or more objects colliding need a RigidBodycomponent attached to them, so you are not entirely wrong with that.
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).