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 .
Related
I'm new to Unity and C#. I'm trying to make the sprite of "bird" change when he dies in unity. I tried following some tutorials but it doesn't work, so now I'm just trying to make the sprite change when "A" is pressed, but it still doesn't work. Is it a problem of the script or of the sprite?
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeSprite : MonoBehaviour
{
public Sprite deadBird;
void Start()
{
}
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
GetComponent<SpriteRenderer>().sprite = deadBird;
}
}
}
Here is a screenshot: https://i.stack.imgur.com/PTd9W.png
I think #derHugo is correct, if you have an Animator then that will most likely overwrite any change you try and do. To fix this, you can use that animator and create an animation that is the deadBird. once you have that, connect it to the animator controller from the normal state. in that connection you can create and set a new animator boolean like "isDead" and set it to switch to the dead animation is the bool is true. then change your code from
GetComponent<SpriteRenderer>().sprite = deadBird;
To
anim = gameObject.GetComponent<Animator>() //place this instead of the bird sprite
anim.SetBool("isDead", true); //place this in the if statement
Hope that helps! it's much cleaner to go through the animator as it allows for easier changes as you build your game.
I am trying to write a code in Unity2D that displays a different gameobject after each set amount of time. I am a complete beginner and just started today. This is my code
using System.Collections.Generic;
using UnityEngine;
public class DestroyEnemy : MonoBehaviour
{
public GameObject anim;
public GameObject anim2;
// Start is called before the first frame update
void Start()
{
StartCoroutine(Run());
}
// Update is called once per frame
void Update()
{
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "FriendlyBullet")
{
IEnumerator run()
{
Destroy(gameObject);
Instantiate(anim, transform.position, transform.rotation);
yield return new WaitForSeconds(2);
Instantiate(anim2, transform.position, transform.rotation);
}
}
}
}
The error message says "The local function "run" is declared but never used." What is wrong here?
First of all, I'd like to point out, that you're calling your coroutine only at the start. As a result, it won't ever run again while the game is already running.
I'm assuming the game is a kind of shooter and you want to run the coroutine function when the bullet hits the enemy. So first check if that's what you really want and otherwise I'd move the StartCoroutine to OnCollisionEnter2D.
Secondly, as UnholySheep pointed out, you've missed a capital letter. You're calling run but you have only declared Run. Yes, that's a difference, C# is case sensitive. Functions in C# are supposed to start with a capital letter :).
That's why the IDE or whatever editor is telling you that you declared a function, but you never used it. Local function means that it's declared inside of another function and won't be accessible anywhere else.
It's hard to fix a piece of code from the top of the head as I'm not all that experienced in Unity, only a couple of months so far, but I've fixed those said issues and it should help :).
using System.Collections;
using UnityEngine;
public class DestroyEnemy : MonoBehaviour
{
public GameObject anim;
public GameObject anim2;
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("FriendlyBullet"))
{
StartCoroutine(Run());
}
}
IEnumerator Run()
{
Destroy(gameObject);
Instantiate(anim, transform.position, transform.rotation);
yield return new WaitForSeconds(2);
Instantiate(anim2, transform.position, transform.rotation);
}
}
PS. I've switched your tag logic for CompareTag as it seems to be a better option for doing the same thing :).
Good luck with your game!
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'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.
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.