I'm making a 2D sidescrolling game in Unity, and when the player shoots an obstacle, I want the obstacle animation to play and then destroy itself. I got it to destroy itself, but the animation won't play. Any suggestions?
protected Animation obsanim;
// Use this for initialization
void Start () {
obsanim = GetComponent<Animation> ();
}
// Update is called once per frame
void Update () {
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "circle")
{
obsanim.Play ("circobs");
Destroy (gameObject, 1.0f);
}
}
}
Thank you for any help!
Sounds good to me, assuming of course that the animation doesn't last more than 1 second. You could use animation["circobs"].length to figure out when you need to destroy.
Maybe the animation you're playing is in a lower layer than the current one?
Related
I've got a problem. I am creating a small game project where where a ball escapes from ghosts.
I am trying to write a script that plays "evil laughter" when the ball collides with a ghost.
When i added the audio upon collision code into the script, the other function which gets the player to the "Game over"-scene stops working
Does anyone know what the problem might be?
Thanks a lot in advance! (code below) <3
public class GhostScript : MonoBehaviour
public AudioSource ghostCollision; //this is the collision sound reference
public GameObject target; //this is the player or a reference for him
UnityEngine.AI.NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
ghostCollision = GetComponent<AudioSource>();
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
if (target == null) {
target = GameObject.FindGameObjectWithTag("Player");
}
}
// Update is called once per frame
void Update()
{
agent.destination = target.transform.position;
}
public void OnCollisionEnter(Collision collision){
if (collision.gameObject.tag == "Player"){
ghostCollision.Play();
SceneManager.LoadScene("menu");
}
}
That's because as soon as you call SceneManager.LoadScene the current scene (which contains your Player, AI and AudioSource) gets lost and replaced with the new Scene. Adding a delay to the scene load should do the trick, you can use Invoke for that (or Coroutines if you're more advanced).
private void OnCollisionEnter(Collision other)
{
if (other.gameObject.tag == "Player")
{
ghostCollision.Play();
// Invokes the function after the AudioClip is over
Invoke("LoadScene", ghostCollision.clip.length);
}
}
private void LoadScene()
{
SceneManager.LoadScene("your-scene-name");
}
I'm creating shooting in Unity, I've set up everything but the problem is that I want the animation to play only on single click but in my script it plays animation infinitely while holding the button. Check the script below. Thanks.
public GameObject bulletPrefab;
public Transform firePoint;
private Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
anim.SetBool("isShooting", true);
}
if (Input.GetKeyUp(KeyCode.Space))
{
anim.SetBool("isShooting", false);
}
}
Set 2 States with just Keys on time = 0 the end position Shooting and the end position idle. From idle to shooting with a trigger parameter. From shooting to idle just a time transition. Ps shooting can be done with multiple frames too. Hope it helps.
I have recently started to learn how to code and I am really enjoying it, I am little stuck and I'd like to have your help. I have added:
A plane
Character Controller (Named 'Matt' in Hierarchy)
A Cube (Which should change color to Red on keypress and also if
Character Controller collides with the collider on cube) + The script
is attached to the cube
I would like the CUBE to change it's color if R key is pressed (which works) or if the player controller collides with the cube's collider.
Screenshot of my scene below
using UnityEngine;
using System.Collections;
public class colorChange : MonoBehaviour
{
public GameObject cube;
private Renderer rend;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
// This will get the OBJECT to CHANGE COLOR on KEY PRESS
if (Input.GetKeyDown (KeyCode.R))
GetComponent<Renderer> ().material.color = Color.red;
print ("A Key Pressed For Red Color");
}
void OnCollisionEnter (Collision col)
{
if (col.collider.name == "Matt")
{
rend.material.color = Color.yellow;
}
}
}
Here is a screenshot of the properties on the the two objects:
The complication in your collision detection is that you're using a Character Controller, which doesn't exactly work within Unity's physics simulation. As a result OnCollisionEnter() will never be called during a collision between a Character Controller and a normal collider.
It sounds like what you need is the OnControllerColliderHit() method. As per the documentation:
OnControllerColliderHit is called when the controller hits a collider while performing a Move.
However, note that it's the Character Controller that receives the event, and not the object it bumped into. So if you do revise your code to use this, you'll need to put the event on the GameObject with the controller, and detect/change the cube's renderer colour from there:
void OnControllerColliderHit(ControllerColliderHit col) {
if (col.collider.name == "cube")
{
col.gameObject.GetComponent<Renderer>().material.color = Color.yellow;
}
}
Note: Because of all the physics-related headaches associated with using Unity's Character Controller, you may actually want to create your own version of it using a Rigidbody and a capsule collider. It will take a bit more scripting, but the solution Unity offers really doesn't work well with other parts of the engine.
Hope this helps! Let me know if you have any questions.
First if you are going to detect collision then your collider on cube shouldn't be trigger. If you are going to use it as a trigger then you should use OnTriggerEnter method. Anyway attach to the character controller another collider like sphere collider make sure it's not trigger and you are good. Use GetComponent() something like this:
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Player")
{
GetComponent<Renderer>().material.color = Color.yellow;
}
}
You need to use OnTriggerEnter instead of OnCollisionEnter
Cause your cube not really solid (cause you enabled trigger boolean in the box collider)
void OnTriggerEnter(Collider other)
{
if(other.name=="Cube")
{
transform.parent.GetComponent<Renderer>().material.color = Color.red;
}
}
also try to use Debug.Log in a lot of places to make sure you are executing or not.
That might do it.
UPDATE:
About the rend variable, since you have it private you need to assign it before executing the color changing, you'll get a NullReferenceException cause it's not assigned (the rend var)
Either make it public and assign in the inspector or do it in the Start():
rend = GetComponent<Renderer>();
Okay guys, I have managed to make it work. Below is my final code:
using UnityEngine;
using System.Collections;
public class colorChange : MonoBehaviour {
public Material color002;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// This will get the OBJECT to CHANGE COLOR on KEY PRESS
if (Input.GetKeyDown (KeyCode.R)) {
GetComponent<Renderer> ().material.color = Color.red;
Debug.Log ("R Key Press For RED");
// This will get the OBJECT to CHANGE MATERIAL on KEY PRESS
} else if (Input.GetKeyDown (KeyCode.P)) {
GetComponent<Renderer> ().material = color002;
Debug.Log ("P Key Press For Pink Material (color002)");
}
}
// This will get the OBJECT to CHANGE COLOR if the FPS Controller collides with Cube GameObject
void OnTriggerEnter(Collider other)
{
print (other.name);
if(other.name=="FPSController")
{
GetComponent<Renderer>().material.color = Color.green;
Debug.Log ("FPS Collided with CUBE");
}
}
}
Thanks a lot for your help! Time to keep on coding :D
I'm newbie programming Game with Unity Engine. I have searched "How to load animation from assets in unity " But haven't find solution.
I'm handle Trigger of collider
void OnTriggerCollisionEnter2D(Collision2D coll){
if(coll.gameObject.tag = "Player"){
//try to load animation
}
}
Help me if you know ! Thanks
First of all, I think you will have hard time making my solution work because it looks like you lack Unity basic stuff.
OnTriggerCollisionEnter2D is not a valid callback function to detect Trigger.
OnTriggerEnter2D(Collider2D coll) is what you are looking for.
Secondly, don't anything during onTrigger. Load the animation in the Start() function then play it in the OnTriggerEnter2D function.
Also if(coll.gameObject.tag = "Player") should be if(coll.gameObject.tag == "Player"). Notice the double '='. You compare with double '=' not one. but not efficient. If possible, use coll.gameObject.CompareTag instead of coll.gameObject.tag ==.
Put the Animation in the Assets/Resources/Animation folder
Animation animation;
AnimationClip animanClip;
string animName = "walk";
// Use this for initialization
void Start()
{
//Load Animation
loadAnimation();
}
void loadAnimation()
{
GameObject tempObj = Resources.Load("Animations/" + animName, typeof(GameObject)) as GameObject;
if (!tempObj == null)
{
Debug.LogError("Animation NOT found");
}
else
{
animation = tempObj.GetComponent<Animation>();
animanClip = animation.clip;
animation.AddClip(animanClip, animName);
}
}
public void OnTriggerEnter2D(Collider2D coll)
{
if (coll.gameObject.CompareTag("Player"))
{
animation.Play(animName);
}
}
Finally, study these tutorials.
Unity Scripting Tutorial
Unity Physics Tutorial
Other Unity Tutorials
What I'm after in my game is when a collision happens with the player and a planet, for the player to disappear, leaving behind an explosion effect in the form of a particle system. Just afterwards (maybe half a second) I want the "game over" scene to appear in its place. Here's what I have so far:
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "enemyPlanet") {
Instantiate (explosion, thingToMove.transform.position, thingToMove.transform.rotation);
ui.gameOverActivated ();
Destroy (gameObject);
am.rocketBang.Play();
Application.LoadLevel ("gameOverScene2");
}
}
The problem I have is that the particles appear but don't move as they should like an explosion. I guess that's either because the game over scene is loading or because its position is the player (thingToMove) which is being destroyed.
I tried this:
public void Awake() {
DontDestroyOnLoad (transform.gameObject);
}
But the same thing happens. If it's because the player is being destroyed, how would I make it be in the place of the player at the time of it being destroyed?
I hope this makes sense and thanks in advance.
You can use the Invoke method to call the game over after a specified delay.
void OnCollisionEnter2D (Collision2D col) {
if (col.gameObject.tag == "enemyPlanet") {
Instantiate (explosion, thingToMove.transform.position, thingToMove.transform.rotation);
ui.gameOverActivated ();
am.rocketBang.Play();
Invoke( "over", 2.0f );
}
}
void over(){
Destroy (gameObject);
Application.LoadLevel ("gameOverScene2");
}