Play an animation only in one prefab

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Card : MonoBehaviour {

    public Animator animatorCard;
    private bool Click = false;

    void Start()
    {
        animatorCard = this.gameObject.GetComponent<Animator>();
    }


    void Update () {
        CheckObjects();
    }

    public void CheckObjects()
    {
       
        RaycastHit hitInfo = new RaycastHit();
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast (ray, out hitInfo) && Input.GetMouseButtonDown(0)){
          
           animatorCard.SetBool("Click", true);

              
        }

    }
}

First, sorry for my english.
I am making a game board. The board is instance when you start the game. The cards are only one prefab, but each one are different from other because I assigned a texture when the board is generated. When you click on one of those cards, it has to make an animation to flip. But, when I click one, all the cards flip at the same time. I am using a raycast.

What can I do?

I don’t know if i have explained very well. Thanks!

Show us your code for how you play the animation?

Because if you raycast, and get a reference to a single card, and grab the script off that single object that handles animation, it should only animate that one card.

But without your code, I don’t know how you have it set up, and thusly don’t know why all are playing at the same time.

This is my code

2902413–213709–Card.cs (776 Bytes)

First, you can just put that here in the thread without requiring me to dl a file:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Card : MonoBehaviour {

    public Animator animatorCard;
    private bool Click = false;

    void Start()
    {
        animatorCard = this.gameObject.GetComponent<Animator>();
    }


    void Update () {
        CheckObjects();
    }

    public void CheckObjects()
    {
       
        RaycastHit hitInfo = new RaycastHit();
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast (ray, out hitInfo) && Input.GetMouseButtonDown(0)){
           
           animatorCard.SetBool("Click", true);
            // Click = true;
           // animatorCard.Play("Card_Flip");

               
        }

    }
}

Next…

I’m assuming this script gets attached to every card? Well, attached to the prefab from which the cards are created, meaning they’re on every card…

This means EVERY card is running this same code every frame.

And since your test only sees if the Raycast hit something AND that the mouse is down… every card reacts. It’s always true for every card.

Lets slightly rewrite this to reflect your needs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Card : MonoBehaviour {

    public Animator animatorCard;
    private Collider _collider;

    void Start()
    {
        animatorCard = this.GetComponent<Animator>();
        _collider = this.GetComponent<Collider>();
    }


    void Update () {
        CheckObjects();
    }

    public void CheckObjects()
    {
        if(Input.GetMouseButtonDown(0))
        {
            //we should only do the physics test if the mouse is down...
            //why do an expensive raycast if it doesn't matter?
           
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if(Physics.Raycast(ray, out hit) && hit.collider == _collider)
            {
                //only if it hit, and what it hit was THIS
                animatorCard.SetBool("Click", true);
            }
        }
    }
}

BUT, even this is a bit ridiculous… why should every card be testing this on every Update??? That’s a lot of raycasts!

Why not have another script completely, which only one exists of, and that handles it:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Card : MonoBehaviour {

    public Animator animatorCard;

    void Start()
    {
        animatorCard = this.GetComponent<Animator>();
    }

    public void PlayFlip()
    {
        animatorCard.SetBool("Click", true);
    }
}

///this should be attached to a GameObject in the scene somewhere
public class InputController : MonoBehaviour
{
   
    void Update()
    {
        if(Input.GetMouseButtonDown(0))
        {
            //we should only do the physics test if the mouse is down...
            //why do an expensive raycast if it doesn't matter?
           
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if(Physics.Raycast(ray, out hit))
            {
                var card = hit.collider.GetComponent<Card>();
                if(card != null)
                {
                    //we hit a card!
                    card.PlayFlip();
                }
            }
        }
    }
   
}
1 Like

It works! Thank you very much Lordofduct! You save my life. You are awesome.

I am sorry if I didn’t create this thread very well. It is the first time I publish something at the Forum. I will try to do better the next time.

Thank you very much again!