Simplify this for me? (Detecting whether or not in location)
Please tell me there's a much less gigantic approach to this.
Had to make it a screenshot so it wouldn't return to the next line.
EDIT:
if (Input.GetKeyDown(KeyCode.L)){
if (transform.position.x + cubeCursor.transform.position.x > (-1 - Tetris.lvl)){
if (transform.position.x + cubeCursor.transform.position.x < (1 + Tetris.lvl)){
if (transform.position.y + cubeCursor.transform.position.y > (-1 - Tetris.lvl)){
if (transform.position.y + cubeCursor.transform.position.y < (1 + Tetris.lvl)){
if (transform.position.z + cubeCursor.transform.position.z < (-1 - Tetris.lvl)){
if (transform.position.z + cubeCursor.transform.position.z < (1 + Tetris.lvl)){
Materialize();
}else{
Destroy(gameObject);
}
}else{
Destroy(gameObject);
}
}else{
Destroy(gameObject);
}
}else{
Destroy(gameObject);
}
}else{
Destroy(gameObject);
}
}else{
Destroy(gameObject);
}
}
(-1)
Because:
Code should never be posted as an image.
images, especially when they are important or vital to understand the question should never be hosted on an external hosting service since they will disappear after some time which will render the question completely broken.
This is not a question that can be answered. You clearly ask for coding help. That's what the help room is good for.
You might want to read the User guide
To the moderator that has published this question:
Are you actually aware of the help room and that such general questions don't belong to the usual UnityAnswers space? You might also want to read the user guide as well as the moderator guidelines.
Bunny83 , for one, the image is hosted on Imgur, so it's not going to disappear. Two, what I meant by "Return to the next line" is basically, when text on one line goes on long enough, it starts to put it on the next line.
This is line one. ------------------------------------------------------------------------------------------------------------------------------------------------------ < These dashes have returned to line 2.
Get what I mean?
Answer by wibble82 · Sep 05, 2015 at 09:29 AM
Heheh - yes there certainly is :) Takes a bit of practice to spot the patterns that make code neater!
Here's some example code to show roughly what you're trying to do. I don't know exactly what your code is trying to do, so I won't write it exactly, but basically the problem you appear to be trying to solve is 'is this point inside this box'. In your case
the 'point' appears to be transform.position + cubeCursor.transform.position
the 'box' is defined some how by a floating point value called 'tetris.lvl'. i.e. if tetris.lvl is '5', you have a box at [5,5,5], with one corner at [4,4,4] and another at [6,6,6] (cos you're subtracting and adding 1 to it)
First lesson is that you can combine multiple conditions in an if statement, so your code could immediately be simplified as follows:
if(input.GetKeyDown(KeyCode.L) && transform.position.x+cubeCursor.transform.position.x > (-1 -tetris.lvl) && bla && bla)
{
Materialize(...)
}
else
{
Destroy(...)
}
Note that the terms in the if statement can still be on multiple lines to keep the code neat:
if(input.GetKeyDown(KeyCode.L)
&& transform.position.x+cubeCursor.transform.position.x > (-1 -tetris.lvl)
&& bla
&& bla)
{
That instantly simplifies your code down to a big condition but only 2 blocks to follow it - the 'if true' and the 'else'. However by calculating some values before the if statement we can make it look a lot cleaner (and even a bit more efficient):
Vector3 point = transform.position+cubeCursor.transform.position;
Vector3 box_centre = new Vector3(Tetris.lvl,Tetris.lvl,Tetris.lvl);
Vector3 box_min = box_centre - Vector3.one;
Vector3 box_max = box_centre + Vector3.one;
if( input.GetKeyDown(KeyCode.L)
&& point.x > box_min.x && point.y > box_min.y && point.z > box_min.z
&& point.x < box_max.x && point.y < box_max.y && point.z < box_max.z)
{
}
else
{
}
Unfortunately (as far as I know) there are no handy functions in unity for comparing all elements of a vector at once, so you still end up having to compare x,y, and z separately, but it's a good start.
Apologies if that code doesn't do exactly what yours does - there might be a few typos :) Should be a good guide though. Enjoy!
(edit: I just noticed in your code your final comparison of the 'z' bit is different to those for the x and y. This might be a bug in your code, though if not you should be able to tweak my example to do the same thing)
Another method using bounds, which internally I believe does exactly what you have, but if it's being done lots might make sense!
Bounds b = new Bounds(Vector3.zero, (Vector3.one * Tetris.lvl)+Vector3.one);
Vector3 point = transform.position+cubeCursor.transform.position;
if(b.Contains(point)){
//inside
}else{
//outside
}
And another idea I'd like to test, I would be worried it might fail from floating point errors, but as it should be setting a float to a float, nothing should change?!
Vector3 point = transform.position+cubeCursor.transform.position;
Vector3 $$anonymous$$ = (-Vector3.one * Tetris.lvl)-Vector3.one;
Vector3 max = (Vector3.one * Tetris.lvl)+Vector3.one;
if(Vector3.$$anonymous$$in($$anonymous$$, point) == $$anonymous$$ && Vector3.$$anonymous$$ax(max, point)){
//inside
}else{
//outside
}
It should be noted that, that last method is actually equivalent to changing the equivalence relations from <
and >
to <=
and >=
respectively.
Totally could have thought of this, I feel so stupid now xD
Thanks for your help!
Answer by bluesam3 · Sep 05, 2015 at 12:20 PM
Ah, we can simplify here by maths: The box that you want is a unit ball in the supremum norm, so the following code will work (after defining point and box_centre as in wibble82's post):
if( input.GetKeyDown(KeyCode.L) && Math.Max(Math.Abs(x-box_centre.x),Math.Max(Math.Abs(y-box_centre.y),Math.Abs(z-box_centre.z))) < 1)
{
Materialize();
}
else
{
Destory(gameObject);
}
nice use of Abs! though you do not need the $$anonymous$$ax call here.
(And the fact that a cube is a unit sphere on the supremum p-norm really has no relevance to the answer you gave ^^)
It has relevance to the logic of how I got to it: $$anonymous$$ath.$$anonymous$$ax($$anonymous$$ath.Abs(x-box_centre.x),$$anonymous$$ath.$$anonymous$$ax($$anonymous$$ath.Abs(y-box_centre.y),$$anonymous$$ath.Abs(z-box_centre.z)))
is precisely the supremum norm distance from (x,y,z)
to box_centre
. Also, the two max calls are very definitely necessary, or you're not checking all three dimensions.
Woah, my bad, I completely misread the brackets!
Still the original code suggests it should be a box centred on (0, 0, 0) with extents of 1+Tetris.lvl rather than centred on (Tetris.lvl , Tetris.lvl , Tetris.lvl) with extents of size 1. Though Wibble appears to have done the same and been accepted so I guess you are correct in the assumption ^^