How to know end coordinates of animation in Unity? - unity3d

I want to know coordinates of root bone in the end of animation in Unity. I tried to put unit with Animator controller programmaticaly to the scene, play animation and execute Update() several times. But coordinates are slightly different from the real.
Is there method to know accurate coordinates in the end of animation?
Upd. This code should work as it should, but it doesnt work accurately:
animator.transform.position = new Vector3(0, 0, 0);
animator.transform.rotation = Quaternion.Euler(0, 0, 0);
animator.Play(_hashName, 0, 0);
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
duration = stateInfo.length;
float t = 0;
float delta = 0.01f;
while (t < duration)
{
animator.Update(delta);
t += delta;
}
Vector3 endCoords = animator.transform.position;

Finally I found the brilliant answer on Unity3d forum.
animator.SetTarget(AvatarTarget.Root, 1.0f);
animator.Update(0);
Vector3 position = animator.targetPosition;
It works perfectly.

Related

Why does Camera.transform.Rotate(X, Y, 0) change Z?

I would like to rotate a camera using a joystick.
The camera should rotate up and down and left and right, but it should not rotate around z.
I have tried the following lines:
float speed = 3.0f;
float yRotation = speed * fY;
float xRotation = speed * fX;
camera.transform.Rotate(-yRotation, xRotation, 0.0f);
It seems to work, but after a few joystick movements, I can see that the camera rotation's z-value has changed, and it looks like this:
Does anybody see an obvious mistake in my code, or is the problem located somewhere else?
Ok, here's how to do it, I have to use eulerAngles:
yaw += speedH * fX;
pitch -= speedV * fY;
pitch = Mathf.Clamp(pitch, -20, 30);
camera.transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);

How to zoom an slide the the screen in Unity?

In my 2D Unity Project i had to use a zooming script in my main camera. Zooming works however, the camera just focuses on the middle of the scene. But I want to see the other parts of the scene which remain out of the field of view of camera. So, what should I add to my script in order to move over the scene when it's zoomed?
Here is my script for zooming. I threw it into the main camera.
This picture is the actual scene before zooming:
And this one is after zooming. Please pay attention that it directly focuses on the geometrical centre of the scene and doesn't allow me to move to another point on the scene(right, left, up, down).
I don't know if you're looking to drag whilst zooming or use the mouse position be the center point of the zoom.
If it's the latter, you can do something like this;
float zoomSpeed = 5f;
void Update()
{
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit point; Physics.Raycast(ray, out point, 25); Vector3 Scrolldirection = ray.GetPoint(5);
float step = zoomSpeed * Time.deltaTime;
mycamera.transform.position = Vector3.MoveTowards(transform.position, Scrolldirection, Input.GetAxis("Mouse ScrollWheel") * step);
}
}

Unity track object rotation

I have several object rotating by itself in FixedUpdate().
Now I need to track rotation of one object, lets call it objX. Rotation goes only from 0 to 360 when I retrieve it. Is it possible to get rotation after 360 degrees?
For example when I use something like
float x = objX.transform.rotation.z;
variable x should be 560 degrees.
Is something like that possible?
Here is the way to track rotation.
Vector3 mouseClickPos;
float angle;
float lastAngle;
int fullRotations;
public float realAngle;
void FixedUpdate(){
mouseClickPos = Input.mousePosition;
Vector3 dir = mouseClickPos - Camera.main.WorldToScreenPoint(transform.position);
angle = Mathf.Atan2(dir.y,dir.x) * Mathf.Rad2Deg;
angle-=90;
if(lastAngle - angle > 270){
fullRotations ++;
}else if(angle - lastAngle > 270){
fullRotations --;
}
Debug.Log(360*fullRotations + angle);
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 6);
lastAngle = angle;
}

CCMoveTo doesn't get the updated player postition.....(iphone,cocos2d)

I'm adding an enemy like this:
-(void)addEnemy {
if ([spawnedEnemies count] < 25) {
CCSprite* sprite = [CCSprite spriteWithFile:#"white.png"];
float randomX = arc4random() % 480;
float randomY = arc4random() % 320;
sprite.position = ccp(randomX,randomY);
[spawnedEnemies addObject:sprite];
[self addChild:sprite];
[sprite runAction:[CCMoveTo actionWithDuration:5 position:player.position]];
} }
but if my player moves the sprite still moves to the last player position...
because of that i tried this in my tick:
-(void)tick:(ccTime)delta {
for (CCSprite *sp in spawnedEnemies) {
[sp stopAllActions];
[sp runAction:[CCMoveTo actionWithDuration:5
position:player.position]];
} }
but the enemies will only move if i stop moving (there just moving reallllllllyyyyyyyyy slow because every time i move it calls [sp stopAllActions]
What should I do now?
EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:*EDIT:
Now I'm doing this and the enemies are moving to the player even if the player is moving
but there's a problem: the nearer the enemy (is to the player) the slower they are moving...
How to solve this?
//function to apply a velocity to a position with delta
static CGPoint applyVelocity(CGPoint velocity, CGPoint position, float delta){
return CGPointMake(position.x + velocity.x * delta, position.y + velocity.y * delta);
}
-(void)tick:(ccTime)delta {
for (CCSprite *sp in spawnedEnemies) {
CGPoint m = ccpSub(player.position, sp.position);
sp.position = applyVelocity(m, sp.position, 1.0/60.0f);
}
}
I have four ideas:
Schedule a new update selector with a lower frequency and move the enemies in that method: [self schedule:#selector(moveEnemies) interval:0.1];
Only move the enemies when the player.position changes, maybe in your ccTouchesMoved-method.
Instead of using CCActions, set the position of the sprite directly, you need to do some vector-computations.
Use a physics-engine like Box2D (included in Cocos2D SDK). Then you can simply apply a force to each enemy to the direction of the player in each step.
EDIT:
In order to move the enemies with constant velocity, normalize the velocity vector m:
m = ccpMult(ccpNormalize(m), kSpeed);
kSpeed is a constant float value to adjust the speed.
Hope that helps...

Iphone, objective-c how to make a Jump method for a platformer

I have this IBAction that is suppose to make a character onscreen jump, however when its called it just moves the character up once, then each call after that the character just moves down more and more. This function should just be called then the character would 'jump' up and then fall straight down off the screen since i havent put in any collision with the ground. ANy suggestions why this is happening? tim is the name of my UIImageView that holds the chracater, btw.
-(IBAction)Jump:(id)sender
{
int jumpSpeed = JumpSpeedLimit;
CGPoint newCenter = tim.center;
if(!mainJumping){
//then start jumping
mainJumping = TRUE;
jumpSpeed = JumpSpeedLimit*-1;
newCenter.x -= jumpSpeed;
tim.center = newCenter;
} else {
//then continue jumping if already in the air
//crazy math that I won't explain
if(jumpSpeed < 0){
jumpSpeed *= 1 - JumpSpeedLimit/75;
if(jumpSpeed > -JumpSpeedLimit/5){
jumpSpeed *= -1;
}
}
if(jumpSpeed > 0 && jumpSpeed <= JumpSpeedLimit){
jumpSpeed *= 1 + JumpSpeedLimit/50;
}
newCenter = tim.center;
newCenter.x -= jumpSpeed;
tim.center = newCenter;
/*
//if hits the floor, then stop jumping
if(tim.center.x >= 360 - tim.bounds.size.height){
mainJumping = FALSE;
newCenter = tim.center;
newCenter.x = 360 - tim.bounds.size.height;
tim.center = newCenter;
}*/
}
}
You are fundamentally designing this wrong. You want it to be that pressing the "jump" button sets some sort of flag, and then in your game engine code, process that flag.
Sounds like a job for CoreAnimation more than one for a repeated call to an IBAction. Create an animation path on which your view should move and add a timing function to give the gravity acceleration effect, something along the lines of the animation cookbook sample: http://developer.apple.com/documentation/GraphicsImaging/Conceptual/CoreAnimation_Cookbook/Articles/Timing.html#//apple_ref/doc/uid/TP40006077-SW1