Well I have a problem, when I press a letter the player must climb or descend (depend of input player on y) and if I keep the letter pressed it should stay still on the wall without move, here is the problem with mo gravity and when I press the key the player don't stay on the wall, tha player continues sliding slow this is for the gravity on the game, I can't desability the gravity because I make special jumps of the wall. so my velocity.y = 0 don't work. How can create a solution for this.
wallDirX = GetDirectionWallPlayer();
if (controller.collisions.left || controller.collisions.right)
{
stateWallPlayer.WallClimbing = true;
if (directionalInput.y > 0)
{
if (velocity.y < wallClimbUpSpeedMax)
{
velocity.y = wallClimbUpSpeedMax;
}
}
else if (directionalInput.y < 0)
{
if (velocity.y < -wallClimbDownSpeedMax)
{
velocity.y = -wallClimbDownSpeedMax;
}
}
else
{
velocity.y = 0;
}
}
Related
So my movement isn't instant. You accelerate and decelerate. I use two floats starting at 0, going to 1, to calculate my movement speed. Here it is:
private void Update()
{
float moveTowardsX = 0;
float moveTowardsY = 0;
// Adjust thrust to be below max Thrust
if(thrust >= maxThrust)
{
thrust = maxThrust;
}
// Calculates movement speed based on all variables
float changeRatePerSecond = 1 / timeFromZeroToMax * thrust * Time.deltaTime;
changeRatePerSecond /= weight / 1.5f;
if(onMobile == true)
{
// Checks for Input. If Input is detected, values get changed [MOBILE]
if(isMovingLeft == true && isMovingRight == false)
{
moveTowardsX = -1.0f;
}
else if(isMovingRight == true && isMovingLeft == false)
{
moveTowardsX = 1.0f;
}
if(isMovingUp == true && isMovingDown == false)
{
moveTowardsY = 1.0f;
}
else if(isMovingDown == true && isMovingUp == false)
{
moveTowardsY = -1.0f;
}
if(isRotatingLeft == true && isRotatingRight == false)
{
rotationsPerSecond++;
}
else if(isRotatingRight == true && isRotatingLeft == false)
{
rotationsPerSecond--;
}
}
Then I parse these values into my movement code and smooth them out:
void FixedUpdate()
{
// Makes values change smoothly
valueX = Mathf.MoveTowards(valueX, moveTowardsX, changeRatePerSecond);
valueY = Mathf.MoveTowards(valueY, moveTowardsY, changeRatePerSecond);
// Turn numbers into movement
rb.velocity = new Vector2(valueX * runSpeed, valueY * runSpeed);
}
The Problem is that when I run into a wall, the numbers don't decrease. And if I run into a wall standing still, the numbers increase. Here is a video linking to my problem too (Look at the top right): https://youtu.be/XRE9p0yo4GA
What could I implement to fix this?
I have 2 suggestions, either one should work:
Do a ground check. Platformers often perform ground checks to check that the player is on the ground. By doing a box cast, you can check if your character is adjacent to a wall in the direction of their movement, and if they are, do not let them move (or gain speed) in that direction.
Here is a video for how to do a ground check. I would recommend the box cast method here, since it would give you the most accurate results:
https://www.youtube.com/watch?v=c3iEl5AwUF8
Use the rb.velocity of the object in a direction divided by your character's maximum speed in place of your valueX and valueY. So, use:
rb.velocity.x / runSpeed
instead of
valueX
and the same for y. This would take into account anything that changes the velocity of the object outside this script, such as crashing into a wall, but also if your character is thrown by some effect you create later on.
im having trouble with the hand IK of a -recoil shoot animation- that is on an override layer in the animator. I have it set up so that when I aim(left trigger), it allows me to shoot with another button(right trigger). I have it so the weight (hand IK) increases to 1 (in the rig layer) when I aim and decreases to 0 when I let go of the aim button.
The problem is that if I shoot the gun (uses recoil gun animation) and let go of the aim button immediately afterwards, the animation will continue to play but the IK will go to 0 and the hands will look all messed up.
I've tried setting the IK hand weight to 1 when he fires the gun, so he'll still hold onto it, but it doesn't work since shoot is only true if aim is being held down.
So overall I fire the gun, he does a recoil animation, and when you let go of aim too early, the animation looks all messed up like he's waving to you from behind his back. Like it aborts the animation or something.
private void HandleMovementInput()
{
horizontalMovementInput = movementInput.x;
verticalMovementInput = movementInput.y;
animatorManager.HandleAnimatorValues(horizontalMovementInput, verticalMovementInput, runInput);
if (verticalMovementInput != 0 || horizontalMovementInput !=0) //running
{
if (aimingInput)
{
if (animatorManager.isAimingGunn == false)
{
shootInput = false;
}
}
}
if (animatorManager.isAimingGunn)
{
animatorManager.leftHandIK.weight = 1; // IK weight
animatorManager.rightHandIK.weight = 1;
horizontalMovementInput = 0f; // joystick
verticalMovementInput = 0f;
}
else if(animatorManager.isAimingGunn == false)
{
if(verticalMovementInput != 0 || horizontalMovementInput !=0) //running
{
animatorManager.leftHandIK.weight = 0;
}
animatorManager.leftHandIK.weight = 0; // IK weight
animatorManager.rightHandIK.weight = 0;
}
}
private void HandleShoot()
{
if (aimingInput) // must aim otherwise shootInput(right trigger on controller) wont work
{
if (shootInput)
{
shootInput = false;
playerManager.UseCurrentWeapon();
}
}
}
I was able to fix it. I used this code to tell the character to keep aiming if still in the current animation.This allows for the animation to finish before you set the Hand IK to 0.
if(animator.GetCurrentAnimatorStateInfo(1).IsName("Pistol_Shoot"))
{
aimingInput = true;
}
Also Due to it getting overly complicated I changed the aim cancel button to the top left trigger on the controller ( while aim is on the bottom left trigger).
I'm a beginner on Unity3D and I decided to create a 3D Tetris to start learning. Everything was fine so far, but I have a problem with collision detection.
https://gyazo.com/49fbf5798dc67a546c5e187fde8f6096
As you can see on this screen, the blue tetromino is not at the good place. This is due to the fact that the orange tetromino position in X is not precise (-2.9999).
Each block that makes up a tetromino has the tag "Block". The ground has the tag "Ground".
This is how I detect collisions in my OnCollisionEnter method.
if (collision.collider.tag == "Block" && !detectedBefore)
{
for (int k = 0; k < collision.contacts.Length; k++)
{
if (Vector3.Angle(collision.contacts[k].normal, validDirection) <= contactThreshold)
{
GetComponent<TetrominoMovement>().Snap();
GetComponent<TetrominoMovement>().enabled = false;
FindObjectOfType<Tetromino>().GenTetromino();
detectedBefore = true;
break;
}
}
}
if (collision.collider.tag == "Ground" && !detectedBefore)
{
GetComponent<TetrominoMovement>().Snap();
GetComponent<TetrominoMovement>().enabled = false;
FindObjectOfType<Tetromino>().GenTetromino();
detectedBefore = true;
}
Do you know how to get around this problem? Thank you in advance.
So, I want to implement dodging which is something like a dash in a direction. It works pretty simple - if you move in a direction and press the button the character dodges there. The velocity should not matter for this, so that the dodging speed is always the same, no matter if you are running or standing and then pressing a direction + dodging. I've got something that seems to work but there are still problems left. It seems like that diagonal dodging is a bit too far in comparison to horizontal/vertical dodging and I tried to fix this. But I'm still not sure if it worked or not. In practice the character dodges and stuff but something still seems off, like it works pretty good with a controller but sometimes it's still wacky when using keyboard after standing still and then using dodge. The thing is - I'm not sure if the code I have is the best I could have or if there are still problems.
A good example of how it should work would be the dodging in Rune Factory 4.
Edit: If the problem lies in the Input Settings I could show them.
if (IsDodging == false)
{
Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
if (input.sqrMagnitude > 1) input.Normalize();
if (Input.GetButtonDown("Jump"))
{
// Jumping stuff I blended out
}
else if (Input.GetButtonDown("Block/Dodge") && input.x != 0 || Input.GetButtonDown("Block/Dodge") && input.z != 0) // To activate dodging
{
if (Time.time > Time_Start + DodgeCooldown) // Checks the cooldown
{
Time_Start = Time.time;
IsDodging = true;
dodge_direction = input;
if (dodge_direction.x > 0) { dodge_direction.x = 1; } // To fixate the distance traveled when dodging while ignoring how fast you are
if (dodge_direction.z > 0) { dodge_direction.z = 1; }
if (dodge_direction.x > 0 && dodge_direction.z > 0) { dodge_direction.Normalize(); } // To prevent diagonal dodging distance from becoming too big
}
}
else
{
// Walk.
transform.position += input * run_speed * Time.deltaTime;
}
}
else
{
transform.position += dodge_direction * dodge_distance;
distance_traveled += Vector3.Distance(transform.position, dodge_direction * dodge_distance) * Time.deltaTime;
if (distance_traveled > dodge_distance)
{
IsDodging = false;
dodge_direction = Vector3.zero;
distance_traveled = 0;
}
}
I'm making a simple 2d pong game. I finished everything now the only problem I have is that the GUI exit or restart button clicks are being recorded when it should not be recorded. Lets say both players fingers are on the screen and they move them so one players finger is 25 units from the button on the x axis and the others -25. These 2 finger touches somehow record as one finger touch in the middle of the screen where my exit button is and the app closes. I have 2 scripts for player controls one for Player 1 and other for player 2
var speed : float = 10;
function Update () {
if (Input.touchCount > 0)
{
var touchDeltaPos:Vector2 = Input.GetTouch(0).position;
if(Input.touchCount>1)
var touchDeltaPos2:Vector2 = Input.GetTouch(1).position;
if(touchDeltaPos.x<Screen.width/2)
{
if(touchDeltaPos.y > Screen.height/2)
{
rigidbody2D.velocity.y = 1*speed;
}
else rigidbody2D.velocity.y = -1*speed;
}
else if(touchDeltaPos2.x<Screen.width/2&&Input.touchCount>1)
{
if(touchDeltaPos2.y > Screen.height/2)
{
rigidbody2D.velocity.y = 1*speed;
}
else rigidbody2D.velocity.y = -1*speed;
}
}
if (Input.touchCount == 0)
rigidbody2D.velocity.y = 0;
rigidbody2D.velocity.x=0;
}
I don't know where your buttons are, but in any case how about making a buffer so it won't be touched by accident like
width = Screen.width/2 - 100
or minus 100 whichever works, the buffer is supposed to take in account the width and height of the finger as well
EDIT
When I say buffer, it means a temporary storage like a variable. So for the code you could do:
var buffer:int = 100;
(touchDeltaPos.x < Screen.width/2 - buffer)
Now why do this? Well, the buffer gives more room for the player's playing area from the exit button.