Gun doesn't zoom out - unity3d

I have a problem with my weapon's zoom script. I have been stuck on this for hours now. I have visited many sites in hope of solving my problem, but to no avail!
I don't think the problem has anything to do with Unity, but with my script instead. The code works perfectly fine when I zoom in (holding right click), but doesn't zoom out when I release right click and the animation has finished playing. It stays zoomed in! Once the animation has ended and I release right click, the weapon stays zoomed in.
The zoomIn() function works fine, but the gun doesn't zoom out during the zoomOut() function. I know the zoomOut() function works fine, because the camera's FOV resets back to what it was(60), but the animation doesn't rewind (maybe because it's stopped?). I have tried changing the animation's time, changing its speed and rewinding and many other things. If I am fully zoomed in and I zoom in again (I right click once the animation has finished playing), the gun jumps back to its original position and plays the zoom animation again.
The script makes perfect sense to me, so I don't know what is going on or how to fix it!
Below is my code:
#pragma strict
var arms : GameObject;
var zoomed : boolean = false;
function Update () {
if (Input.GetMouseButton(1) && zoomed == false) {
zoomIn();
}
if (!Input.GetMouseButton(1)) {
zoomOut();
}
}
function zoomIn() {
if (Input.GetMouseButton(1)) {
animation.Play("zoom");
camera.main.fieldOfView = 50;
arms.active = false;
yield WaitForSeconds(0.3);
zoomed = true;
}
}
function zoomOut() {
zoomed = false;
if (zoomed == false) {
animation.Rewind("zoom");
camera.main.fieldOfView = 60;
arms.active = true;
}
}
Please help
Thanks in advance

You're trying to use Animation.Rewind. This only rewinds the animation, but does not (AFAIK) play the animation in reverse
Try this out instead.
Replace your zoomIn() and zoomOut() methods with the below
function zoomIn() {
//A speed of 1 means that the animation will play at 1x in the positive timeline
animation["zoom"].speed = 1;
//Set the time to the FIRST key frame.
animation["zoom"].time = 0;
animation.Play("zoom");
camera.main.fieldOfView = 50;
arms.active = false;
yield WaitForSeconds(0.3);
zoomed = true;
}
function zoomOut() {
zoomed = false;
//A speed of -1 means that the animation will play the animation at 1x speed in reverse
animation["zoom"].speed = -1;
//Set the time to the LAST key frame. Replace the number "10" with the time of your last keyframe
animation["zoom"].time = 10;
animation.Play("zoom");
camera.main.fieldOfView = 60;
arms.active = true;
}

Related

How to register a fall from height in unity 2D

So i'm working on a 2D game, first stage is a platformer so i'm trying to make it look nicer. I added a particle system with dust, so in case he falls down from height animation should be played. How do i register a fall from height to play the animation?
You can play animation on collision with the ground collider, when player's falling velocity is higher than 0. Using specific positive value may be nicer, cos it's gonna look like only achieving enough speed will spread dust.
I can see another way of doing this, but it takes more calculations:
To define the last position and current position of Y coordinates of the player.
If it is going down currentPos < lastPos
If it is going up currentPos > lastPos
public GameObject player;
public GameObject particleDust;
Vector3 lastPos;
Vector3 currentPos;
float _time = 0;
private bool up = false;
private bool down = false;
private bool equal = false;
void Awake()
{
lastPos = player.transform.position;
}
void Update()
{
//assign player's position to current position
currentPos = player.transform.position;
//going up
if (lastPos.y < currentPos.y)
{
up = true;
down = false;
equal = false;
}
//going down
else if (lastPos.y > currentPos.y)
{
up = false;
down = true;
equal = false;
}
//same level
else if (lastPos.y == currentPos.y)
{
equal = true;
}
if (down == true && equal == true)
{
particleDust.Play();
}
lastPos = currentPos;
}
You can define the up and down functions to define player's movement with bool.
When the direction down is True and lastPos = currentPos
then it means that he was going down and he stopped because the player hit the ground.
I choose this option without using colliders because it can be versatile and be used on every level without adding new things.
I assume this will work but it need more things, i hope this will get you started.
(If i said something wrong please correct me , it help me improve too, thank you!)
Just thinking of how to detect falls from a specific height, I think this should work just fine in most cases:
private float startingHeight = 0.0f;
private bool grounded = true;
private bool landed = false;
//this is the distance the player needs to fall before dust shows up
private float fallingDist = 5.0f;
private void Start()
{
startingHeight = transform.position.y;
}
private void Update()
{
if(grounded) //set this to false when not colliding with the ground
{
startingHeight = transform.position.y;
}
else if(landed) //set this to true when hitting the ground while grounded is false
{
landed = false;
if((startingHeight - transform.position.y) >= fallingDist)
{
//trigger dust particles or animation
}
}
}

Get touch location on screen for perspective Camera

As the title of the question goes, I am trying to get the touch location on screen for perspective Camera.
Pretty much when I click a button my character has the ability to "teleport" or change it's location/transform to the same area of my finger with the Z axis hard coded.
Now I stress "Perspective Camera" because when the camera is Orthographic the following works fine.
if (canTeleport == true) {
if (Input.GetMouseButtonDown (0)) {
//fingerPos = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position);
// fingerPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //Desktop
// transform.position = fingerPos;
// Debug.Log (transform.position);
//Needed for Mouse
//fingerPos = Input.mousePosition;
//Needed for Finger
fingerPos = Input.GetTouch(0).position;
//Oth Camera
fingerPos.z = -36.1f;
fingerPos = Camera.main.ScreenToWorldPoint (fingerPos);
//Pers Camera
// Vector3 screenPosition= new Vector3(0,0,0);
//fingerPos = GetWorldPositionOnPlane(screenPosition, -36.1f);
fingerPos.z = -36.1f;
transform.position = fingerPos;
Debug.Log (transform.position);
canTeleport = false;
}
}
But when in perspective it does not, I understand 2D and 3D space is different but only thing that should matter is the Z axis and i'm hard codding the Z axis so im not sure why it does not work.
any help offered will be appreciated.
thank you.
Update
The circle area is where I touched and as you can see my sprite went to the location on the canvas not in the game world.

Make character only can jump when touching the ground

I want to make a character jump only when he is with his feet on the ground. I don't want him to be able to 'air-jump', so I came with this solution:
if (JumpButtonPressed()) {
if (GetComponent<BoxCollider2D>().IsTouchingLayers(LayerMask.NameToLayer("Ground"))) {
velocity.y = jumpForce;
}
}
The idea is that only when in touch with a "Ground" Layer, it can jump. But this is what happens:
It doesnt work just on his foot. If he is touching a platform by the side, it can jump as well. What could I do?
Use circle overlap with a position vector which is placed at the bottom on the player. Detect layer from there.
You may need to use different layer for platform if you want to write features like ledge grab, jump.
Create a bool isJumping and set it to true while in the air. When it reaches the ground - set it to false. Smth like that if your snippet is in Update():
bool isJumping = false;
if (JumpButtonPressed() && !isJumping) {
if (GetComponent<BoxCollider2D>().IsTouchingLayers(LayerMask.NameToLayer("Ground"))) {
velocity.y = jumpForce;
isJumping = true;
}
}
if (GetComponent<BoxCollider2D>().IsTouchingLayers(LayerMask.NameToLayer("Ground"))) {
isJumping = false;
}

Unity changing friction from code not working (2D)

I want to change a collider's physic's material from code, I use the code below. I see the material's friction changing in the inspector, however the collider behaves as if the friction wouldn't change.
void checkOnGround() {
Transform t;
foreach(Collider2D c in collidingTiles) {
t = c.transform;
if(t.position.y - transform.position.y < -Misc.TILE_SIZE * 0.75f) {
onGround = true;
myCollider.sharedMaterial.friction = 0.8f;
return;
}
}
onGround = false;
myCollider.sharedMaterial.friction = 0f;
return;
}
There are knowed Unity bug.
You can disable/enable your collider to got the material changed applied, and a little flick texture sometimes.

Iphone - CGPointIntersectsRect Collision Problem?

The problem is when the player collides with the blackB the player doesn't stop. It slowly continues through the blackB. The IBAction is being used with a game loop. I need a way to freeze the player completely when it collides with the blackB. Any help is welcome, I am a beginner programmer. Thank you!
player and blackB are both UIImageViews
- (IBAction)right
{
direction = kright;
if (direction == kright)
{
rightMovement = CGPointMake(kMovement,0);
blockVelocity.x += rightMovement.x;
player.center = CGPointMake(player.center.x + blockVelocity.x,player.center.y);
if(CGRectIntersectsRect(player.frame, blackB.frame))
{
if(player.center.x < blackB.center.x)
{
if(blockVelocity.x > 0)
{blockVelocity.x = zero;
}
}
}
}
}
Sort of a sloppy answer, but in pseudo code:
-(IBAction)right {
if (playerCanMove==1) {
//move player
}
}
Set playerCanMove to 1 when the game loads, and set it to 0 on collision.