- Home /
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);
}
}
}
If a script is disabled the update function doesn't run.
@ShadyProductions Yeah but that's okay, because I only want the update to run when I enable them. The problem is that when I enable both, it seems like not both of the updates are also running.
Answer by Bunny83 · Aug 01, 2017 at 10:23 PM
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".
@Bunny83 Thanks for taking the time to write such a detailed answer, I really appreciate it!! There are a couple of things I'm a bit confused about though, and maybe I didn't give enough context in my original post:
I used the rightP/leftP for the orientation of the ray itself, not the object, and I'm not moving the raycast object, but the actual block it's attached to. The raycasts are set to be child objects of the tile. I thought I should just set the direction of the raycast ins$$anonymous$$d of changing the rotation of the object itself.
The concrete value comparison works for me because I have a set of objects that spawn in very specific positions on awake, and I've checked in the inspector in play mode. And it also works, it does stop at the edge where it's supposed to.
Yeah but the the chunks of code with the movement are both conditional, and since they can't both be true (in this case where there's a hand of cards/tiles), I thought that only one of them can run at a time? And in the first bit of code I posted, the update only runs if the top raycast returns true. In the actual game, I wanted it to move only when a selected block is held above it, so it would only need to move then to make room. So it wouldn't keep moving left and right, only when an object is held above it.
Okay noted :D I'll fix that!
Would it move 1 every frame? Because I thought update meant that it checked every frame, and in my case, check every frame whether it's empty left/right, and only move 1 when the conditional statement returns true, and get disabled again via the update in the top raycast.
Sorry if this all seems terribly convoluted, I've had a lot of trouble with it and if you have a less horrible way of getting this mechanic to work it would be very appreciated :))