I have implemented a player movement and jump in my game. I also attached a run and jump animation to animator. However, the jump animation does not perfectly match with the player vertical movement. How can I match them perfectly?
Thanks in advance,
void Control()
{
if (charController.isGrounded)
{
float h = Joystick.GetHorizontalAxis("MyJoystick");
float v = Joystick.GetVerticalAxis("MyJoystick");
moveDirection = new Vector3(h, 0.0f, v);
moveDirection *= (speed * sprint);
anim.SetFloat("WalkSpeed", moveDirection.magnitude);
if (moveDirection.magnitude > 0.5)
{
anim.SetFloat("WalkSpeed", moveDirection.magnitude / speed);
anim.SetFloat("Walk", 1.0f);
transform.forward = moveDirection;
}
else if (moveDirection.magnitude > 0 && moveDirection.magnitude < 0.5)
{
anim.SetFloat("WalkSpeed", moveDirection.magnitude / (speed * 0.5f));
anim.SetFloat("Walk", 0.5f);
transform.forward = moveDirection;
}
else if (moveDirection.magnitude == 0)
{
anim.SetFloat("Walk", 0f);
}
if (Input.GetKeyDown("space"))
{
moveDirection.y = jumpSpeed;
anim.SetTrigger("Jump");
}
}
moveDirection.y -= gravity * Time.deltaTime;
charController.Move(moveDirection * Time.deltaTime);
}
There is an option in the Animator component to do what you want.
Here is a link that describes it in more details.
Related
So, I was testing my scripts and i wanted my player to jump with character controller and i am having a problem with it.
Problem
```
public CharacterController control;
public float playerSpeed;
public float jumpSpeed;
void Start()
{
playerSpeed = 6.0f;
jumpSpeed = 50;
}
void Update()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
Vector3 move = new Vector3 (h, 0, v);
Vector3 velocity = move * playerSpeed;
if (control.isGrounded && Input.GetKey(KeyCode.Space))
{
velocity.y += jumpSpeed; // velocity.y = jumpSpeed; tried both
}
else
{
velocity += Physics.gravity * Time.deltaTime;
}
control.Move(velocity * Time.deltaTime);
}
}```
Here's my unity screen and code above.
The problem is when i press jump it does jump but it's position goes to 2.068, i.e it jumps to low and when gravity is activated it comes down to slow, it takes around 6 seconds to come to its initial position.
I even tried to add a parent object to it so that it may change, but it does the same to it.
if (control.isGrounded && Input.GetKey(KeyCode.Space))
{
// first just try this
velocity.y += jumpSpeed * Time.deltaTime;
}
else
{
velocity.y -= Physics.gravity * Time.deltaTime;
}
and if it is not working
Vector3 move = new Vector3 (h, 0, 0);
Vector3 jump = new Vector3 (0, 0, v);
Vector3 _velocityMove = move * playerSpeed;
Vector3 _velocityJump = jump* jumpSpeed;
if (control.isGrounded && Input.GetKey(KeyCode.Space))
{
velocity.y += _velocityJump ;//and you can add ' * Time.deltaTime '
}
else
{
velocity += Physics.gravity * Time.deltaTime;
}
control.Move(_velocityMove * Time.deltaTime);
ohk so I tweaked some of my code and instead of declaring velocity.y in the condition of if the player is grounded , i declared outside the condition and change the value of variable in condition.
velocity.y = jumpSpeed;
if (control.isGrounded && Input.GetKey(KeyCode.Space))
{
jumpSpeed = 10;
}
else
{
jumpSpeed += Physics.gravity.y * Time.deltaTime;
}
This seems to do the trick and my player can jump nicely.
wont let me run and jump at the same time, movement works fine but when i sprint jump isnt registered i tried a few things but nothing was successful
the character is a capsule and camera
this is the relevant code:
void UpdateMovement()
{
Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
targetDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);
if(controller.isGrounded)
{
if(Input.GetKeyDown(KeyCode.Space))
{
velocityY = 10.0f;
Debug.Log("Jump");
}
else
{
velocityY = 0.0f;
}
}
speed = walkSpeed;
if(Input.GetKey(KeyCode.LeftShift))
{
//Debug.Log("Sprint");
speed = walkSpeed * sprintMultiplier;
}
velocityY += gravity * Time.deltaTime;
Vector3 velocity = transform.forward * currentDir.y * speed + transform.right * currentDir.x * speed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
//Debug.Log(speed);
}
thank you in advance for any help
Basically I want to make bouncing stick and rotate control, with the left-right button.i'm facing an issue that the rotate not good as I expected because it won't follow my button like being affected by something after bouncing,
I'm using 2d physics material with friction = 1 and Bounciness = 0.9797 for perfect bouncing also attached to rigidbody2d.
I don't know, should I attach it on collider?
here my Player control Script:
public Rigidbody2D r2d;
public float vertical;
public float horizontal;
public Joystick joystick;
private void Start() {
r2d = gameObject.GetComponent < Rigidbody2D > ();
joystick = FindObjectOfType < Joystick > ();
}
private void Update() {
Movement();
}
public void Movement() {
r2d.velocity = r2d.velocity.normalized * 7f;
//horizontal = joystick.Horizontal;
//vertical = joystick.Vertical;
//if (horizontal == 0 && vertical == 0)
//{
// Vector3 curRot = transform.localEulerAngles;
// Vector3 homeRot = transform.localEulerAngles;
// transform.localEulerAngles = Vector3.Slerp(curRot, homeRot, Time.deltaTime * 2);
//}
//else
//{
// transform.localEulerAngles = new Vector3(0f, 0f, Mathf.Atan2(horizontal, vertical) * -180 / Mathf.PI);
//}
}
public Vector3 target;
public float rotationSpeed = 10f;
public float offset = 5;
public void turnLeft() {
Vector3 dir = target - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(new Vector3(0, 0, angle + offset));
transform.rotation = Quaternion.Slerp(transform.rotation, -rotation, rotationSpeed * Time.deltaTime);
}
public void turnRight() {
Vector3 dir = target - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(new Vector3(0, 0, angle + offset));
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime);
}
Whenever there is a Rigidbody/Rigidbody2D involved you do not want to manipulate anything via the .transform component!
This breaks the physics, collision detection and leads to strange movements basically the transform "fighting" against physics for priority.
What you rather want to do would be e.g. adjusting the Rigidbody2D.angularVelocity
public void turnLeft()
{
// Note that Time.deltaTime only makes sense if this is actually called every frame!
r2d.angularVelocity -= rotationSpeed * Time.deltaTime;
}
public void turnRight()
{
r2d.angularVelocity += rotationSpeed * Time.deltaTime;
}
I am developing endless runner game like subway surfer in Unity.
I want to move my player, smoothly on swipe left or right.
How can do it?
Here is my code:
using UnityEngine;
using System.Collections;
public class SwipeScript3 : MonoBehaviour {
private Touch initialTouch = new Touch();
private float distance = 0;
private bool hasSwiped = false;
//Quaternion targetx = Quaternion.Euler(0, -3f, 0);
//Quaternion targety = Quaternion.Euler(0, 3f, 0);
void FixedUpdate()
{
foreach(Touch t in Input.touches)
{
if (t.phase == TouchPhase.Began)
{
initialTouch = t;
}
else if (t.phase == TouchPhase.Moved && !hasSwiped)
{
float deltaX = initialTouch.position.x - t.position.x;
float deltaY = initialTouch.position.y - t.position.y;
distance = Mathf.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
bool swipedSideways = Mathf.Abs(deltaX) > Mathf.Abs(deltaY);
if (distance > 50f)
{
if (swipedSideways && deltaX > 0) //swiped left
{
//transform.rotation = Quaternion.Slerp (transform.rotation, targetx, Time.deltaTime * 0.8f);
this.transform.Rotate(new Vector3(0, -3f, 0)*Time.deltaTime);
//transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x+5f,transform.position.y,transform.position.z),Time.deltaTime*2f );
transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x - 5f, transform.position.y, transform.position.z), Time.deltaTime * 5f);
}
else if (swipedSideways && deltaX <= 0) //swiped right
{
//transform.rotation = Quaternion.Slerp (transform.rotation, targety, Time.deltaTime * 0.8f);
this.transform.Rotate(new Vector3(0, 3f, 0)*Time.deltaTime);
//transform.position = Vector3.Lerp (transform.position, new Vector3 (transform.position.x - 5f, transform.position.y, transform.position.z), Time.deltaTime * f);
transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x+5f,transform.position.y,transform.position.z),Time.deltaTime*5f );
}
else if (!swipedSideways && deltaY > 0) //swiped down
{
//this.transform.Rotate(new Vector3(0, 2f, 0));
transform.position = Vector3.Lerp (transform.position,new Vector3(transform.position.x,transform.position.y,transform.position.z-5f),Time.deltaTime*2f );
}
else if (!swipedSideways && deltaY <= 0) //swiped up
{
this.GetComponent<Rigidbody>().velocity = new Vector3(this.GetComponent<Rigidbody>().velocity.x, 0, this.GetComponent<Rigidbody>().velocity.z);
this.GetComponent<Rigidbody>().AddForce(new Vector3(0, 400f, 0));
Debug.Log ("Swiped Up");
}
hasSwiped = true;
}
}
else if (t.phase == TouchPhase.Ended)
{
initialTouch = new Touch();
hasSwiped = false;
}
}
}
}
You could use Vector3.Slerp(Vector3 StartPosition, Vector3 DestinationPosition, float Number)
Number is between 0 and 1 and it indicates where will be the position of your object between StartPosition and DestinationPosition.
Lets say Number = 0.0f;: your object will be at StartPosition.
If Number = 0.5f;: your object will be between StartPosition and DestinationPosition.
You need to increase the Number value from 0 to 1 when swipe action is performed.
The faster you increase the "Number" value, the faster your object will move towards Destination.
You should set you StartPosition once when the swipe action begins, not give your transform.position repeatedly in your Vector3.Slerp() function.
You can find an example here in Unity Docs.
Hope this helps! Cheers!
I have this code below and works in Keyboard, but does not works with touch.
Quaternion rot = transform.rotation; float z = rot.eulerAngles.z;
z-= Input.GetAxis("Horizontal") * rotSpeed * Time.deltaTime;
rot = Quaternion.Euler( 0, 0, z );
transform.rotation = rot;
I need that code above works on touch, how to do this?
Maybe you should read the Api for input of Unity Scripting http://docs.unity3d.com/ScriptReference/Input.html
you could use the getTouch method to rotate the object
here the documentation
http://docs.unity3d.com/ScriptReference/Input.GetTouch.html
you can use the delta for draging or the Position for rotating the Object
so it would be like this not sure its working it should work with dragging
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
z-=touchDeltaPosition.x * rotSpeed * Time.deltaTime;
rot = Quaternion.Euler( 0, 0, z );
}
It should be nearly the same as above but instead of the x axis which is the horizontal one we are using the y axis for the vertical one this code is also with dragging
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) {
Vector2 touchDeltaPosition = Input.GetTouch(0).deltaPosition;
Vector3 pos = transform.position;
Vector3 velocity = new Vector3(0, touchDeltaPoition.y * maxSpeed * Time.deltaTime, 0);
pos += rot * velocity;
}