- Home /
Vector3 multiplied by its magnitude results in infinity?
I'm working on a section of code that needs to find a vector from the difference between two other vectors:
Vector3 displacement = (attachedTransform.position - masterTransform.position);
Then the code needs to multiply this vector (displacement) by it's own magnitude:
displacement *= displacement.magnitude;
Which is where things go wrong. Unity handles the vector fine until I try to apply it to a transform. At this point, it gives one of several error messages:
transform.position assign attempt for 'Rope.Node' is not valid. Input position is { NaN, NaN, NaN }.
UnityEngine.Transform:set_position(Vector3)
or
transform.position assign attempt for 'Rope.Node' is not valid. Input position is { infinity, infinity, infinity}.
UnityEngine.Transform:set_position(Vector3)
Note that the infinity error usually states either one or two of the components as being negative infinity.
I've used monoDevelop debugging and in the method that is supposed to return this Vector3, MonoDevelop has no problem showing me values for displacement, displacement.magnitude, or displacement.sqrMagnitude; they are all perfectly fine values, e.g.
displacement.magnitude = 3.208273
displacement = {(-0.7,0.6,0.3)}
I'm a little lost as to what is causing this, has anyone else seen this?
EDIT:
Let me explain a little better. I've designing a system that contains a bunch of instances of a class called Node. Nodes have a List of another class, called Target. Each frame, the Node runs through the list of targets and adds up each one's displacement (kind of a force, if you will) on it's master node.
In this case, the system is composed of a string of nodes where each node has a target on the previous and next nodes, so that each node is pulled towards both of its neighbors. I want this displacement to be the squared distance between the nodes, which is why I am NOT normalizing displacement before multiplying it again by it's magnitude.
I have also tried:
Vector3 displacement = (attachedTransform.position - masterTransform.position);
Vector3 n = displacement.normalized;
float d = displacement.sqrMagnitude;
return n * d;
and it results in the same error.
Here is the more complete code, for reference:
Target.getDisplacement():
public Vector3 getDisplacement() {
Vector3 n = (attachedTransform.position - masterTransform.position);
float d = n.sqrMagnitude;
n.Normalize();
//weight is a float from 0 to 1 that allows balancing of targets
return n*d*weight;
}
Node.Update():
public void Update() {
Vector3 displacement = Vector3.zero;
foreach (Target t in targetList) {
displacement += t.getDisplacement();
// Debug.DrawLine(transform.position, transform.position + t.getDisplacement(), c);
}
RaycastHit rayHit;
if (Physics.Raycast(transform.position, displacement.normalized, out rayHit, displacement.magnitude, collidesWith)) {
//if we hit something with our displacement, only move to that point
transform.position += displacement.normalized * (rayHit.distance - colliderRadius);
} else {
//if we didn't hit something, apply full displacement
transform.position += displacement;
}
}
}
If you could, provide us with the methods involving this problem, maybe your problem is being caused somewhere that you are not realizing it.
Try to use use auxiliary variables intermediate operations, sometimes works
Answer by Blackup · Apr 09, 2015 at 02:17 PM
You're not using a normalized vector... so your first and second lines result in an exponential displacement, which, if applied every frame will keep pushing the displacement further and further out exponentially.
Technically you only need the first line.
Get rid of "displacement *= displacement.magnitude;" So just have "Vector3 displacement = (attachedTransform.position - masterTransform.position);" and see if that works.
Alternatively
Try the following instead.(though my first recommendation is a shorter simpler version of achieving the same...this will just explain what is missing.)
Vector3 displacement = (attachedTransform.position - masterTransform.position);
Vector3 direction = displacement.normalized;
displacement = direction * displacement.magnitude;
I've edited above to clarify a bit. I realize that I am not using the normalized vector, but it should result in a runaway value because this vector, displacement
, is used to pull masterTransform
towards attachedTransform
,so it should act like a negative feedback loop.
In fact,
Vector3 n = (attachedTransform.position - masterTransform.position);
float d = n.magnitude;
n.Normalize();
return n*d*weight;
returns the exact same errors, but
Vector3 displacement = (attachedTransform.position - masterTransform.position);
return displacement*weight;
works fine.
So is it working now or not yet?
The two segments above should yield the same results. The logic is exactly the same. I'm not sure why you are squaring your displacement and would recommend that you stick with one of the two approaches above.
What are you doing for the first and last node sin your string? If you are applying the same displacement method then (having only one neighbor) they might be going out of control. But if you are forcing their position ins$$anonymous$$d, then it might be fine.
If you are still experiencing problems then exa$$anonymous$$e the assignments of attachedTRansform, masterTransform and weight. If any of these three are not what you expect them to be, then it could cause the runaway.
Alternatively use a stepping process to play and pause your program one frame at a time. You might be able to see which node is causing the trouble if not all of them.
Your answer
Follow this Question
Related Questions
What is the error? 2 Answers
Vector3.SmoothDamp has some invalid arguments 0 Answers
Distribute terrain in zones 3 Answers
Switch statement not working C# (answered) 1 Answer
[Solved]List.FindIndex error C# 1 Answer