Input.GetAxis for android - c#

I'm creating a maze game and curently i am having delays with my android controls. I have lade the computer controls to move front and to turn left and right and to jump using input.getaxis. Now on android i created buttons that work but not how i want. It can jump and turn how i want but it doesnt move properly. There are 2 problems one is that when i click it moves a bit and then i need to click again but i want to hold and it will move continuously and second problem is that when i turn the character doesnt move the corect way it goes always on x axis with input.getaxis everything works perfectly but i need something that will work for androdid like that, here is my code:
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public float speed;
public float speedj;
Rigidbody rb;
static Animator anim;
void Start()
{
rb = GetComponent<Rigidbody>();
anim = GetComponent<Animator>();
}
public void Walk ()
{
anim.SetTrigger ("Walk");
rb.velocity = new Vector3 (0,0,7f);
}
public void Left ()
{
transform.Rotate(0,-90f,0);
}
public void Right ()
{
transform.Rotate(0,90f,0);
}
public void Jump ()
{
anim.SetTrigger ("Jump");
rb.velocity = new Vector3 (0,4f,0);
}
public void StopVelocity ()
{
rb.velocity = Vector3.zero;
transform.Translate(0,0,0);
}
void FixedUpdate ()
{
float x = Input.GetAxis ("Horizontal") * Time.deltaTime * speed;
float z = Input.GetAxis ("Vertical") * Time.deltaTime * speed;
transform.Translate (0,0,z);
transform.Rotate (0,x,0);
if(Input.GetKey(KeyCode.Space))
{
anim.SetTrigger ("Jump");
rb.velocity = new Vector3 (0,speedj,0);
}
}
}
So this is it the fixedUpdate functionis for the computer the others are for buttons for android i am using event trigger for pointer up and down events pleasehelp me to change the code so that it will work for android like it works with Input.getAxis for computer thanks!

"when i click it moves a bit and then i need to click again but i want to hold and it will move continuously."
Using the EventTrigger here should be the optimal way. Check out OnPointerDown(); the function should be called for every frame. You should attach the EventTrigger to the button for it to work on mobiles.
"when i turn the character doesnt move the corect way."
Try moving using your Local Transforms Forward. Namely Transform.Forward(). It will allow you to move forward into the direction you set before, the Forward is always a Normalized Vector3. Moving in the way you are will use the world axis, your rotation wont matter at all.

Related

Cannot get rb.velocity to work when making a jumping script in unity 2D

I'm trying to use rb.velocity in unity to make my 2D character jump. I have used Debug.Log() to check if unity registers the input, and it does. But it does not affect my character in game when pressing the button. Here's the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f;
public float jumpForce = 7f;
public Rigidbody2D rb;
Vector2 movement;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Space was pressed");
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
}
}
}
I have tried replacing the values with all sorts of things in the Vector2, but to no avail.
If your rigidbody is using gravity then in this case a small vertical velocity of 7f would be negated by gravity very quickly (less than a second). You can check this in the physics settings of your project or with Rigidbody.useGravity.
If you intend to use gravity then it is recommended to use Rigidbody.AddForce to add an upward force to the object and let gravity bring it back down - example SO answer here.
If you want to turn off gravity and not use AddForce then it would be best to either use Rigidbody.MovePosition or set Rigidbody.velocity, but not both.
For example:
void Update() {
movement = new Vector2(Input.GetAxisRaw("Horizontal") * moveSpeed, movement.y);
}
void FixedUpdate() {
if (Input.GetKeyDown(KeyCode.Space)) {
movement.y = jumpForce;
}
rb.velocity = movement;
}
But in that case you would have to manually figure out when the jump is complete and set a downwards velocity to bring it back to the ground yourself. If you want the easiest and most natural solution, then leveraging Unity's built-in physics with gravity and forces would be best.
Honestly, your code looks fine. I would move the Input.GetKeyDown check into Update instead of FixedUpdate. But other than that it looks good.
Instead, make sure your jumpForce is not 0. Just because you set the initial value in your script
public float jumpForce = 7f;
Doesn't mean that it is 7f. Check the script in the inspector and make sure it's not 0. Setting values on scripts like you did only sets the initial value. If you created the jump force variable before assigning 7 to it, it will still be 0. You have to set the variables in the inspector.
And if that doesn't work use:
rb.AddForce(jumpForce * Vector3.up, ForceMode.Impulse);
Instead of trying to manually set the velocity.

Floating when adding Time.deltaTime to movement

My movement is working fine without Time.deltaTime but when I add it to my player movement I can move left to right fine but I fall slowly and I cant jump
using Newtonsoft.Json.Bson;
using System;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float horSpeed;
[SerializeField] private float vertSpeed;
private Rigidbody2D rb;
private Boolean isJumping;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void Update()
{
// we store the initial velocity, which is a struct.
var v = rb.velocity * Time.deltaTime;
if (Input.GetKey(KeyCode.Space) && !isJumping)
{
vf.y = vertSpeed;
isJumping = true;
}
if (Input.GetKey(KeyCode.A))
{
vf.x = -horSpeed;
}
if (Input.GetKey(KeyCode.D))
{
vf.x = horSpeed;
}
if (Input.GetKey(KeyCode.S))
{
vf.y = -vertSpeed;
}
rb.velocity = vf;
if(Input.GetKey(KeyCode.Escape))
SceneManager.LoadScene(0);
}
private void OnCollisionEnter2D(Collision2D collision)
{
isJumping = false;
}
}
I've added it to my enemy script and it works fine so im not sure whats different with player movement to using transform.position
Why would you multiply the velocity by Time.deltaTime?
This is used to convert a value from a "certain unit per frame" into a value "certain unit per second".
A velocity already IS a value in units per second.
Linear velocity of the Rigidbody in units per second.
=> It makes no sense to apply Time.deltaTime here at all.
For your X axis movement it doesn't make much difference since you anyway apply that velocity continuously every frame. Here you just would probably want to handle the case where neither left nor right is pressed and set vf.x = 0.
For the Y axis however you apply the jump only once, just to divide it by about 60 (or whatever your frame rate is) right in the next frame => you never give it the chance to fall or jump.
In general you should modify the Rigidbody in FixedUpdate. In your specific case it is fine to do this in Update, it is just redundant work ;)

Rigidbody.MovePosition() behaving strangely

using UnityEngine;
public class ThirdPersonMovement : MonoBehaviour
{
Rigidbody rb;
private Animator animator;
public float speed = 5f;
void Start() {
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//Get player input based on world space.
float playerHorizontalInput = Input.GetAxisRaw("Horizontal");
float playerVerticalInput = Input.GetAxisRaw("Vertical");
//Get camera-normalized directional vectors
Vector3 forward = Camera.main.transform.forward;
Vector3 right = Camera.main.transform.right;
//Create direction-relative input vectors
Vector3 forwardRelativeVerticalInput = playerVerticalInput * forward;
Vector3 rightRelativeHorizontalInput = playerHorizontalInput * right;
Vector3 cameraRelativeMovement = forwardRelativeVerticalInput + rightRelativeHorizontalInput;
Vector3 movement = cameraRelativeMovement * speed * Time.deltaTime;
rb.MovePosition(transform.position + movement);
transform.forward = cameraRelativeMovement;
if (cameraRelativeMovement != Vector3.zero)
{
animator.SetBool("IsMoving", true);
}
else {
animator.SetBool("IsMoving", false);
}
}
}
I know similar questions have been posted before but I haven't been able to find a solution to what I'm experiencing.
I have the code above and it is linked to a character with a rigidbody component and 'is kinematic' checked. When I try to move, the character doesn't move for ages and then randomly jumps forward a random distance and doesn't do it again until I hit W again.
This has worked before when I used transform.Translate but obviously my character ran through the floor when the camera pointed down so I was trying to fix the issue.
A few things I notice about your code. You said this method used to work with transform.translate but not anymore, this tells me that your movement vectors are probably fine up until the point you changed them for this implementation (my guess is everything is the same except when you added tranform.position to your vector, since the function doesn't take speed, it takes position). You could try testing tranform.position + movement or just movement with a Debug.Log() statement, but that's probably not your issue.
Since you said this issue only started when you changed the function you use to move the player, I would try just inputting a non-changing Vector3 into the movement function: rb.movePosition(tranform.position + new Vector3(1,0,0)); or something like that, just to see if the movement function is even working.

Struggling in Unity 3d object Controls

I'm totally new to Unity and game development...I made a 2D object of the car that can move to 8 directions....each direction with the specific animation of the car's movement...Now, how do I make my car move in such a way that if it's moving straight LEFT it shouldn't go immediately straight to RIGHT when turning RIGHT, so I want it to make a proper round turn or a "U TURN" to move towards its opposite direction and obviously the same with UP and DOWN turns....can anyone please help me in at least one way I can fix this?
or the other way to ask this question would be if I'm moving my object to x = -1 direction then on turning to x = 1 it should first go through x = 0 and then x = 1 so that it looks like a turn.
this is the code for my CAR so far..
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CARmovement : MonoBehaviour
{
public float speed;
private Rigidbody2D myRigidbody;
private Vector3 change;
private Animator animator;
private Vector3 lastMoveDirection;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
change = Vector3.zero;
change.x = Input.GetAxis("Horizontal");
change.y = Input.GetAxis("Vertical");
UpdateAnimationAndMove();
}
void UpdateAnimationAndMove()
{
if (change != Vector3.zero)
{
MoveCar();
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
animator.SetBool("driving", true);
}
else
{
animator.SetBool("driving", false);
}
}
void MoveCar()
{
myRigidbody.MovePosition(transform.position + change * speed * Time.deltaTime);
}
}
I try an example of rotating a car. We add an object (here I add a car as an example), select the object (car) to create a C# Script script, double-click to open, we define two variables Speed_move, Speed_rot to control the movement speed and Rotation speed and assign values to them. We use Translate to control the forward and backward movement of the cube through the W and S buttons, forward with forward, and back with back; use Rotate to control the rotation of the object through the A and D buttons, up is the Y-axis rotation. The following is the code for the specific rotation.
if (Input.GetKey(KeyCode.W))
{
this.transform.Translate(Vector3.forward * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.S))
{
this.transform.Translate(Vector3.back * Time.deltaTime * Speed_move);
}
if (Input.GetKey(KeyCode.A))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * -Speed_rot);
}
if (Input.GetKey(KeyCode.D))
{
this.transform.Rotate(Vector3.up * Time.deltaTime * Speed_rot);
}

How do I make my player with a Rigidbody move with isKinematic checked?

My game is a topdown zombie shooter and whenever the zombies get to the player they bunch up underneath them, to the point where the player can just walk over the zombies. I noticed that when I check isKinematic on the Rigidbody the zombies cant push the player up to go underneath him, so they just run into him(which is what I want). Despite this I am then unable to move. How can i fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMoving1 : MonoBehaviour {
public float moveSpeed;
private Rigidbody myRigidbody;
private Vector3 moveInput;
private Vector3 moveVelocity;
private Camera mainCamera;
public GunController theGun;
void Start () {
myRigidbody = GetComponent <Rigidbody>();
mainCamera = FindObjectOfType<Camera>();
}
// Update is called once per frame
void Update () {
moveInput = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput * moveSpeed;
Ray cameraRay = mainCamera.ScreenPointToRay(Input.mousePosition);
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
float rayLength;
if(groundPlane.Raycast(cameraRay,out rayLength))
{
Vector3 pointToLook = cameraRay.GetPoint(rayLength);
transform.LookAt(new Vector3(pointToLook.x,transform.position.y,pointToLook.z));
}
if (Input.GetMouseButtonDown(0))
theGun.isFiring = true;
if (Input.GetMouseButtonUp(0))
theGun.isFiring = false;
}
void FixedUpdate(){
myRigidbody.velocity = moveVelocity;
}
}
With isKinematic == true You can't change object position through rigidbody, You can only change transform.position.
I think it could be better, if You set isKinematic to false and add stopping distance to enemies, so they can't get too close to player.
Being that your player can no longer be effected by the physics engine, you'd have to manipulate the object's transform manually. Your script isn't ideally setup for it currently, but if I was to hack it into it and try to make it work it would look something like this:
(you can change it from fixedUpdate to update if you're no longer utilizing the physics engine)
void update(){
float x = Input.GetAxisRaw("Horizontal")* Time.Deltatime;
float z = Input.GetAxisRaw("Vertical") * Time.Deltatime;
transform.position = new Vector3(transform.position.x+x,0,transform.position.z+z);
Another way of doing this is to lock the position of Y for the player (assuming Y is the positive "up" direction). isKinimatic is best when you want to move the player or objects around yourself.
I would say upping the mass is better in this case, and you can keep isKinematic unchecked in this case then too. Also apply the lock for Y movement (again if it is the "up" direction from the plane)
Let me know what your solution is regardless, I've had some issues in the past as well with these types of events happening

Categories

Resources