Only a portion of update gets called?

Hi! I’m making a mahjong type game and right now I’m working on the ability to reorganise a hand. I did this by making 3 game objects that cast raycasts (top, right, left). The right and left one and disabled on awake, and only when the top one hits an object will the other two be enabled. The right and left objects have a respective script that calls an update to move the block right or left depending on which side is empty. However, it’s like the two updates can’t be called at the same time. They only work when only one of them is enabled. Is this the result of some clashing in the updates? Thank you in advance!!

The raycast on top:

public class UpRaycast : MonoBehaviour {

	Vector3 up;
	GameObject right, left;

	void Awake(){
		up = transform.TransformDirection (Vector3.up);
		right = this.transform.parent.GetChild (1).gameObject;
		left = this.transform.parent.GetChild (2).gameObject;
	}

	void Start(){
		right.SetActive (false);
		left.SetActive (false);
	}

	void Update () {

		if (Physics.Raycast (this.transform.position, up, 50)) {
			left.SetActive (true);
			//right.SetActive (true);

		}

		if (Physics.Raycast (this.transform.position, up, 50) == false) {
			right.SetActive (false);
			left.SetActive (false);
		}
	}
}

Raycast on the right:

public class RightRaycast : MonoBehaviour {

	Vector3 rightP;

	void Awake(){
		rightP = transform.TransformDirection (Vector3.right);
	}

	void Update () {
		if (Physics.Raycast (this.transform.position, rightP, 1) == false && transform.parent.parent.position.x != 6) {
			Debug.Log ("i shuodl be moving right");
			transform.parent.parent.position += new Vector3(1,0,0);
		} 
	}
}

Raycast on the left:

public class LeftRaycast : MonoBehaviour {

Vector3 leftP;

void Awake(){
	leftP = transform.TransformDirection (Vector3.left);
}

void Update () {
	if (Physics.Raycast (this.transform.position, leftP, 1) == false && transform.parent.parent.position.x != -6) {
		transform.parent.parent.position -= new Vector3(1,0,0);
	}
}

}

There are several things strange / wrong in your scripts:

  • First of all you use a vector relative to the objects rotation (rightP / leftP) for the raycast, but the object is moved in world space along “x”. This seems just strange. Either you don’t care about the rotation and you shoulst simply use “Vector3.right” or you do care about the rotation in which case you should move along rightP / leftP. This mixture makes no sense. It’s irrelevant if the object isn’t rotated (aligned with the world). Though it’s just inconsistant which makes no sense.
  • Comparing the x component of the position against a concrete value will almost always fail (or inequalite will always be true). It’s almost impossible due to floating point rounding errors to exactly hit “6” or “-6”. A value of “6.00000001” is not “6”. You always need to check a range. In your case you might want to check if it’s larger or equal to “6” and smaller or equal to “-6”.
  • You are aware of the fact that when both of your scripts (“RightRaycast” and “LeftRaycast”) are active that their action will cancel each other since one script move the object to the right and the other move it to the left.
  • Be careful when using GetChild. Keep in mind that the child index start at “0”. It’s dangerous to reference childs like that. They could be reordered. It’s usually better to just use public variables and assign the right child objects to the right variables in the inspector. If you want to dynamically assign the variables it’s still better to use “transform.Find” with the child name.

It seems a bit strange that you create seperate scripts for this. It’s not really clear what the result of those 3 scripts should be. If there’s space to the left the LeftRaycast script will move the object 1 unit to the left each frame. However if both scripts are active after you moved on step left there would be space on the right as well so the movement of both scripts will cancel each other and the object won’t move at all.

Since the UpRaycast script dynamically activates / decativates the other scripts the execution order of your scripts gets very important. Without knowing that order the result is pretty random.

Finally not an error but a possible simplification. This line:

up = transform.TransformDirection (Vector3.up);

can be simplified to:

up = transform.up;

The same can be done for “rightP” and “leftP”.