Compilation of Problems

Greetings good folk of the Unity Forum. Today my partner has requested that I post all of our problems on here in the hope that they can be browsed and fixed quickly - and to make it easier for you guys he’s made some video evidence so you can diagnose our issues more accurately! :smile: I’ll start with some contents…

  1. A seemingly perfect code has a crazy effect on the iPhone version of Unity
  2. Turret Rotation Limits
  3. “Jittering” on NPC’s

Here is the video, it covers the problems with some detail so you can see exactly what is happening; http://www.youtube.com/watch?v=7SsYLU9k3qs (sound is required for explaination)

Ok, let’s start with 1. -
A seemingly perfect code has a crazy effect on the iPhone version of Unity

This problem is the one that is most visible in the video - instead of aiming at the UFO and firing a single shot the NPC’s start blasting away as if they’re carrying a minigun. As my partner said, the script works properly in the editor, and it’s only after compilation that this starts to happen. Here is the script in question;

var LookAtTarget : Transform;
var damp = -1.0;
var bulletPrefab : Transform;
var thingdelay : int;
var cowxpos : float;
var cowypos : float;

function secondwait ()
{
    thingdelay = 2;
    yield WaitForSeconds(2);
    thingdelay = 0;
}

function Update () 
{
    LookAtTarget2 = transform.Find("front");
    cowxpos = transform.position.x;
    cowypos = transform.position.y;    
    
    if (cowxpos >= UFOcontrolBox.ufoxpos + 0.5)
    {
        Shoot();
            
        if(LookAtTarget)
        {
            //this is where the wanted rotation is calculated
            var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
            
            //this spherically lerps the rotation from what it is to the wanted rotation
            transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);

            //this is the part I added, which clamps every variable between a minimum and maximum amount
            rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
        }
    }
    
    if (cowxpos <= UFOcontrolBox.ufoxpos - 0.5)
    {
        Shoot();
        
        if(LookAtTarget)
        {
            //this is where the wanted rotation is calculated
            rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
            
            //this spherically lerps the rotation from what it is to the wanted rotation
            transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
            
            //this is the part I added, which clamps every variable between a minimum and maximum amount
            rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
        }
    }
}


function Shoot()
{
        if (thingdelay == 0)
        {
            var bullet : Object = Instantiate(bulletPrefab,transform.Find("spawnPoint").position, Quaternion.identity);

            bullet.rigidbody.AddForce(transform.forward * 350);

            secondwait();
        }

}

Quote: Adad

“The Editor is displaying a working code with the line “var bullet : Object = Instantiate(bulletPrefab, transform.Find(“spawnPoint”).transform.position, Quaternion.identity);” switching “Object” with “GameObject” would create an infinite spawning of bullets problem for us, the editor likes just the “Object” code, but when compiled with this code for the iPhone 4, the same problem that GameObject was giving us arises”

Problem 2. -
Turret Rotation Limits

This problem has been nagging at me for a while, and I’ve really been trying to avoid doing it for a while, but sadly this is because I’ve had no success and don’t know how to fix it! We’ve been using a variation of the standard TornadoTwins Turret Script to make our NPC’s target the UFO and fire. This has been working well, almost perfectly in fact, but my partner complains that the result looks “half assed” - by this he means the character’s arms rotate to an unrealistic angle when they shoot and he has asked that I fix it by limiting the angles at which the turret can turn to. Sadly, I don’t have a clue how to do this and help in the past has gotten nowhere (though I suspect that is due to my limited understanding of what was provided). Here is one of the targetting scripts in question;

var LookAtTarget : Transform;
var damp = -1.0;
var bulletPrefab : Transform;
var thingdelay : int;
var cowxpos : float;
var cowypos : float;

function secondwait ()
{
    thingdelay = 2;
    yield WaitForSeconds(2);
    thingdelay = 0;
}

function Update () 
{
    LookAtTarget2 = transform.Find("front");
    cowxpos = transform.position.x;
    cowypos = transform.position.y;    
    
    if (cowxpos >= UFOcontrolBox.ufoxpos + 0.5)
    {
        Shoot();
            
        if(LookAtTarget)
        {
            //this is where the wanted rotation is calculated
            var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
            
            //this spherically lerps the rotation from what it is to the wanted rotation
            transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);

            //this is the part I added, which clamps every variable between a minimum and maximum amount
            rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
        }
    }
    
    if (cowxpos <= UFOcontrolBox.ufoxpos - 0.5)
    {
        Shoot();
        
        if(LookAtTarget)
        {
            //this is where the wanted rotation is calculated
            rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
            
            //this spherically lerps the rotation from what it is to the wanted rotation
            transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
            
            //this is the part I added, which clamps every variable between a minimum and maximum amount
            rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
        }
    }
}


function Shoot()
{
        if (thingdelay == 0)
        {
            var bullet : Object = Instantiate(bulletPrefab,transform.Find("spawnPoint").position, Quaternion.identity);

            bullet.rigidbody.AddForce(transform.forward * 350);

            secondwait();
        }

}

Personally I feel that physics code is “icky”, so please provide an explaination with your solution! :smile:

Quote: Adad

“The game is 2d, so the rotation of the turret should always be 2d locked, kinda like the old 2d metal slug games.”

Problem 3.
“Jittering” on NPC’s

This is quite a problem for us as it is quite noticeable ingame - as you can see in the video the NPC’s vibrate when the saucer flies over them, and I suspect I may have put some if statements the wrong way round somewhere, but I was unable to find anything myself. As it is always good to get another programmer to look over your code, I’ve done exactly that! This is probably just something I’ve overlooked, but please point out anything you notice!

var beenbeamed = 0; // lets the game know when to kill cows when they fall a long distance
var move = -0.5; // this is the normal move speed
var moveup = -0.5; // this variable is for upward/downward movement aka abduction and gravity
var cowxpos : float; // the NPC's x position
var cowypos : float; // the NPC's y position
var Moo : AudioClip;
var steakPrefab : Transform; // the remains that spawn

function Update () 
{ 
    cowxpos = transform.position.x; 
    cowypos = transform.position.y;
    transform.position.z = -0.5;
    
    if (transform.position.x < -20) 
    { 
    transform.rotation.y = 180; 
    } 
    if (transform.position.x > 13) 
    { 
    transform.rotation.y = 0; 
    }
    if (transform.position.y > -2.5)
    {
        beenbeamed = 1;
    }
    if (transform.position.y < -4.55)
    {
        if (beenbeamed == 1)
        {
            Destroy (gameObject);
        }

        transform.position.y = -4.55;
    }


    
    move *= Time.deltaTime;         // this is changing the value of move - thats why the cow wont
    moveup *= Time.deltaTime;      // move unless it's reset every time it's run.

    transform.Translate (move, moveup, 0); 
}

function FixedUpdate () 
{
    // NORMAL ABDUCTION BEAM
    if (BeamTexture.on == 1) // is the beam on?
    {
        if (cowxpos >= UFOcontrolBox.ufoxpos - 0.2  cowxpos <= UFOcontrolBox.ufoxpos + 0.6) // is the cow within 0.5 distance of the saucer?
        {
            move = 0;
            moveup = 1.5;
            if (!audio.isPlaying)
            audio.Play ();
            
            if (cowypos > UFOcontrolBox.ufoypos)
            {
                Destroy (gameObject);
                ScoreCount.score = ScoreCount.score + 10;
            }
        }
        
        else
        {
            move = -0.5;
            if (transform.position.y < -4.54)
            {
                moveup = 0;
            }
            if (transform.position.y > -4.54)
            {
                moveup = -1.5;
            }
        }
    }

    else // if the beam is anything else but on, aka off, go back to the normal speeds.
    {
        move = -0.5;
        if (transform.position.y < -4.55)
        {
            moveup = 0;
        }
        if (transform.position.y > -4.55)
        {
            moveup = -1.5;
        }
    }

    // DEATH BEAM
    if (cowxpos >= UFOcontrolBox.ufoxpos  cowxpos <= UFOcontrolBox.ufoxpos + 0.6) // is the cow within 0.3 distance of the saucer?
    {
        if (DeathBeamTexture.on == 1) // is the beam on?
        {
            var steak = Instantiate(steakPrefab,transform.position, Quaternion.identity);
            Destroy (gameObject);
        }
        
        else
        {
            move = -0.5;
            if (transform.position.y < -5.6)
            {
                moveup = 0;
            }
            if (transform.position.y > -5.6)
            {
                moveup = -1.5;
            }
        }
    }
}

If you’ve gotten this far and read everything, you truly are a GOD. But please, be benevolent and help us! We’re always open to suggestions, so if you find anything that can be optimized without too much hassle or something that can be done better, please say and you shall be worshipped :smile:

I look forward to your many thousands of infinately helpful replies! :razz:

Much love, the ><>FreakFish<>< and Mr. Morales

BUMP-

Hmm… no replies in 20 hours… where have all the good guys gone? :frowning:

Bumping this

We’re all debugging our own code, which is what you should be doing. :wink:

Use Debug.Log() or OnGUI() to display your variables on screen and figure out why your object positions aren’t what you think they should be.

Now this I might be able to help you with, try casting to Transform instead:

var bullet : Transform = Instantiate(bulletPrefab, transform.Find("spawnPoint").transform.position, Quaternion.identity);

And if you need to access the gameObject, just use bullet.gameObject

It may seem counter-intuitive, but I would suggest you not use other people’s code unless you have a fair understanding of what it is doing. Otherwise, it can be quite difficult to track down any bugs that appear (you never know if it’s your code, or the other person’s code).

You sir are a genius and a savior, if not a God. It’s working in both the editor and on the iPhone! Thanks for the fix and the tips, you’ve saved us a whole load of time! We’re now 1/3 closer to releasing the game thanks to your almighty knowledge!

Thanks for the reply Tony, that sure did the trick for the bullets!

Hopefully we could figure out the other two problems :slight_smile: , anyone have suggestions??

Willing to Paypal $50 to a professional programmer who can help us fix these errors so we can release our game already

If I understand your second problem correctly, I think you can use Quaternion.Angle to get the degrees of the angle it is turning, then do a check on it before doing the Slerp. Something like this maybe:

if(LookAtTarget)
{
	//this is where the wanted rotation is calculated
	var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
	
	if(Quaternion.Angle(transform.rotation, rotate) < maxRotationDegrees)
	{
		//this spherically lerps the rotation from what it is to the wanted rotation
		transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
		//this is the part I added, which clamps every variable between a minimum and maximum amount
		rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
	}
}

That’s my take on it, hopefully it will help. Not sure about your third problem yet… :slight_smile:

For your third problem, you might try adding an else to the 2nd if statement in the groups that compare similar variables:

if (transform.position.y < -5.6)
            {
                moveup = 0;
            }
            else if (transform.position.y > -5.6)
            {
                moveup = -1.5;
            }

I’m not totally sure how your code works and where all of the numbers come from, but it looks to me like a variable that controls movement in the y direction might be flipping back and forth. Also, you probably already know, but when doing 2 comparisons with ‘<’ and ‘>’ you exclude the actual value (-5.6 in the example above), so unless you don’t want to do anything when the variable is that value, be sure to use ‘=’ in one of the comparisons (<= or >=), or just eliminate the 2nd ‘if’ and make it just an ‘else.’ If nothing else that should speed up its execution as there are less comparisons to make. Hopefully that helps some, good luck! :slight_smile:

lol… your thread title made me laugh cos i thought it said complications of problems and that is what im having too with my project … if i had the knowledge i would try to help …but my programming really suks monkye notes

Thanks for the fast replies Bauer, im testing the jitter code right now , but your turret code might be on to something

heres whats it doing

click here for a bigger image


( i flipped one of the crops because i was too lazy to take another screenshot, but essentially the gun moves up like if it was on a cylindrical base, until it points straight up at the target, and it then continues acting like the spherical lerp it is, non of the clampings for the Y axis seem to work to stop it from doing this)

as you see, were trying to make the turret not turn when the its pointing straight up, ive tried clamping with different variables and the same issue occurs, any ideas?

I think I see an error in what I gave you earlier. I had the Angle function getting the angle between the turrets current rotation and the target rotation. Instead, I think what you want is the angle between the horizontal axis and the target rotation. Depending on how the game object is rotated, you’ll want to use its forward or right local axis. Anyway, swap that line I gave you out and try these:

var forward = transform.TransformDirection(Vector3.forward); //if that doesnt work, try -forward, right, -right
if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < maxRotationDegrees)

(where maxRotationDegrees is the most you want it to turn up from the horizontal axis)

var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);

am I removing this line too? , I receive alot of errors because of their being no variable to “rotate” , and the code gets lost

				var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);
				var forward = transform.TransformDirection(Vector3.forward); //if that doesnt work, try -forward, right, -right
				if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < 180)
			{
				//this spherically lerps the rotation from what it is to the wanted rotation
				transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
				//this is the part I added, which clamps every variable between a minimum and maximum amount
				rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 180, 180));
			}

thats what I have now, it runs but no noticeable affect can be seen, let me know if you need me to change the "rotate"s into something else ( tried replacing all of them with forward and an error shitstorm occured)

Bauer

this piece of code seems to almost be working

        {
				rotate = Quaternion.LookRotation(forward);
				forward = transform.TransformDirection(Vector3.up); //if that doesnt work, try -forward, right, -right
				if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < 90)
			{
				//this spherically lerps the rotation from what it is to the wanted rotation
				transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
				//this is the part I added, which clamps every variable between a minimum and maximum amount
				rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 0, 180));
			}

for some reason the turret “jitters” left and right, but its properly facing its side to the camera, unfortunately it also doesnt follow my target now

, forgive me , i have absolutely no experience with quaternions etc, thanks soo much for the help so far!

AH! , so its moving when i give it a “rotate) < 180)” instead of 90, but its turning on the Y axis and not the X… god this turret is such a fuckup lol

That should work, but your max degrees is too high I think. 180 degrees is a half turn, so the turret will still be able to aim straight up. Try somewhere between 45 and 70, depending on how high you want it to be able to aim.

We posted at the same time :slight_smile: I was referring to your post 2 above me. If changing the 180 to something smaller still doesn’t work, then the line
var forward = transform.TransformDirection(Vector3.forward);
might be off. Try changing the Vector3.forward to one of these:
Vector3.right
-Vector3.right
-Vector3.forward
It all just depends how your game object is originally rotated.

Gave it a shot , still doesnt want to work properly, im uploading a video onto youtube so you can witness what is happening, I’ll scrap the npc and start a fresh prefab and try this again tomorrow, its getting late here (2 am)

Thanks again for the help Bauer, email me at adad.morales@gmail.com, if you have any ideas from the video, ill check the thread tomorrow (today) to get this fixed lol

ill post the video url once it finishes uploading (10 mins)

heres the video

Well it looks like its not rotating straight up anymore, but instead rotating around both the y and x axis. Post your code again or send it to me and I’ll take another look. Also, if you can take a screen shot of the game object’s local axes in relation to the world axes, that way I know how you have it rotated.

var LookAtTarget : Transform;
var damp = -1.0;
var bulletPrefab : Transform;
var thingdelay : int;
var cowxpos : float;
var cowypos : float;

function secondwait ()
{
    thingdelay = 2;
    yield WaitForSeconds(2);
    thingdelay = 0;
}

function Update () 
{
    LookAtTarget2 = transform.Find("front");
    cowxpos = transform.position.x;
    cowypos = transform.position.y;    
    
    if (cowxpos >= UFOcontrolBox.ufoxpos + 0.5)
    {
        Shoot();
            
        if(LookAtTarget)
        {
				
				var forward = transform.TransformDirection(-Vector3.right); //if that doesnt work, try -forward, right, -right
				var rotate = Quaternion.LookRotation(forward);
				if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < 70)
			{
				//this spherically lerps the rotation from what it is to the wanted rotation
				transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
				//this is the part I added, which clamps every variable between a minimum and maximum amount
				rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 0, 180));
			}
        }
    }
    
    if (cowxpos <= UFOcontrolBox.ufoxpos - 0.5)
    {
        Shoot();
        
        if(LookAtTarget)
        {
				rotate = Quaternion.LookRotation(forward);
				forward = transform.TransformDirection(-Vector3.right); //if that doesnt work, try -forward, right, -right
				if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < 70)
			{
				//this spherically lerps the rotation from what it is to the wanted rotation
				transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
				//this is the part I added, which clamps every variable between a minimum and maximum amount
				rotate.eulerAngles = Vector3(Mathf.Clamp(rotate.eulerAngles.x, 180, 225), Mathf.Clamp(rotate.eulerAngles.y, 0, 0), Mathf.Clamp(rotate.eulerAngles.z, 0, 180));
			}
        }
    }
}


function Shoot()
{
        if (thingdelay == 0)
        {
            var bullet : Object = Instantiate(bulletPrefab,transform.Find("spawnPoint").position, Quaternion.identity);

            bullet.rigidbody.AddForce(transform.forward * 350);

            secondwait();
        }

}

and screenshot

Im going to change our 270 value on the y axis to zero and see if it helps

Ok question, you have a variable LookAtTarget declared at the top, but it’s never assigned in the code. You have a LookAtTarget2 that is assigned, but never used. Is that intentional? It looks like you changed your rotate variable, I think you had it right originally. Your eulerAngles might be a bit off too. I changed it to make sure there is 0 rotation around the x and y axes, and left the clamp for z. Give this a try:

if(LookAtTarget)
{
var forward = transform.TransformDirection(Vector3.forward);

//this is where the wanted rotation is calculated
var rotate = Quaternion.LookRotation(LookAtTarget.position - transform.position);

if(Quaternion.Angle(Quaternion.LookRotation(forward), rotate) < 70)
{
				//this spherically lerps the rotation from what it is to the wanted rotation
				transform.rotation = Quaternion.Slerp(transform.rotation, rotate, Time.deltaTime * damp);
		
				//this is the part I added, which clamps every variable between a minimum and maximum amount
				rotate.eulerAngles = Vector3(0, 0, Mathf.Clamp(rotate.eulerAngles.z, 0, 70));
}
}