2
\$\begingroup\$

I have an object in my game that, when clicked, causes the player to move toward it. It does this by sending its position to the player's SetTarget function. The player's Move function then heads toward the position.

This is working, but when I duplicate the object and click on it, the player still moves toward the original object's position. When I print debugging statements to the console, it appears that both positions are being calculated, but the original position is the last one and wins out. (I'm using the object's this.transform.position to send the position to the player's SetTarget function.)

Can I not duplicate objects like this and expect the script to work? Do I need to use a prefab? If so, how? I know how to create prefabs but am not sure what I would need to change with the script or other settings when they are created. Thanks.

Here's the code:

public class PotController : MonoBehaviour {

private GameObject chefObject;

void Start () {
    chefObject = GameObject.Find ("Chef");
}

void Update() {
    if(Input.GetMouseButtonDown(0)){
        //print ("pot clicked!");
        ChefController chefScript = chefObject.GetComponent<ChefController> ();

        print (this.gameObject.transform.position);
        chefScript.SetTheTarget (this.gameObject.transform.position);
    }
}
}

public class ChefController : MonoBehaviour {

private Vector3 target;
public float speed = 2;

// Use this for initialization
void Start () {
    target = this.transform.position;
}

private void MoveTowardsTarget() {
    Vector3 targetPosition = new Vector3(0,0,0);
    targetPosition = target;
    Vector3 currentPosition = this.transform.position;
    //check distance to target
    if(Vector3.Distance(currentPosition, targetPosition) > 0.4f) { 
        Vector3 directionOfTravel = targetPosition - currentPosition;

        directionOfTravel.Normalize();

        this.transform.Translate(
            (directionOfTravel.x * speed * Time.deltaTime),
            (directionOfTravel.y * speed * Time.deltaTime),
            (directionOfTravel.z * speed * Time.deltaTime),
            Space.World);
    }
}

void Update () {
    MoveTowardsTarget ();           
}

public void SetTheTarget (Vector3 position){
    target = position;
}

}
\$\endgroup\$
  • 1
    \$\begingroup\$ Showing your object's script would be very helpful here. Remember, we don't have access to your project except for what you tell us. \$\endgroup\$ – DMGregory Jun 30 '15 at 16:22
  • 1
    \$\begingroup\$ Need to see your code. More than likely, you are just doing something incorrectly in your calculations. \$\endgroup\$ – jgallant Jun 30 '15 at 16:24
  • \$\begingroup\$ Okay, updated my question to include the code. \$\endgroup\$ – johnnyb1970 Jun 30 '15 at 22:26
2
\$\begingroup\$

EDIT

Okay, so the problem is that you need to identify which pot was clicked. With your current code, whenever the mouse is clicked, it fires off code in every PotController.

What you should do, is add a collider to your Pot, which would allow you to perform a collision check on the mouse to see which Pot was clicked.

Then instead of your Update() code, you would have:

void Update() 
{
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit2D[] hits; 
        Vector2 pos = Input.mousePosition;
        pos = Camera.main.ScreenToWorldPoint (pos);
        hits = Physics2D.RaycastAll (pos, new Vector2 (0, 0), 0.01f);

        for (int i = 0; i < hits.Length; i++) {
            if (hits [i].collider.gameObject == this.gameObject) {
                 ChefController chefScript = chefObject.GetComponent<ChefController> ();
                 print (this.gameObject.transform.position);
                 chefScript.SetTheTarget (this.gameObject.transform.position);
                 break;
            }
        }
    }
}

But quite frankly, the Raycasting should probably be done from the Player class, and then you would call a Pot.SetTarget() from there. This is not very efficient, but it should show you how to do this.

\$\endgroup\$
  • \$\begingroup\$ No, the problem is that when the mouse is clicked, every object with a PotController script tries to set the Chef's target - not only the PotController that was clicked. So whichever one runs second, wins. Instead, the asker will want to ensure this code only runs for one PotController per click - either using OnMouseDown or by manually checking the position of the cursor. \$\endgroup\$ – DMGregory Jul 1 '15 at 0:02
  • \$\begingroup\$ @DMGregory that sounds like an answer to me ;) \$\endgroup\$ – Kelly Thomas Jul 1 '15 at 0:59
  • \$\begingroup\$ @DMGregory, your description of the problem sounds spot on. Unfortunately, I don't know how to implement that. Can you give me a little more guidance? How would I use OnMouseDown to ensure that the code only runs for the intended PotController? (Alternatively, how would I check the position of the cursor and use that info?) Thanks. \$\endgroup\$ – johnnyb1970 Jul 1 '15 at 2:03
  • \$\begingroup\$ @Jon, thanks but I'm duplicating the Pot object, not the Chef object. I didn't make that clear in my post. \$\endgroup\$ – johnnyb1970 Jul 1 '15 at 13:21
  • \$\begingroup\$ @johnnyb1970 updated the answer. \$\endgroup\$ – jgallant Jul 1 '15 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.