I created a project using the FPS Microgame in Unity Hub to learn scripting. I'm trying to play a simple particle effect when the player collides with it (in the future I'd love to be able to trigger it from farther away, maybe when crossing into a plane, but I'll learn that later). I created the following script and attached it as a component to the particle effect on the scene:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class portalTrigger : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
ParticleSystem ps = GetComponent<ParticleSystem>();
ps.Play();
}
}
And here's what the particle effect looks like in the Unity Inspector:
The particle effect plays when the game starts if I select Play on Wake so I disabled it because I want it to play when the user collides with it. Any ideas?
Thanks!
First I would add a debug print to verify that a collision is triggered in the onTriggerEnter method.
If that is not the case, I would check that both game objects have a rigid body and a collider. One (and only one) of the two colliders must have the isTrigger flag set.
Here is unity doc link for reference:
https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
Had you quite made sure that the isTrigger option in object main object has been checked true?
If not then either see the way to check it( What do I mean here is that if you only check isTrigger without making another collision than object won't stop even after the collision. It had been really hectic for me when I started.)
or use the OnCollisionEnter. If none of these happened then try printing to see if they're even colliding or not. C'mon you are trying to become a Unity scripter so best way is to debug anything you doubt about.
Related
I'm fairly new to Unity and I've decided to work on a simple 2d platformer from youtube tutorials.
Everything works fine until I start using collisions. My problem isn't only that it doesn't work, It's that it doesn't appear at all on auto-complete.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class finishLine : MonoBehaviour
{
void Start()
{
}
void Update()
{
}
private void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.CompareTag("Player")) {
SceneManager.LoadScene("level2");
}
}
}
I've also added rigid bodies and box colliders to both objects (player and finish line).
Anyone know what's wrong?
Make sure that you used BoxCollider2D and not the 3D one.
If the autocomplete doesn't work try restarting VisualStudio or whatever IDE you use. If that doesn't work look in the Unity Settings under External Tools and try regenerating project files. That works for me sometimes.
So a couple things you might want to look into to fix this are:
Check if you have the right colliders on both your gameobjects (in this exmaple box collider 2D I assume)
Check if either of your colliders has the "Is Trigger" box check or not. If yes then uncheck it
Make sure your player gameobject has the "Player" tag and the same as the tag you compare in your script because compare tag is case sentitive
Check if you have your finishLine script on the object you want as the root object meaning it's the parent of all the other one inside it and has no parent (this doesn't need to be the case all the time but in this scenario it might help fix the problem)
Did you check the trigger box in the colliders?
Does any one of those objects have a rigid body?
Did you have other functions that destroyed the character when it reaches the destination that is meant to be the trigger?
You can try to set up a two new cubes for testing purposes to narrow down the problem.
This is the current script that I have. I have a ball that is player, and I want a collision with my game object tagged as "pit" to end the game. When the game ends I want my game over canvas to pop up. The current script detects the hit when the player rolls over the pit, however, currently, nothing else happens. Both my player and pit have rigidbodies and colliders attached to them. I would really appreciate any help with how to get my code to work properly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Trigger : MonoBehaviour
{
public GameObject GameManager;
private void OnTriggerEnter(Collider other)
{
Debug.Log("hit detected")
if(other.gameObject.tag == "pit")
{
GameManager.GetComponent<Game_Manager>().EndGame();
}
}
}
My EndGame code is in my GameManager script. The is the part of that script that deals with ending the game.
public void EndGame ()
{
player.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePosition;
hasGameStarted = true;
inMenuUI.gameObject.SetActive(false);
inGameUI.gameObject.SetActive(false);
gameOverUI.gameObject.SetActive(true);
}
If I'm correct in interpreting your question, your script successfully detects player death already. If you want a game over screen you have a couple of options:
You can create a UI canvas with a panel on it that obscures the whole screen and put the words Game Over.
Or, probably the better option is to create an entirely new Unity scene and make the Game Over canvas there. When you want to trigger the game over screen you simply use:
Scene manager.LoadScene("Scene name");
You have to add "using UnityEngine.SceneManagement;" at the top of your script. Also note you have to add your Game Over scene to the list of scenes in you game. I believe this can be done by navigating to File>Build settings>scenes and then pressing add open scenes assuming the game over scene is open.
So I have a little game with a gameobject called "bomb". I've coded a script that makes it so whenever you tap or click on the screen, the bomb gameobject gets cloned (using instantiate). Well, on my bomb gameobject I have attached a new script component with
FindObjectOfType().Play("name");
inside. My bomb is supposed to make a boom sound when colliding with something, so a trigger and that line of code above do that exact thing.
And here comes the problem: When I throw multiple bombs (because my game includes throwing as well) the boom sound plays flawlessly, until another bomb explodes and the boom sound goes all the way to the start and plays again.
The thing is I don't want the same sound to stop, go to the start, and then play again, I want multiple sounds that play independently of eachother, so when another bomb explodes, the currently exploding bomb's sound doesn't play again, it should continue playing and another sound to be created for the other bomb explosion.
I've lost so many neurons today trying to figure out how to do this, but I can't find any clue, so I am asking you for your help now! 😉
Here you have a link to a video in which you can hear how bad the explosions sound https://youtu.be/JdIrcgfkVHI
Thanks in advance!!
From what I can tell you are over complicating it when there isn't a need too, Just attach an AudioSource with the bomb clip to the bomb prefab with it set to PlayOnWake.
As for why you're having this issue I think it maybe due to how an AudioSource can only be making one sound at a time so cannot do explosion sounds for 2 bombs at the same time.
EDIT Update after comment
You can change if from PlayOnWake to be triggered when hit by the Player using its tag like in this example.
public class BombDemo : MonoBehaviour
{
private AudioSource _soundEffect;
private void Awake()
{
_soundEffect = GetComponent<AudioSource>();
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
_soundEffect.Play();
}
}
}
This script when attached to a GameObject with an Audiosource will play it when it is triggered by the Player Object colliding with it.
Keeping this logic on the bomb it self is a lot easier to maintain aswell rather than trying to do it all from the Player side, also if you do need to access the PlayerController (or whatever you called it) you can then do so while playing the sound effect using..
PlayerController playerController = other.gameObject.GetComponent<PlayerController>()
..for example
I'm trying to create a script in Unity wherein the gravity will go to zero when the game starts. The problem is, the gravity was still there after I launched the game.
This is for a Unity3D game. I've already tried to change the variable name, add using System; and moved my script to the top of the Rigidbody component, but none of these things worked.
public class PlayerGrav : MonoBehaviour
{
public Rigidbody rb;
void Start()
{
rb.useGravity = false;
}
void Update()
{
}
}
I expected the gravity to be removed when the game launches, but in the actual output the gravity still remained, and the cube still fell downwards.
create a new scene
create a new cube
add rb = this.GetComponent<Rigidbody>() to your start function in your PlayerGrav script
attach your PlayerGrav script to the new cube
Hit play, and take look at the "use gravity" property from your new cube's inspector window (make sure the inspector isn't locked to other game object)
If the above tryout succeeds, then you need to check the other code/objects in your original scene. If there are massive other objects in your original scene, then I will suggest disable other objects first, and re-enable them back group by group to see which object/monobhevaiour is causing the issue.
I know this is an old question but I looked forever trying to find an answer to this. I am new to unity so it took me a long time to figure this out but I am using a Rigidbody 2d so this is what worked for me
gameObject.GetComponent<Rigidbody2D>().gravityScale = 0;
I'm new to unity and I'm currently working on a portal-like game.
I did the whole teleportation script and it works, but the problem comes that I didn't implement the player camera correction and actually I don't have any ideas how to do it. The concept is that when you're jumping through a portal, the player (or player camera) rotation should be changed to the portal/portal camera rotation from you've come so the final effect is more 'realistic'.
I've tried some lines in teleportation script like player.transform.rotation = portal.transform.rotation but in the end it didn't work and now I end up with nothing, deleting previous scripts and trying to write it all over and over again.
I'll be glad if someone could guide me how to start coding it. Should I do it in onTriggerEnter (when you're jump through portal), or in onTriggerExit? Should the script be attached to a player or to a portals? Should I gather rotation only from camera or from the whole gameobject (portal/player)? I'm posting also couple of screens (with a video how it currently works, and also an entire teleportation script. If I missed something just ask me and I'll post it here.
https://imgur.com/a/pbqYnLD - screens with portals inspector
https://streamable.com/b14hk - video how it works
teleportation script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Teleportation : MonoBehaviour {
[SerializeField] private GameObject otherPortal;
[SerializeField] private GameObject player;
void OnTriggerEnter(Collider col) {
if(col.tag == "Player") {
col.transform.position = new Vector3(otherPortal.transform.position.x+1, otherPortal.transform.position.y+1, otherPortal.transform.position.z+1);
Debug.Log("wszedłem w portal");
}
}
void Update() {
}
}
some informations how it is coded right now:
portals are currently in game behind 'the box', i didnt instantiate them anywhere; just changing position on lpm (blue portal) and ppm (orange portal)
portals are sticking to the walls, just like in the original game
portals have a camera attached to it and right now the cameras are static. (offtop: i have a script to move them exactly when player is moving and it quite works but also have some problems, like camera can get too far away from portal and start rendering only that green outer side of the box, and i also dont know how to fix it, so currently i didnt use this script)
the player movement im using is that from unity standard assets (if it somehow matters)
the player have a rigidbody but the portals dont; not sure if i should attach this component to them
teleportation script is attached to the both of portals - the 'otherPortal' variable is moved from inspector, like in orange portal the 'otherPortal' variable is blue portal and the other way
What you did is correct (setting the player rotation to the portal.
You can do it in onTriggerEnter after setting the position, then it should look like
player.transform.rotation = otherPortal.transform.rotation
If you do that, the player will have the same rotation. You already have something that make the camera follow the player, so it is likely that you don't need to set the camera rotation. I don't know how you did your camera follow, so I can't be sure, though. If the camera has not the proper orientation, doing Camera.main.transform.rotation = otherPortal.transform.rotation will do it.
The remaining thing that might be wring, could be that your player (and camera) is not facing the right axis. On your video, I can see that the portal faces the x-axis (the red axis in Unity editor). Check that when going forward, your player has the red axis looking forward.
It is likely that your player has the z-axis (blue) facing forward, which is (by convention) more correct and fits the names Unity uses (z-axis is also called forward-axis)
I would recomand to create the portal object (and all other objects, including the player) so that the forward-axis is the blue one. It might require editing the objects. Anycase, check that the player forward axis is that same as the portal, otherwise setting the rotation won't work