3
$\begingroup$

I have an object that I wanted to only be limited to two possible locations, ex: X=0 OR X=1... so if the object is on X=0 and I move it forwards, it jumps to X=1, and if X=1 and I move it backwards, it jumps to X=0.

Using the Limit Location constraint only allows me to limit the object location inside a range (if min=0 and max=1, location can be 0.5, 0.3, 0.8 etc).

Is there any way to do it, even if using drivers and python expressions (maybe using an OR logic gate)?

$\endgroup$

3 Answers 3

3
$\begingroup$

For simplicity and avoiding the use of extra information:

You can check 'use self' which allows to get data from the object directly.

Using 'self' calculates the expression during the move, but keeps the current value (so that no circular dependencies) and finally apply the expression.

So for instance if the expression is:

(self.location[0] <= 0.5) * 0 + (self.location[0] > 0.5) * 1

you obtain:

enter image description here

Edit: of course in this case, the expression can be shorten to:

self.location[0] > 0.5

Edit2: following the comment of @DuaneDibbley, for your information.

A Python boolean expression can be True or False and True is numerically equal to 1, False is numerically equal to 0.

So you can use them as numerical values.

$\endgroup$
9
  • 2
    $\begingroup$ Explaining that booleans are actually represented by integers might be useful, as the OP mentioned in a reply to my comment to his own answer that he's pretty new to Python. $\endgroup$
    – user27640
    Mar 13, 2017 at 9:40
  • $\begingroup$ @batFINGER, sure! This was to give a way to assign values different to 0 and 1 $\endgroup$
    – lemon
    Mar 13, 2017 at 14:07
  • 1
    $\begingroup$ Yep read on and saw that (deleted comment). This only works if the cube is moved more than 0.5 forward or back from 0 or 1, anything less wont give the behaviour requested in question. $\endgroup$
    – batFINGER
    Mar 13, 2017 at 14:21
  • $\begingroup$ @batFINGER, see what you and agree $\endgroup$
    – lemon
    Mar 13, 2017 at 14:57
  • $\begingroup$ @lemon let me see if I understood the expression: if the self location is greater than 0.5 then the expression is True, therefore equal to 1? If less then it is False and equal to 0? Testing here I see that to increase the distance you then have to multiply the final value, so instead of *1, you use *2, etc... correct? $\endgroup$
    – Arkhangels
    Mar 13, 2017 at 17:44
2
$\begingroup$

enter image description here

Here is a quick setup in Animation Nodes, I think either using Snap or just limit between 2 values using Switch node. Depending on condition.

$\endgroup$
1
  • $\begingroup$ Really cool, thanks!!! That Switch node is so useful I cannot believe! $\endgroup$
    – Arkhangels
    Mar 13, 2017 at 4:39
1
$\begingroup$

Well, I just managed to do the switch positions thing on the viewport (which is what I wanted), using drivers and a scripted expression (avoiding a dependency cycle which is the worst problem).

The secret was using a driver on Delta Transforms instead of regular transforms, because if you use a driver on the regular transforms (ex: X-Location), Blender doesn't let you move the object at all on the viewport, but changing Delta values still lets you move the object on the viewport so we can use any local location changes to trigger the driver.

The final driver uses the Local Location of the object (var), and also the Data Path of it's own Delta Location(var2). The scripted expression is as follows:

1 if (var>0 and var!=0 and var2!=1) else 0 if (var<1 and var!=1) else 1

The logic of the expression is:

The initial Delta Location is Value1 which is X=0

The final Delta Location is Value2 which is X=1

So if the cube Local Location(var) is anything but Value1, which it is as soon as I move it a little bit and it leaves 0, then the cube Delta Location must be changed to Value2, so the cube jumps to X=1.

Since the first IF part of the expression also determines that the Delta Location must not be exactly Value2 (var2!=1), and now it is, then the IF becomes invalid and the Else part happens, so when I try to move the cube from X=1 back to zero it then checks if the Local Location is less than Value2 and also not exactly Value2 meaning that it just left X=1. If yes, then the cube's Delta Location must be changed to Value1, so the cube jumps to X=0, back to the start.

The last Else is unnecessary because it never happens, but I must use it for the expression to be valid.

I also added a limit location constraint to keep the cube inside the 0-1 range.

Here is an image: enter image description here

And it working:

enter image description here

$\endgroup$
4
  • 1
    $\begingroup$ This is good, but why the var>0 and var!=0 and the var<1 and var!=1? If var is greater than 0, it is by definition not equal to zero, and if it less than one it is by definition not equal to 1. This seems redundant to me, and I'm curious about whether you actually tried without it. $\endgroup$
    – user27640
    Mar 13, 2017 at 4:16
  • $\begingroup$ You are probably right... I'm pretty new to python programming, and I kept adding conditions to see if it would work, and as soon as it did I left it afraid of ruining it haha... PS: I just checked and you are correct, it is redundant, but curiously If I left the "!=" instead of the greater/less sign it worked but glitched a little... while leaving only the greater/less signs worked flawlessly $\endgroup$
    – Arkhangels
    Mar 13, 2017 at 4:44
  • $\begingroup$ Oh and to explain my train of thought when I was making it, I wanted to guarantee that the if or else would NOT work if the value was exactly 1 (for example), but would FOR SURE work if the value was anything BUT 1 you know? The redundancy was not really necessary in the end :/ $\endgroup$
    – Arkhangels
    Mar 13, 2017 at 4:51
  • 1
    $\begingroup$ @Arkhangels, for your information, you can also check 'use self' and set '(self.location[0] <= 0.5) * 0 + (self.location[0] > 0.5)' as expression (with no other variables needed)... I think I add an answer about that because this is to avoid circular dependencies $\endgroup$
    – lemon
    Mar 13, 2017 at 7:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .