Replace Input.GetAxis to touch - c#

I want to code the car's rotation system as I move left and right. I use the following code for this.
float steer = Input.GetAxis("Horizontal");
float finalangel = steer * 45f;
wheelcoll[0].steerAngle = finalangel;
But I want to set it for the phone. When the user touches the screen of the phone and keeps his hand on the screen of the phone, the car goes to the left and stays. When the user removes his hand from the phone, the car returns to its original position. But when doing this process, I want the car to turn in the right direction.
How can I do this?
I tried this too:
[SerializeField] Rigidbody rb;
public Vector3 targetpostion;
public int Speed;
public bool FirstLaneBlueCar;
public bool BlueCar;
public Vector2 Xpos;
public float rotatlerptime;
bool rottrue;
void Start()
{
rottrue = false;
BlueCar = false;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}else if (Input.GetMouseButtonUp(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}
if (!rottrue)
{
if (transform.position.x <= 4f)
{
Debug.Log(">-.5");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
if (transform.position.x >= 3f)
{
Debug.Log(">.5f");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
}
}
private void FixedUpdate()
{
transform.Translate(targetpostion, Space.World);
if (BlueCar)
{
if (FirstLaneBlueCar)
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, -60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("left", .1f);
}
else
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("right", .1f);
}
}
}
public void rot2()
{
rottrue = false;
}
void left()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.y, transform.position.y, transform.position.z), .08f);
}
void right()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.x, transform.position.y, transform.position.z), .08f);
}
public void LeftButtonPressed()
{
if (FirstLaneBlueCar)
{
FirstLaneBlueCar = false;
}
else
{
FirstLaneBlueCar = true;
}
}

You can track the first touch position, and make the respective calculations in the Update method, comparing the previous touch position with the current one.
private void Update()
{
if (Input.touches.Length < 1)
return;
var touch = Input.touches[0];
var deltaPosition = touch.deltaPosition;
// Move the car according to the shift in touch position
}
You can also save the touch ID when the touch has just begun, so you can track the same touch later (user can have multiple fingers on the screen).
Use Touch.fingerId for that.

Related

Unity - how to make an object face the direction of its movement?

I'm trying to make a character prefab face the direction in which its moving. I've tired all sorts of things, with and without rigidbodies but nothing seems to work. The thing is, it does actually face in the correct direction. But once its there, it starts to rotate the whole prefab and it goes down into the ground.
The character holds a 3D shield, and goes towards a tower. So once it reaches the tower it raises the shield which in turn rotates the whole character down into the ground. I would like it to just rotate in the X and Z axis and never change the Y axis.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BlockRadar : MonoBehaviour
{
// Start is called before the first frame update
public Transform Tower;
private GameObject[] multipleBlocks;
public Transform closestBlock;
public bool blockContact;
public float currentDistance;
public float stopDistance;
public Animator animator;
public int damage;
public float attackspeed;
private float canAttack;
public float moveSpeed = 5f;
public Vector3 distance;
private Vector3 movement;
void Start()
{
closestBlock = null;
blockContact = false;
}
// Update is called once per frame
void Update()
{
Vector3 pos = transform.position;
pos.y = 0;
pos.x = 0;
transform.position = pos;
closestBlock = getClosestBlock();
closestBlock.gameObject.GetComponent<Renderer>().material.color = new Color(1, 0.7f, 0, 1);
Vector3 direction = closestBlock.position - transform.position;
direction.Normalize();
movement = direction;
float dist = Vector3.Distance(closestBlock.position, transform.position);
if (dist <= 1.5f)
{
{
blockContact = true;
animator.SetBool("Moving", false);
Debug.Log("Now touching block");
if (attackspeed <= canAttack)
{
Attack();
canAttack = 0f;
}
else
{
canAttack += Time.deltaTime;
}
}
}
if (dist > 1.5f)
{
transform.forward = movement;
blockContact = false;
Debug.Log("Lost contact with block");
animator.SetBool("Moving", true);
moveCharacter(movement);
}
}
public void Attack()
{
Debug.Log("ATTACKING!");
Damage(closestBlock.transform);
animator.SetTrigger("Attacking");
}
private void FixedUpdate()
{
}
void moveCharacter(Vector3 direction)
{
transform.Translate(direction * moveSpeed * Time.deltaTime, Space.World);
}
void DistanceToTower()
{
if (Tower)
{
float dist = Vector3.Distance(Tower.position, transform.position);
if (dist <= 1)
{
{
blockContact = true;
Debug.Log("Now touching block");
if (attackspeed <= canAttack)
{
Attack();
canAttack = 0f;
}
else
{
canAttack += Time.deltaTime;
}
}
}
}
}
//when the object carrying this script is destroyed
private void OnDestroy()
{
if (closestBlock !=null)
{
closestBlock.gameObject.GetComponent<Renderer>().material.color = new Color(0, 0, 0, 0);
}
}
public Transform getClosestBlock()
{
multipleBlocks = GameObject.FindGameObjectsWithTag("Block");
float closestDistance = Mathf.Infinity;
Transform trans = null;
//finds all blocks in the scene
foreach (GameObject go in multipleBlocks)
{
currentDistance = Vector3.Distance(transform.position, go.transform.position);
if (currentDistance < closestDistance)
{
closestDistance = currentDistance;
trans = go.transform;
}
}
return trans;
}
void Damage(Transform block)
{
Tower_Stats e = block.GetComponent<Tower_Stats>();
if (e != null)
{
e.TakeDamage(damage);
}
}
}
I would be really, really grateful for any help. As I said before I used to have rigidbodies on the character, but I removed them since I thought maybe they were the fault. But doesnt seem like it. One other thing I've noticed is that when the prefab is instantiated, its children doesnt have the correct position values. Not sure why. But if that could be a clue I just thought I'd let you know.

Unity 3D Aerial movement and jumping problem

Aerial Movement Problem
I've followed a few tutorials and I've set up a decent base for a game, - basic player movement, entity animation, health, HUD UI, etc. - but I wanted to make the movement a bit smoother, less snappy, more physics-based, you get the gist. I made it a bit better and it definitely meets all the requirements for terrain-based movement (i.e: movement across physical surfaces - while the player is on the ground), but I want jumping to be a bit more dynamic, and I know what I want to do but I'm having trouble doing it.
Here's the issue:
If the player moves (regardless of whether sprintActive is toggled or not) and they jump after moving, the player gains speed in the air way too fast, and they can't move in any direction other than forward (relative to their rotation).
Here's the objective:
I set it up so the velocity is simply redirected to whatever direction is forward from the playerRB, but I think I would prefer if the velocity didn't immediately change direction, but rather gradually curve as the player tries to move a certain direction? I know I may be asking for a lot, but some advice on how to do this, or if I should try a different approach, would be very much appreciated.
Code used:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RFPSPlayerMovement : MonoBehaviour
{
public float speedForce;
public float jumpForce;
public float diveForce;
public Transform groundCheck;
public float groundDistance = 0.25f;
public LayerMask groundMask;
private Transform playerBody;
private Rigidbody playerRB;
private bool isGrounded;
private bool sprintActive = false;
private bool delay = false;
private float lateralSpeed;
private Vector3 velocity;
float xMov, zMov;
float xSpeed, zSpeed;
IEnumerator DelayTimer(float duration)
{
delay = true;
yield return new WaitForSeconds(duration);
delay = false;
}
void Start()
{
playerBody = GetComponent<Transform>();
playerRB = GetComponent<Rigidbody>();
}
void Update()
{
xMov = Input.GetAxisRaw("Horizontal") * Time.deltaTime;
zMov = Input.GetAxisRaw("Vertical") * Time.deltaTime;
if(Input.GetKey(KeyCode.LeftShift))
{
sprintActive = true;
}
else
{
sprintActive = false;
}
if(Input.GetKey(KeyCode.W))
{
Movement(0, speedForce);
}
if(Input.GetKey(KeyCode.S))
{
Movement(0, -speedForce);
}
if(Input.GetKey(KeyCode.A))
{
Movement(-speedForce, 0);
}
if(Input.GetKey(KeyCode.D))
{
Movement(speedForce, 0);
}
if(Input.GetKey(KeyCode.Space))
{
if(delay == false)
{
if(isGrounded)
{
StartCoroutine(DelayTimer(0.05f));
Jump(jumpForce);
}
}
}
}
void FixedUpdate()
{
velocity = playerRB.velocity;
lateralSpeed = new Vector2(playerRB.velocity.x, playerRB.velocity.z).magnitude;
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded)
{
velocity = new Vector3(
xMov + (float) (playerRB.velocity.x * 0.90),
playerRB.velocity.y,
zMov + (float) (playerRB.velocity.z * 0.90)
);
}
else
{
velocity.x = (float) (playerBody.forward.x * lateralSpeed);
velocity.y = playerRB.velocity.y;
velocity.z = (float) (playerBody.forward.z * lateralSpeed);
}
playerBody.eulerAngles = new Vector3(0, playerBody.eulerAngles.y, 0);
playerRB.velocity = velocity;
}
void Movement(float xAmount, float zAmount)
{
if(sprintActive)
{
xSpeed = (float) (xAmount * 2);
zSpeed = (float) (zAmount * 2);
}
else
{
xSpeed = xAmount;
zSpeed = zAmount;
}
playerRB.AddRelativeForce(new Vector3(xSpeed, 0, zSpeed), ForceMode.Impulse);
}
void Jump(float yAmount)
{
playerRB.AddRelativeForce(new Vector3(0, yAmount, 0), ForceMode.Impulse);
}
}

I'm trying to get my cube to only jump on the ground but my if statement isn't working

public Rigidbody rb;
public bool cubeIsOnTheGround = true;
public float speed = 10;
Vector3 direction;
// Start is called before the first frame update
void Start()
{
rb.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
direction = input.normalized;
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
}
if (cubeIsOnTheGround == true)
{
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
cubeIsOnTheGround = false;
}
}
}
void FixedUpdate()
{
rb.position += direction * speed * Time.deltaTime;
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
cubeIsOnTheGround = true;
}
}
The if statemnt boolIsOnTheGround is not working. What I'm trying to do is check whether the cube is on the ground so I kno when you can jump. The cube just bounces infinitely by pressing space.
In your code you have two if-blocks where you jump:
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
}
if (cubeIsOnTheGround == true)
{
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
cubeIsOnTheGround = false;
}
}
The first if-block does not check cubeIsOnTheGround, so it will jump as long as the jump button is pressed. If you remove the first block this behavior should stop.

Unity Raycasting problem in some part of the scene

I started doing some simple stuff in Unity (goal is to make a great game) so I made a simple Player Controller.
public class PlayerController : MonoBehaviour
{
public float walkingSpeed;
public float jumpSpeed;
public bool jumpFlag = false;
public float maxJumpDistance = 1.0f;
Rigidbody rb;
Collider col;
Vector3 playerSize;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
playerSize = col.bounds.size;
}
// Update is called once per frame
void FixedUpdate()
{
WalkHandler();
JumpHandler();
}
void WalkHandler()
{
float horizonstalAxis = Input.GetAxis("Horizontal");
float verticalAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(-horizonstalAxis * walkingSpeed * Time.deltaTime, 0, -verticalAxis * walkingSpeed * Time.deltaTime);
rb.MovePosition(transform.position += movement);
}
void JumpHandler()
{
float jumpAxis = Input.GetAxis("Jump");
//Debug.Log(jumpAxis);
if (jumpAxis > 0)
{
bool isGrounded = CheckGrounded();
if (jumpFlag != true && isGrounded)
{
jumpFlag = true;
Vector3 jumpVector = new Vector3(0, jumpSpeed * Time.deltaTime, 0);
rb.AddForce(jumpVector, ForceMode.VelocityChange);
}
}
else
{
jumpFlag = false;
}
}
bool CheckGrounded()
{
Vector3 checkerPoint = transform.position + new Vector3(0, -playerSize.y / 2, 0);
bool grounded = Physics.Raycast(checkerPoint, -Vector3.up, maxJumpDistance);
return grounded;
}
I came across a wierd problem. In some parts of the scene my method JumpHandler is not working. After reaching some z coordinates, the CheckGrounded returns False instead of True, even though the Raycast direction is set down.
Can anyone help?

Can't Jump on Unity3D

I have a problem about jump for a character..
I can use CharacterMotor.Move() for jumping, but no .SimpleMove(), why?
This is my class at the moment:
public float speed = 10.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 50.0f;
public float gravitySpeed = 30.0f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
CharacterController cc;
Vector3 newPos;
public void Start()
{
cc = GetComponent<CharacterController> ();
}
public void Update()
{
/*Movements part*/
if (Input.GetKey (Avancer.ToString ())) {
newPos = new Vector3 (speed, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (Reculer.ToString ())) {
newPos = new Vector3 (speed * -1, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideGauche.ToString ())) {
newPos = new Vector3 (0, 0, speed);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideDroite.ToString ())) {
newPos = new Vector3 (0, 0, speed * -1);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
} else if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
newPos = new Vector3 (0, jumpSpeed * Time.deltaTime, 0);
cc.SimpleMove (newPos);
//cc.Move (newPos);
print ("JUMP !");
} else if (!cc.isGrounded) {
newPos = new Vector3 (0, (gravitySpeed * Time.deltaTime) * -1, 0);
cc.SimpleMove (newPos);
print ("en l'air");
}
/*Movements part*/
}
I just not understand why it don't perform
So if you can help me, thank you
EDIT
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[AddComponentMenu("Camera-Control/Mouse Look")]
public class palskie : MonoBehaviour
{
public float speed = 1000000.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 100.0f;
public float gravitySpeed = 50f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
private CharacterController cc;
Vector3 dir = Vector3.zero;
public int ammo = 100;
public int life = 100;
public void Start()
{
cc = GetComponent<CharacterController> ();
}
public void Update()
{
/*Movements part*/
Vector3 direction;// = Vector3.zero;
if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
dir.y = jumpSpeed;
direction = dir;
} else if (!cc.isGrounded) {
dir.y -= gravitySpeed;
direction = dir;
} else {
direction = Vector3.zero;
}
if (Input.GetKey (Avancer.ToString ())) {
direction.x = speed;
} else if (Input.GetKey (Reculer.ToString ())) {
direction.x -= speed;
}
if (Input.GetKey (SlideGauche.ToString ())) {
direction.z = speed;
} else if (Input.GetKey (SlideDroite.ToString ())) {
direction.z = -speed;
}
if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
}
//Transformer le Vector3 en direction local
direction = transform.TransformDirection (direction);
//Deplacement du personnage
cc.Move (direction * Time.deltaTime);
transform.Rotate (0, Input.GetAxis ("Mouse X") * rotationSpeed, 0);
/*Movements part*/
}
void OnTriggerEnter(Collider obj)
{
if ((obj.gameObject.name == "Healt")) {
life += 5;
if (life > 100)
life = 100;
Destroy (obj.gameObject);
} else if ((obj.gameObject.name == "Ammo")) {
ammo += 5;
if (ammo > 200)
ammo = 200;
Destroy (obj.gameObject);
}
}
}
last edit, it works ! :) We found solution after long search ;)
Thank for you help :)
[SOLVED]
According to Unity, you can't and should not try to jump with the SimpleMove function. It clearly states on the documentation page of SimpleMove that SimpleMove will ignore any attempt to add force to the y-axis which is what you are doing. It is designed like that for thier own reason. Use the Move function as they made it for jumping.
Also the last line of your if statement code !cc.isGrounded is not required if you are using the SimpleMove function. The document again states that gravity is automatically applied to it when the object is moving.
For some reason I was able to get SimpleMove to work but the gravity pulling it down is too weak. If you want to try this, replace
newPos = new Vector3 (0, jumpSpeed * Time.deltaTime, 0);
with
newPos = new Vector3 (0, 1 * jumpSpeed * Time.deltaTime, 0);
then change the public float jumpSpeed = 50.0f;
to
public float jumpSpeed = 60000f;
It works but doesn't look good at all. You should go with the Move function instead.
EDIT:
"you say SimpleMove() can't do anything on Y-axis, then why my Y-axis is edit when I fall, I mean of gravaity?" It looks like you are doubting me. That's fine. It is your responsibility to click and read the the link I posted.
"The problem is, if I don't add gravity code, my character stay in fly, the other problem is, when I jump with Move(), It's like a teleportation" That's what you have said your problem was in the beginiing. It can be solve easily with the Move function by using Time.deltaTime to smooth out the y-axis movement.
Forget about the code I posted above. It worked but then stopped working after I restarted Unity. I guess it was a bug that made it to work in the first place.
I have changed your code to have smooth jumping with the Move function. I only changed the jumping and the gravity part of the code. Just copy the whole code and replace it with what you posted above. You shouldn't have any problem then. Make sure to reset the Character Controller values to default in Editor then reset the values of this script in the Editor too so that it will use the default values from the script. You can adjust the gravitySpeed and jumpSpeed to suit your needs after you test it.
public float speed = 10.0f;
public float rotationSpeed = 10.0f;
public float jumpSpeed = 130;
public float gravitySpeed = 80.0f;
public string Avancer = "z";
public string Reculer = "s";
public string RotationGauche = "q";
public string RotationDroite = "d";
public string SlideGauche = "a";
public string SlideDroite = "e";
public string Jump = "space";
CharacterController cc;
Vector3 newPos;
public void Start ()
{
cc = GetComponent<CharacterController> ();
}
public void Update ()
{
/*Movements part*/
if (Input.GetKey (Avancer.ToString ())) {
newPos = new Vector3 (speed, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (Reculer.ToString ())) {
newPos = new Vector3 (speed * -1, 0, 0);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideGauche.ToString ())) {
newPos = new Vector3 (0, 0, speed);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (SlideDroite.ToString ())) {
newPos = new Vector3 (0, 0, speed * -1);
newPos = transform.rotation * newPos;
cc.SimpleMove (newPos);
} else if (Input.GetKey (RotationGauche.ToString ())) {
transform.Rotate (0, rotationSpeed * -1, 0);
} else if (Input.GetKey (RotationDroite.ToString ())) {
transform.Rotate (0, rotationSpeed, 0);
} else if (cc.isGrounded && Input.GetKeyDown (Jump.ToString ())) {
newPos = new Vector3 (0, jumpSpeed, 0);
cc.Move (newPos * Time.deltaTime);
print ("JUMP !");
}
if (!cc.isGrounded) {
newPos.y -= gravitySpeed * Time.deltaTime;
cc.Move (newPos * Time.deltaTime);
print ("en l'air");
}
/*Movements part*/
}

Categories