- Home /
Problem with dynamic camera script ( Super smash bros. )
Inspired by one of the older entries in this forum I wrote a dynamic camera script for a small "Super smash bros."-esque brawler. For some reason that lies beyond my comprehension I, seemingly, randomly get a very weird glitch. The camera does what it should perfectly well but if I jiggle and jump the characters around enough at some point the camera will position itself completely weird when one of the characters is directly above the other one... on a platform for example. Since I couldnt find out what was wrong I thought maybe one of you could help me. Anyway..I thank everybody even only reading this in advance and help would be very much appreciated.
PS: I've done some read-out of the used values ( subPosition, cross etc. ) and, as far as I could tell, they were correct/identical on both occasions ( the correct and the glitched occasion ).
CODE:
void calculateCameraPos()
{
float tempDistance;
tempDistance = GameObject.Find("Character 1 Controller").transform.position.x
- GameObject.Find("Character 2 Controller").transform.position.x;
if( tempDistance <= 0 )
{
newDistance = Vector3.Distance( GameObject.Find("Character 1 Controller").transform.position,
GameObject.Find("Character 2 Controller").transform.position );
Vector3 subPosition = GameObject.Find("Character 1 Controller").transform.position -
GameObject.Find("Character 2 Controller").transform.position;
Vector3 cross = Vector3.Cross( subPosition, Vector3.up );
Vector3 halfWay = ( GameObject.Find("Character 1 Controller").transform.position +
GameObject.Find("Character 2 Controller").transform.position ) / 2;
halfWay.y += yOffset;
mainCamera.transform.position = halfWay + cross.normalized * newDistance * distanceScale;
}
if( tempDistance > 0 )
{
newDistance = Vector3.Distance( GameObject.Find("Character 1 Controller").transform.position,
GameObject.Find("Character 2 Controller").transform.position );
Vector3 subPosition = GameObject.Find("Character 2 Controller").transform.position -
GameObject.Find("Character 1 Controller").transform.position;
Vector3 cross = Vector3.Cross( subPosition, Vector3.up );
Vector3 halfWay = ( GameObject.Find("Character 2 Controller").transform.position +
GameObject.Find("Character 1 Controller").transform.position ) / 2;
halfWay.y += yOffset;
mainCamera.transform.position = halfWay + cross.normalized * newDistance * distanceScale;
}
}
What it should do all the time:
What it does occasionally ( characters are positioned like they are in the picture above ):
Although I'm not sure what could be going wrong in this particular situation, I can give you some tips for solving bugs such as these:
1) $$anonymous$$ake a quick repro case
Set up your game so that as soon as you hit play, or with as little interaction as possible, the issue occurs. Doing so will reduce your iteration time.
2) Work your way back from the problem gradually:
So for example if the camera position is wrong, first find out which one of those if statements is being executed. This might be done using breakpoints or Debug.Logs.
3) Reduce the problem to absurdity:
If something is happening which, by your logic, cannot possibly be happening if the code is functioning correctly, try to work your way back through the code to something else which also could not be happening. $$anonymous$$eep going, checking the logic of your code. You should eventually reach a point where you spot the error in the logic.
Answer by MakeCodeNow · Feb 19, 2014 at 04:47 PM
The problem is this line:
Vector3 cross = Vector3.Cross( subPosition, Vector3.up );
When one character is right above the other, subPosition will be the same as Vector3.up and the cross product will return a zero length vector (which you also can't normalize later on). The easy fix is to check for this case and then use a different basis vector, like Vector3.right when subPosition is close to straight up and down.
Sorry as I started writing my response yours wasnt showing yet. I'll try that immedately. Thanks! Sounds very promising ^^
Somehow it doesnt seem to work. But that could be because I might have gotten it wrong. I tried these approaches based on your advice:
Replaced: Vector3 cross = Vector3.Cross( subPosition, Vector3.up );
With:
1) if( subPosition == Vector3.up ) { cross = Vector3.Cross( Vector3.right, Vector3.up ); } else { cross = Vector3.Cross( subPosition, Vector3.up ); }
2) if( subPosition == Vector3.up ) { cross = Vector3.Cross( subPosition, Vector3.right ); } else { cross = Vector3.Cross( subPosition, Vector3.up ); }
Also like I elaborated in my second post sometimes it works just fine with the cross-product being (0,0,0). For example ( camera doesnt glitch ):
Left of**
Distance: 8.813066
Subposition: (0.0, 8.8, 0.0)
Cross: (0.0, 0.0, 0.0)
Halfway: (19.3, 0.6, -1.8)
$$anonymous$$ainCamPos(actual): (19.3, 0.6, -15.0)
$$anonymous$$ainCamPos(calculated): (19.3, 0.6, -15.0)
Thanks anyway by the way.
The == comparison is probably too specific a test. With floating point numbers you usually need to compare with a range. I'd suggest using the dot product. Something like:
if($$anonymous$$athf.Absf(Vector3.Dot(subPosition.normalized, Vector3.up)) > 0.98f)
Is there any need to work out that cross product vector anyway? In a 2D game it's always going to be (0.0, 0.0, 1.0) when normalised.
Ah I see that would make sense since the problem occurs in a certain range when it does occur... Sorry I did not answer sooner I didnt have very much time yesterday. But I will implement your advice as soon as I get home. Thanks again
Answer by Facelessoldier · Feb 19, 2014 at 05:24 PM
Thank you very much for your response. Sadly I am already almost out of options regarding your advice:
1) Because I cant seem to find out what the cause of that glitch is I am not able to shorten the time for the bug to occur.
2) I've done that and came to conclusion that it does not seem to be related to exactly one of the if statements. It rather occurs in a "range" of values. So after a few minutes of jumping around etc. the camera wrongly positions itself as soon as I come close to the point of the two characters being upon one another in any way ( jumping over the other or on a platform above ). This does not happen all the time by the way. It starts at random. On rare occasions as soon as I start the program sometimes after a few minutes of play but as soon as it occurs it doesnt go away ^^'
3) As I mentioned earlier Ive done some read-out of the values and this is just some of my data:
Two of the "correct" value-sets ( meaning the camera does not glitch ):
Left of**
Distance: 8.813796
Subposition: (-0.1, 8.8, 0.0)
Cross: (0.0, 0.0, -0.1)
Halfway: (19.3, 0.6, -1.8)
MainCamPos(actual): (19.3, 0.6, -15.0)
MainCamPos(calculated): (19.3, 0.6, -15.0)
Left of**
Distance: 8.813066
Subposition: (0.0, 8.8, 0.0)
Cross: (0.0, 0.0, 0.0)
Halfway: (19.3, 0.6, -1.8)
MainCamPos(actual): (19.3, 0.6, -15.0)
MainCamPos(calculated): (19.3, 0.6, -15.0)
"Wrong" values from either if-statement ( camera does glitch ):
Left of**
Distance: 8.813087
Subposition: (0.0, 8.8, 0.0)
Cross: (0.0, 0.0, 0.0)
Halfway: (19.4, 0.6, -1.8)
MainCamPos(actual): (25.0, 0.6, -13.8)
MainCamPos(calculated): (25.0, 0.6, -13.8)
Right of**
Distance: 11.4156
Subposition: (-0.1, -11.4, -0.1)
Cross: (0.1, 0.0, -0.1)
Halfway: (19.5, 1.9, -1.7)
MainCamPos(actual): (33.2, 1.9, -12.1)
MainCamPos(calculated): (33.2, 1.9, -12.1)
As you can see the values seem to be identical ( Ive tried to recreate the positions as closely as possible ).
My only explanation is that either the values get tampered with by rounding the values too much or the Vector-functions have some kind of bug. At least I cant find any other solution.
Again thank you anyway Dave Hampson for sacrificing your time and I'll definitly come back to this problem every now and then...maybe at some point I'll have one of those 'Eureka' moments ^^
Your answer
Follow this Question
Related Questions
Arms disappearing in front of camera? 1 Answer
Editor Camera moving while rotating 0 Answers
Problem with Camera when building 1 Answer
How to make camera position relative to a specific target. 1 Answer
How do I fix this? 1 Answer