1
votes

I have a prefab that is instantiated when the user buys the item from my In-game store, how ever many is instantiated, the all of prefab has a start position of a certain position. The prefab can be dragged around the scene using this TouchScript package I found online! My issue: I want to play the prefab's animation every time the user is dragging the prefab around the screen, I attempted this by creating a RaycastHit2D function that would allow me to detect if the user has clicked on the prefab's collider, script below:

    if (Input.GetMouseButtonDown (0)) {
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint (Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast (worldPoint, Vector2.zero);
        if (hit.collider != null) {
            if (this.gameObject.name == "Item5 (1)(Clone)" +item5Increase.i) {
                monkeyAnim.SetBool ("draging", true);
                Debug.Log (hit.collider.name);
            }
        } else {
            monkeyAnim.SetBool ("draging", false);
        }
    }

However if I were to buy more than one prefab, all instantiated prefabs will play it's animation when I start to drag only one of the instantiated prefabs, hope I'm making sense. Can some one help me? Thank you!

1

1 Answers

2
votes

I faced a similar issue with platforms in my 2D game. The solution I would suggest is to create a GameObject that acts as the current item you wish to animate, and a LayerMask that acts as a filter for which objects your raycast can hit. You can use this LayerMask in conjunction with the Physics2D.Raycast API, which has an overload method that takes a LayerMask as a parameter.

Start by creating a new layer, which can be done by going to the top right of an object in your scene and accessing the "Layer" box. Once you've created a new layer (I called mine "item"), make sure your prefab's layer is assigned correctly.

Then, create an empty object in your scene, and attach this script to it. On that object you will see a dropdown menu that asks which layers your raycast should hit. Assign it the "item" layer; this ensures that your raycast can only hit objects in that layer, so clicking on anything else in your game will produce no effect.

using UnityEngine;

public class ItemAnimation : MonoBehaviour
{
    private GameObject itemToAnimate;
    private Animator itemAnim;

    [SerializeField]
    private LayerMask itemMask;

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            CheckItemAnimations();
        }

        else if (Input.GetMouseButtonUp(0) && itemToAnimate != null) //reset the GameObject once the user is no longer holding down the mouse
        {
            itemAnim.SetBool("draging", false);
            itemToAnimate = null;
        }
    }

    private void CheckItemAnimations()
    {
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero, 1, itemMask);

        if (hit) //if the raycast hit an object in the "item" layer
        {
            itemToAnimate = hit.collider.gameObject;

            itemAnim = itemToAnimate.GetComponent<Animator>();
            itemAnim.SetBool("draging", true);

            Debug.Log(itemToAnimate.name);
        }

        else //the raycast didn't make contact with an item
        {
            return;
        }
    }
}