I'm pretty new to unity and I've been trying to get this scene switch to work however the trigger doesn't seem to be activating when the player hits it. The debug.Log is doing nothing so I'm stumped. I know my terminology may make no sense so let me show some pictures. If youre able to help it would be extremely helpful. Thank you!
This is the inspector panel for the object I want to trigger
This is the inspector the player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneChangeScript : MonoBehaviour
{
public int iLevelToLoad;
public string sLevelToLoad;
public bool useIntegerToLoadLevel = false;
void start()
{
}
void update()
{
}
private void onTriggerEnter2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
Debug.Log("Somethings Being Triggered!");
LoadScene();
}
}
void LoadScene()
{
if(useIntegerToLoadLevel)
{
SceneManager.LoadScene(iLevelToLoad);
}
else
{
SceneManager.LoadScene(sLevelToLoad);
}
}
}
Unity Monobehavior Lifecycle methods start with a capital and C# methods are case-sensitive. Therefore, the following methods need to be corrected to be used by Unity:
start => Start
update => Update
onTriggerEnter2D => OnTriggerEnter2D
Since the C# convention is that methods start with uppercase you'll less likely encounter this issue if you assume it starts with an uppercase letter rather than lower case. But it is better to confirm! Also if you are using Visual Studio, you can avoid much of these pains by investing the time to learn some shortcuts.
Hey I just spotted that you initiated the bool useIntegerToLoadLevel to be false and you are using this condition to load the scene in the if statement and the bool is never being set to true.
Try setting this bool to true when you enter the trigger, that is in the OnTriggerEnter2D method, should definitely work. It is a minor bug that anyone can make.
Related
Im working on a game similar to archvale and enter the dungeon and I'm trying to create a dash function. Ive tried using force and some other methods I've searched for online but I haven't been able to find anything. Any ideas?
This game is a similar perspective to ETG being a 3D game using 2D sprites in a top down format.
Thanks!
EDIT: This is code I tried using but it didn't work at all. It is code I found online.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Dash : MonoBehaviour
{
public class PlayerMovement : MonoBehaviour
{
public float dash = 3000f;
public bool DashTime = true;
// Use this for initialization
void Start()
{
bool DashTime = true;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("f"))
{
GetComponent<Rigidbody>().AddForce(new Vector2(dash, 0), ForceMode.Force);
StartCoroutine(LateCall());
}
}
IEnumerator LateCall()
{
yield return new WaitForSeconds(0.05f);
GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePositionX;
yield return new WaitForSeconds(0.06f);
GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
}
}
}
Without any code or anything to look at its kind of hard to answer the question. You could do a transform.translate or you could teleport based on where the player is looking or the mouse location. There are a ton of ways you could create a dash effect but without anything to go on it's really up in the air as to what solution you come up with.
You can check out this tutorial and it might help you:
https://generalistprogrammer.com/unity/unity-2d-dash-movement-effect-learn-to-how-to-tutorial/
I guess this is a really easy problem, but I just started Programming. I tried to Set the Player as a Child of a Platform while they touch, so he is moving with it. And if there is only one such Platform in the Game it works, but otherwise, the Player can only stick on the Platform I placed last. On the otherones, both bools isOnBlock and findPlayer are set true (I tested this), but the first If-Statement still doesn`t work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HaftungAnBlock : MonoBehaviour
{
public bool isOnBlock;
private GameObject myPlayer;
bool findPlayer;
public void FindPlayer()
{
myPlayer = GameObject.FindGameObjectWithTag("Player");
findPlayer = true;
}
void Update()
{
if (isOnBlock && findPlayer)
{
myPlayer.transform.SetParent(this.transform);
}
else if (!isOnBlock && findPlayer)
{
myPlayer.transform.SetParent(null);
}
}
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Player"))
{
isOnBlock = true;
}
}
private void OnCollisionExit(Collision other)
{
if (other.gameObject.CompareTag("Player"))
{
isOnBlock = false;
}
}
}
As soon as you have multiple platforms, at least one will always set the parent transform to null(since you can at most have one platform below the player, i assume), meaning that even if you stand on a platform it's a race condition for which platform updates first in the loop, as platform #2 and platform #3 will try to set the parent to null.
A fix to this would be anchoring the player to the platform within the trigger methods, rather than within the update method, so that each platform only cares about what happens when the player enters/exits that specific platform, and not what happens in the rest of the game world.
I don't know your exact setup though, so my approach might not be the correct way to handle it for your scenario, but just throwing it out there.
Well, I'm trying to make an fps where you shoot tagets and appears an "Arcade-Style" score over them on unity 5, but, I don´t really know how to do it, already tried with an OnCollisionEnter(), but I did something wrong and it didn't worked, What can I do? Below you can see my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Diana : MonoBehaviour {
public GameObject diana;
public AnimationClip Score;
private Animation myAnimation;
/* IEnumerator Wait()
{
myAnimation = GetComponent<Animation>();
myAnimation.Play("DianaScore");
yield return new WaitForSeconds(3);
} */
void OnTriggerEnter(Collider other)
{
Debug.Log("Funcó wacho");
myAnimation = GetComponent<Animation>();
myAnimation.Play("DianaScore");
// StartCoroutine(Wait());
}
void Update () {
}
}
(Sorry for my bad english, I´m argentinian and new in all this coding thing)
I suggest putting this line of code: myAnimation = GetComponent(); into a Awake() function. If the above method does not work, I suggest checking that the Is Trigger is checked for OnTriggerEnter. If the console message (Debug.Log) shows, the problem might be something to do to the animation not the script. Last but not least, check that the bullet actually collides. I know this might sound crazy, but sometimes the bullet might be able to "not get detected" if it has enough velocity. Hope these suggestions work :D .
I have a game mechanic where the player can toggle the car headlights with the L keypress and the backlights witht he S key, which also controls backwards movement.
This is shown in the code below.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class headLights : MonoBehaviour {
private Light frontLight;
private Light backLight;
// Use this for initialization
void Start () {
frontLight = GetComponent<Light>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
frontLight.enabled = !frontLight.enabled;
}
if (Input.GetKeyDown(KeyCode.S))
{
backLight = GetComponent<Light>();
backLight.enabled = !backLight.enabled;
}
}
}
The problem is when I press L or S, both the front and back lights turn on because which I assume, the GetComponent refers to all extra Light components in the Scene and generalizes them as one.
I want to get the S key to only turn on the "backLights" while it is pressed and the L key to only toggle the "frontLights".
METHODS I HAVE USED TO TRY FIX THE PROBLEM
frontLight = GameObject.Find("Player").GetComponent<Light>();
This code just gives me errors like "the gameobject player does not have any light components attached to it(although it clearly does) blah blah blah.
I have also tried using tags but they confuse me a lot and seem like the easy way out. I know in the future I will have to learn how to do object orientated syntax and coding so I would very much like to learn how to reference it!
Please help me if you can, it would make my day~~ :)
Please note, you do not have to solve the whole problem for me if you are short on time, just giving general syntax that I can just swap out would help me a great deal!
Its really easy to disambiguate the two lights. Just make the variables public and set them in the inspector. Be sure to null check them before you use them to make sure they are set.
I just realized that probably didn't make sense.
Lets say your hierarchy is set up like this with the light objects as children to the car:
car
+-FrontLight
+-RearLight
Instead of putting the custom behavior on the light gameobjects, you should put it on the car.
Then, the behavior would look like this:
public class headLights : MonoBehaviour {
public Light frontLight;
public Light backLight;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
if(frontLight != null) {
frontLight.enabled = !frontLight.enabled;
}
}
if (Input.GetKeyDown(KeyCode.S))
{
if(backLight != null) {
backLight.enabled = !backLight.enabled;
}
}
}
This is because the lights are not Components of the car, they are Children of it.
I am trying to make my player hit an object, destroying the object and triggering an animation, but everything I try causes an error. I am relatively new at c# so the answer may be obvious but I need help. How can I set it up so that the collision will cause the object to disappear and the player to play an animation? Here is the script I am currently trying.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class succ : MonoBehaviour
{
public float speed = .15f;
public static float jumpSpeed = 170f;
void Start()
{
GetComponent<ConstantForce2D>().enabled = false;
GameObject.Find("goal");
}
public bool animation_bool;
private object coll;
private object other;
void Update()
{
OnCollisionStay2D(Collision2D coll);
{
if (coll.gameObject.tag == "succ") ;
{
animation_bool = true;
GetComponent<Animator>().SetBool("succ", animation_bool);
GetComponent<ConstantForce2D>().enabled = true;
Destroy(other.object);
}
}
}
private void Destroy(object gameObject)
{
throw new NotImplementedException();
}
private void OnCollisionStay2D(Collision2D collision2D, object coll)
{
throw new NotImplementedException();
}
}
There are a few things I can see that are wrong, but I'll start by answering your question.
I suggest you change your MonoBehaviour method OnCollisionStay2D to OnCollisionEnter2D. OnCollisionStay2D is "sent each frame where a collider on another object is touching this object's collider". OnCollisionEnter2D is "sent when an incoming collider makes contact with this object's collider".
I believe you are looking for the latter since you only want to trigger this once during the collision. You are also destroying the other object, making it impossible to call OnCollisionStay2D anymore even if you wanted to do so.
You should also remove your Update method. I honestly do not understand what you are trying to achieve there now. All of the OnCollision methods get called automatically; you do not have to call them yourself.
Then you can use the Awake and OnCollisionEnter2D methods as follows
public class Succ : MonoBehaviour
{
private Animator animator;
private void Awake()
{
// You can already get a reference to the Animator on Awake
// This way you do not have to do it on every collision
animator = GetComponent<Animator>();
}
// Use OnCollisionEnter2D instead since the code
// needs to be excecuted only once during the collision
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("succ")
{
// Assuming that you only want to trigger an animation once
// to reflect attacking or colliding, you could use SetTrigger
// instead. Otherwise you need to use SetBool again to set it
// back to false. You should then change the Animator parameter
// accordingly, from a bool to a trigger.
animator.SetTrigger("succ");
Destroy(collision.gameObject);
}
}
}
Apart from this, I have a few things I would like to comment on:
I am not sure what you are trying to achieve by setting your ConstantForce2D component to false on Start and then setting it to true on collision.
You seem to be using GameObject.Find on Start. GameObject.Find is something that should be very rarely used. It can be extremely expensive, especially if your Scene has a lot of GameObjects in it; this is because it simply goes through the Hiearchy, comparing the parameter string to names of GameObjects until it either finds a match or runs out of GameObjects.
Moreover, you are using GameObject.Find on Start to look for a GameObject, but then you do not store that anywhere, making the whole finding process completely pointless.
Overall, I recommend you to take a look at all of the different learning resources offered by Unity themselves. Your question is about fairly basic functionality that is certainly covered during all of the different tutorials.