0
votes

Working on 2D mode, I have a script attached to a Sprite. The Update() part is as follow:

void Update () {
  if (Input.GetKeyDown ("left")) {
    cursor.rigidbody2D.MovePosition (cursor.rigidbody2D.position - speedX);
  } else if (Input.GetKeyDown ("right")) {
    cursor.rigidbody2D.MovePosition (cursor.rigidbody2D.position + speedX);
  } else if (Input.GetKeyDown ("up")) {
    cursor.rigidbody2D.MovePosition (cursor.rigidbody2D.position + speedY);
  } else if (Input.GetKeyDown ("down")) {
    cursor.rigidbody2D.MovePosition (cursor.rigidbody2D.position - speedY);
  }
}

where cursor is a Prefab linked in Inspector. The cursor prefab has only 2 components, Sprite Renderer (to define the image), and the Rigidbody 2D, which setting is as follow:

  • Mass = 1
  • Linear Drag = 0
  • Angular Drag = 0
  • Gravity Scale = 0
  • Fixed Angle = true
  • Is Kinematic = false
  • Interpolate = None
  • Sleeping Mode = Start Awake
  • Collision Detection = Discrete

But when I press the arrow keys, the sprite showing on screen does not move. What did I miss?

Tried to add Debug.Log() inside the if case, it really enters the case. And no error occurred.

Note: speedX = new Vector2(1,0); and speedY = new Vector2(0,1);

1
Is cursor really linked with the prefab or with an instance of it? If it is linked with an object in your scene than the script should work.Stefan Hoffmann
It linked with a Prefab, dragged from Asset Library. How can I move a Prefab that does not appear on screen at the beginning? The above script is run after a OnMouseDown() event, which Instantiate() the Prefab on screen.Raptor

1 Answers

1
votes

You're trying to move an object that doesn't exist from the game's perspective. Assigning cursor a prefab by dragging it from the assets library, is like assigning a blueprint. Telling the prefab to move is like yelling at a car's blueprint to accelerate :)

There are two general solutions.

1) Save a reference

Instantiate the prefab and save the resulting reference to manipulate your new object. You can directly cast it to Rigidbody2D if you're mainly interested in using the rigidbody. The cast will only work if your prefab variable is of the same type, otherwise it will raise an exception. This way will ensure that your prefab always contains a Rigidbody2D or you can't even assign it in the editor.

public Rigidbody2D cursorPrefab; // your prefab assigned by the Unity Editor

Rigidbody2D cursorClone = (Rigidbody2D) Instantiate(cursorPrefab);
cursorClone.MovePosition (cursorClone.position - speedX);

2) Assign the script to the prefab

Depending on your game and what you want to achieve, you can also add a script directly to the prefab. This way every instance of it would just control itself.

void Update () {
  if (Input.GetKeyDown ("left")) {
    rigidbody2D.MovePosition (rigidbody2D.position - speedX);
  } else { //...}
}