2D- Scale&rotate Object between two points - calling math wizards

Hi Guys,

Basically i need a characters tongue to shoot out towards a point on the screen the player clicks. After the click an object will shoot towards that point and on arrival, immediately move back towards the player. I have a sprite that is the graphics of the tongue and i need it to scale and rotate to the tongue shoot object as the object moves the screen point.

I’m having issues coding the scale and the rotation of the tongue sprite object, particularly the rotation.

Here’s the code i have so far:

function Update () {

	var pos1 = GameObject.Find ("Player").transform.position;
	var pos2 = GameObject.Find ("TongueHitBox").transform.position;
	
	var angle = Mathf.Atan2(pos2.y , pos2.x ) * Mathf.Rad2Deg;
	transform.position = pos1;
	
	if (pos2 != pos1) {

	     var v3 = pos2 - pos1;
         transform.position = pos1;
         transform.localScale.x = v3.magnitude/3.0f;
         transform.rotation = Quaternion.Euler (new Vector3 (0, 0, angle));
	}
	
}

At the moment the object scales sort of correctly, a little bit too long but I think I can fix that… It’s more the rotation. When I shoot the tongue it spins around to a different direction depending on how long it is.

I’ve pretty much formed this entire script from snippets of other answers. I’m no math wizard, and having experimented with different values I was left no choice but to seek help!

Any help would be much appreciated!

Regards,
Genaza

Anyone else got an idea?

1 Answer

1

I’m imaging the tongue of a frog shooting towards a fly. Typically I want to do the setup so that the code is as simple as possible. So you need to do the following:

  • Setup the sprite so that the front of the tongue points right in the sprite when the rotation is (0,0,0).
  • Set the pivot for the sprite to be ‘Left’.
  • Figure out the real-world width of the sprite when the scale is (1,1,1). You can do that first select the texture for the sprite and recording the ‘Pixels To Units’ setting. Next record the pixel width of the sprite. Use both pieces to get the real-world width (I’m calling it objectWidth).

Then to rotate and scale, you can do:

 var dir = target - transform.position;
 var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
 transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
 transform.localScale.x = dir.magnitude / objectWidth;

Where ‘target’ is a Vector3 of the position you want the tongue to hit.

hey, Thanks so much for your reply I can see already that its starting to work after implementing your code. I am having problems with the scale now though- The pixel width of the sprite is 170, and the units are the default, 100. So should the objectWidth be 1.7? when i click to shoot the tongue the scale either over shoots the point and when i shoot close to the play or fails to reach when i shoot really far. If i shoot halfway it hits. Any idea how to approach this one? thanks again mate, G

As a guess, I'll bet the tongue is a child of another object, and that parent object has a non-uniform scale. True?

Its a standalone game object that sits in the game world unattached to anything. When I play the game the code will set its position to the players mouth via update(), so that as the player is moving the pivot point will always stay on the player.

Still cant seem to figure it out =/ really need some help!

Something strange is going on here. As an experiment, replace your sprite with a Quad with your texture. The world size of a Quad is 1 x 1, so your calculation: transform.localScale.x = dir.magnitude There may be reasons to go back to a sprite, but by testing with a Quad, you will see if the issue is related to a Sprite, or something in your code. If the Quad also has problems, then post your code.