Unity 2D function gameObject.transform.Translate(...) does not work - c#

Vector3 localScale = transform.localScale;
//Translation$
if (Input.GetKey (KeyCode.LeftArrow))
{
gameObject.transform.Translate (-speed * Time.deltaTime);
if (localScale.x > 0)
{
localScale.x *= -1.0f;
}
}
if (Input.GetKey(KeyCode.RightArrow))
{
gameObject.transform.Translate (speed * Time.deltaTime);
if (localScale.x < 0)
{
localScale.x *= -1.0f;
}
}
transform.localScale = localScale;
i use this to move my character, but it doesnot work, someone help! Thanks in advance!

Related

Jump script in unity involving rb.velocity not working

Here is my code and inspector data, I am rookie in unity And I do not have an idea why it is not working. I tagged this as a 3D problem, since I think it wouldn't work in either. I watched some youtube videos and other posts, and I cannot find a mistake.I would be grateful for any help.
This is picture of my inspector
public Animator animator;
public SpriteRenderer sprite;
public Rigidbody2D rb;
Vector2 playerDirection;
public float speed;
public float jumpForce;
public float fallMultiplier=2.5f;
public float lowJumpMultiplier=2f;
void Update()
{
playerDirection.x = Input.GetAxisRaw("Horizontal");
//Animation
////////////////////////////////////////////////////
if (playerDirection.x != 0)
animator.SetBool("isMoving", true);
else
animator.SetBool("isMoving", false);
////////////////////////////////////////////////////
//flip
////////////////////////
if (playerDirection.x < 0)
{
sprite.flipX = true;
}
if (playerDirection.x>0)
{
sprite.flipX = false;
}
////////////////////////
//Jump
///////////////////////
////////////////////////
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + speed *playerDirection * Time.fixedDeltaTime);
if (Input.GetButton("Jump"))
{
rb.velocity = Vector2.up * jumpForce;
}
if (rb.velocity.y < 0)
{
rb.velocity += Vector2.up * fallMultiplier * Time.fixedDeltaTime;
}
else
if (rb.velocity.y > 0 && !Input.GetKey(KeyCode.W))
{
rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - rb.gravityScale) * Time.fixedDeltaTime;
}
}
First of all you need to understand the difference between Update and FixedUpdate. Update runs at all the frames. FixedUpdate runs at specific time intervals. What you are doing is registering user input in the FixedUpdate. That means that, you need to be lucky and have the FixedUpdate run at the specific frame you pressed the button. If you had pysics calculations, you should indeed place them in the FixedUpdate. However, when jumping, you do not, you simply set the velocity. Now, the falling part is interesting, because you do want that in the FixedUpdate.
Try this:
void Update()
{
playerDirection.x = Input.GetAxisRaw("Horizontal");
//Animation
////////////////////////////////////////////////////
if (playerDirection.x != 0)
animator.SetBool("isMoving", true);
else
animator.SetBool("isMoving", false);
////////////////////////////////////////////////////
//flip
////////////////////////
if (playerDirection.x < 0)
{
sprite.flipX = true;
}
if (playerDirection.x>0)
{
sprite.flipX = false;
}
////////////////////////
//Jump
///////////////////////
if (Input.GetButton("Jump"))
{
Debug.Log("Jumping button registered");
rb.velocity = Vector2.up * jumpForce;
}
////////////////////////
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + speed *playerDirection * Time.fixedDeltaTime);
if (rb.velocity.y < 0)
{
rb.velocity += Vector2.up * fallMultiplier * Time.fixedDeltaTime;
}
else
if (rb.velocity.y > 0 && !Input.GetKey(KeyCode.W))
{
rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - rb.gravityScale) * Time.fixedDeltaTime;
}
}
Once you make sure that the jump is registered, it should probably work fine. If however you do NOT get console log when pressing the jump button, you should check your input settings.

Player has little control over the character after dashing in midair

I'm working on a 2.5D player controller right now, and there is a problem with my dash in midair. The dash works, but the character can't be completely controlled on the X axis after the dash is finished until they hit the ground. I want the player to have full control on the X axis right after the dash so that they can dodge appropriately.
void Update()
{
PlayerInput();
}
void FixedUpdate()
{
xMovement();
yMovement();
}
void PlayerInput()
{
//Registers X and Y movement
horizontalInput = Input.GetAxis("Horizontal");
verticalInput = Input.GetAxis("Vertical");
if (Input.GetButton("Run"))
{
isRunning = true;
}
else if (Input.GetButtonUp("Run"))
{
isRunning = false;
}
//Makes player jump by returning a bool value to "yMovement()" when pressed.
if (Input.GetButtonDown("Jump"))
{
jumpRequest = true;
}
if (Input.GetKeyDown(KeyCode.A))
{
if (doubleTapTime > Time.time && lastKeyCode == KeyCode.A)
{
StartCoroutine(Dash(1f));
Debug.Log("You dashed left");
}
else
{
doubleTapTime = Time.time + 0.5f;
}
lastKeyCode = KeyCode.A;
}
if (Input.GetKeyDown(KeyCode.D))
{
if (doubleTapTime > Time.time && lastKeyCode == KeyCode.D)
{
StartCoroutine(Dash(-1f));
Debug.Log("You dashed right");
}
else
{
doubleTapTime = Time.time + 0.5f;
}
lastKeyCode = KeyCode.D;
}
}
void xMovement()
{
//Makes player walk left and right
if (!isRunning && !isDashing)
{
transform.Translate(Vector3.left * walkSpeed * horizontalInput * Time.deltaTime);
}
//Makes player run left and right
else if (isRunning && !isDashing)
{
transform.Translate(Vector3.left * runSpeed * horizontalInput * Time.deltaTime);
}
}
void yMovement()
{
//Make player jump when Jump is pressed
if (jumpRequest)
{
playerRb.velocity = new Vector3(playerRb.velocity.x, jumpForce);
jumpRequest = false;
//playerRb.velocity = new Vector2(playerRb.velocity.x, playerRb.velocity.y * jumpForce);
}
//Makes player fall faster in general, and when the Jump button is released
if (playerRb.velocity.y < 0)
{
playerRb.velocity += Vector3.up * Physics.gravity.y * (fallMultiplyer - 1) * Time.deltaTime;
}
else if (playerRb.velocity.y > 0 && !Input.GetButton("Jump"))
{
playerRb.velocity += Vector3.up * Physics.gravity.y * (lowJumpMultiplyer - 1) * Time.deltaTime;
}
}
IEnumerator Dash(float direction)
{
isDashing = true;
playerRb.velocity = new Vector3(playerRb.velocity.x, .0f);
playerRb.velocity = new Vector3(dashDistance * direction, 0f, 0f);
playerRb.useGravity = false;
yield return new WaitForSeconds(.2f);
isDashing = false;
playerRb.useGravity = true;
Any tips on code optimization is also greatly appreciated. I'm still fairly new to coding and would rather learn appropriate coding habits before I have to unlearn bad ones. Thank you!
I think your issue is that you're using a Translation on transform for the x axis when on the yAxis you're actually using the velocity. Unity might have trouble dealing with both in a single "FixedUpdate" call. Or it might just not do what you expect.
I would recommend sticking to velocity changes. So that would give something like
void xMovement()
{
//Makes player walk left and right
if (!isRunning && !isDashing)
{
playerRb.velocity += Vector3.left * walkSpeed * horizontalInput * Time.deltaTime;
}
//Makes player run left and right
else if (isRunning && !isDashing)
{
playerRb.velocity += Vector3.left * runSpeed * horizontalInput * Time.deltaTime;
}
}

How to move forward an object in Unity?

I made a game object and attached a script to it. I need to rotate and move the object in a straight line, depending on the rotation. I made a turn, but I have problems with movement. Any solutions?
//Rotation
if (Input.GetAxis("Rotation") > 0) {
transform.Rotate(Vector3.back, turnSpeed * Time.deltaTime);
}
else if (Input.GetAxis("Rotation") < 0)
{
transform.Rotate(Vector3.back, -turnSpeed * Time.deltaTime);
}
//Velocity
if (Input.GetAxis("Thrust") != 0) {
rb.AddForce(Vector3.forward * Time.deltaTime * Speed);
}
else if (Input.GetAxis("Thrust") <= 0.1f){
rb.velocity = new Vector2(0, 0);
}
Rigidbody.AddForce applies the vector as force in world space. So, you need to give it a vector that is in the world space direction of the transform's forward. Luckily, that's as simple as using transform.forward, transform.up, or transform.right or a negation of one of them instead of Vector3.forward:
//Rotation
if (Input.GetAxis("Rotation") > 0) {
transform.Rotate(Vector3.back, turnSpeed * Time.deltaTime);
}
else if (Input.GetAxis("Rotation") < 0)
{
transform.Rotate(Vector3.back, -turnSpeed * Time.deltaTime);
}
//Velocity
if (Input.GetAxis("Thrust") != 0) {
Vector3 frontDirection;
// probably one of these for a 2D game:
frontDirection = transform.right;
//frontDirection = -transform.right;
//frontDirection = transform.up;
//frontDirection = -transform.up;
rb.AddForce(frontDirection * Time.deltaTime * Speed);
}
else if (Input.GetAxis("Thrust") <= 0.1f){
rb.velocity = new Vector2(0, 0);
}

Change Object's Scale Smoothly with Swipe

I wrote the code below to change an object's scale (X axis) with mouse swipe, it works but it's not smooth, how can I smooth it?
Script:
Vector3 newScale;
private float _previousSwipePosition;
private float newPosition;
if (Input.GetMouseButton(0))
{
_previousSwipePosition = Input.mousePosition.x;
if (newPosition != _previousSwipePosition)
{
if (newPosition - _previousSwipePosition < -2)
{
if (transform.localScale.x <= 1.4f)
{
newScale = transform.localScale;
newScale.x += 0.06f;
transform.localScale = newScale;
}
}
else if (newPosition - _previousSwipePosition > 2)
{
if (transform.localScale.x >= 0.2f)
{
newScale = transform.localScale;
newScale.x -= 0.06f;
transform.localScale = newScale;
}
}
}
newPosition = Input.mousePosition.x;
}
You can use Input.GetAxis("Mouse X") to get smoothed scale of how much the mouse has moved in the last frame. Multiply that by a speed parameter.
Get the power of 2 by that product to get how much to change the current scale. Then, change the scale and clamp it:
public float scaleSpeed = 1f;
// ...
// ignore first frame mouse is pressed
if (Input.GetMouseButton(0) && !Input.GetMouseButtonDown(0))
{
float scaleFactor = Mathf.Pow(2f, Input.GetAxis("Mouse X")
* scaleSpeed);
float newX = Mathf.Clamp(transform.localScale.x * scaleFactor, 0.2f, 1.4f);
transform.localScale = new Vector3(
newX,
transform.localScale.y,
transform.localScale.z);
}
Use Time.deltaTime to smooth
Vector3 newScale;
private float _previousSwipePosition;
private float newPosition;
private float speed = 6f;
private void Update()
{
if (Input.GetKey(KeyCode.A))
{
if (transform.localScale.x <= 1.4f)
{
newScale = transform.localScale;
newScale.x += speed * Time.deltaTime;
transform.localScale = newScale;
}
}
if (Input.GetKey(KeyCode.B))
{
if (transform.localScale.x >= 0.2f)
{
newScale = transform.localScale;
newScale.x -= speed * Time.deltaTime;
transform.localScale = newScale;
}
}
}

Unity hold touch move horizontally

I have no idea how to start this, I want to move my character left and right when holding the touch.
Like in this game:
Example Game - Stairs from Ketchapp
I have only my script that detects the left or right space of the screen.
public float forwardSpeed = 5f;
public float sideSpeed = 5f;
private void Update()
{
Vector3 deltaPosition = transform.forward * forwardSpeed;
if (Input.touchCount > 0)
{
Vector3 touchPosition = Input.GetTouch(0).position;
if (touchPosition.x > Screen.width * 0.5f)
deltaPosition += transform.right * sideSpeed;
else
deltaPosition -= transform.right * sideSpeed;
}
transform.position += deltaPosition * Time.deltaTime;
}
This solution works for me. Its used in a simple block breaker game to move a paddle left or right.
void Update () {
if (Input.touchCount > 0){
Touch touch = Input.GetTouch(0);
int direction = (touch.position.x > (Screen.width / 2)) ? 1 : -1;
MovePaddle(direction);
}
}
void MovePaddle(int direction){
float xPos = transform.position.x + (direction * Time.deltaTime * paddleSpeed);
playerPos = new Vector3 (Mathf.Clamp (xPos, -8f, 8f), -9.5f, 0f);
transform.position = playerPos;
}
i think that what you are trying to say is to only move when you are pressing the screen, not?
maybe this might help you:
public float forwardSpeed = 5f;
public float sideSpeed = 5f;
private void Update()
{
Vector3 deltaPosition = transform.forward * forwardSpeed;
if (Input.touchCount > 0)
{
Vector3 touchPosition = Input.GetTouch(0).position;
if (touchPosition.x > Screen.width * 0.5f)
deltaPosition += transform.right * sideSpeed;
else
deltaPosition -= transform.right * sideSpeed;
}
else{
deltaPosition = sideSpeed;
}
transform.position += deltaPosition * Time.deltaTime;
}
pd: not tested because yet
I have a solution that is not really smooth
public float speed = 5;
public Rigidbody rb;
public void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
//Add touch support
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
Touch touch = Input.touches[0];
h = touch.deltaPosition.x;
}
//Move only if we actually pressed something
if (h > 0 || h < 0)
{
Vector3 tempVect = new Vector3(h, 0, 0);
tempVect = tempVect.normalized * speed * Time.deltaTime;
//rb.MovePosition(rb.transform.position + tempVect);
Vector3 newPos = rb.transform.position + tempVect;
checkBoundary(newPos);
}
}
void checkBoundary(Vector3 newPos)
{
//Convert to camera view point
Vector3 camViewPoint = Camera.main.WorldToViewportPoint(newPos);
//Apply limit
camViewPoint.x = Mathf.Clamp(camViewPoint.x, 0.04f, 0.96f);
camViewPoint.y = Mathf.Clamp(camViewPoint.y, 0.07f, 0.93f);
//Convert to world point then apply result to the target object
Vector3 finalPos = Camera.main.ViewportToWorldPoint(camViewPoint);
rb.MovePosition(finalPos);
}
private void Start()
{
Application.targetFrameRate = 60;
}
void Update()
{
if (Input.touchCount > 0)
{
Touch t = Input.GetTouch(0);
transform.position = new Vector3(transform.position.x + t.deltaPosition.x * .02f, transform.position.y, transform.position.z );
}
}
You can use this. Simple :)

Categories