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 :)
Related
Did someone know how to make the player not turning when i press left or right button ? I'm using unity script refrence for moving.
this video showing my problem: https://drive.google.com/file/d/1m-_Q3j0kt5bMfxiiqqjGAp0wtW7x8gno/view?usp=sharing
public class Move : MonoBehaviour
{
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
private float playerSpeed = 2.0f;
private float jumpHeight = 1.0f;
private float gravityValue = -9.81f;
private void Start()
{
controller = gameObject.AddComponent<CharacterController>();
}
void Update()
{
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
controller.Move(move * Time.deltaTime * playerSpeed);
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
// Changes the height position of the player..
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
}
Remove this line:
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
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;
}
}
}
Right now I have a small soldier on the screen that moves with W, A, S, D and rotates / changes direction with the arrow keys. What I want to happen is when the player's direction changes (by using the arrow keys), pushing W will send him in that direction instead of up the screen.
Also (for example), if you are holding D and the right arrow key at the same time he should move in a circle about a point on the ground (instead of spinning in a circle while moving in a straight line to the right).
Here is my current code:
public class MovePlayer : MonoBehaviour {
void Update() {
// Rotate left
if (Input.GetKey (KeyCode.LeftArrow)) {
transform.Rotate(0, 0, 1.3f);
}
// Rotate right
if (Input.GetKey(KeyCode.RightArrow)) {
transform.Rotate(0, 0, -1.3f);
}
// Strafe left
if (Input.GetKey (KeyCode.A)) {
Vector3 position = this.transform.position;
position.x -= 0.055f;
this.transform.position = position;
}
// Move up
if (Input.GetKey (KeyCode.W)) {
Vector3 position = this.transform.position;
position.y += 0.043f;
this.transform.position = position;
}
// Move down
if (Input.GetKey (KeyCode.S)) {
Vector3 position = this.transform.position;
position.y -= 0.043f;
this.transform.position = position;
isMoving = true;
}
// Strafe right
if (Input.GetKey (KeyCode.D)) {
Vector3 position = this.transform.position;
position.x += 0.055f;
this.transform.position = position;
}
}
}
Any ideas? Wasn't sure what to search exactly.
Here is what I've done for my character (Plus a mouse script for directions)
update()
{
Vector3 dir = new Vector3(); //(0,0,0)
//float CharacterSpeed = 10.0f;
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
dir.z += 1.0f;
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
dir.x -= 1.0f;
else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
dir.z -= 1.0f;
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
dir.x += 1.0f;
dir.Normalize();
transform.Translate(dir * CharacterSpeed * Time.deltaTime);
}
If you only have keyboard for movement : (I'm not %100 sure this one)
Vector3 dir = new Vector3(); //(0,0,0)
//float CharacterSpeed = 10.0f;
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
dir.z += 1.0f;
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
var Rotation = Quaternion.AngleAxis("Rotation Angle Here", transform.InverseTransformDirection(Vector3.up));
transform.localRotation *= Rotation;
}
else if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
dir.z -= 1.0f;
else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
var Rotation = Quaternion.AngleAxis("Rotation Angle Here", transform.InverseTransformDirection(Vector3.up));
transform.localRotation *= Rotation;
}
dir.Normalize();
transform.Translate(dir * CharacterSpeed * Time.deltaTime);
You can use Transform.forward to get the facing direction in world space, then simply scale, and add up to the current position. Just hook up this to W:
this.transform.position += this.transform.forward * 0.043f;
I am trying to build an asteroids style game in Unity and could really use some help. I believe all my math is correct as far as the ship movement but I am having trouble getting it to work inside Unity. I am having a couple different problems.
The ship does not update with velocity ( if you start moving and then let go, it will stand still)
I am unsure in Unity how to set the ships rotation to my specific angle.
Any help would be greatly appreciated.
public class playerController : MonoBehaviour {
public static float timer;
public static bool timeStarted = false;
Vector2 accel;
Vector2 velocity;
float direction;
float angle;
float shotCooldown;
float speed;
const float pi = 3.141592f;
const float maxSpeed = 300;
const float maxAccel = 500;
void Start () {
timeStarted = true;
}
void Update () {
if (timeStarted == true) {
timer += Time.deltaTime;
}
shotCooldown -= (timer%60);
angle = direction * pi / 180;
if (Input.GetKey(KeyCode.W)) {
accel.y = -Mathf.Cos(angle) * maxAccel;
accel.x = Mathf.Sin(angle) * maxAccel;
velocity += accel * Time.deltaTime;
}
if (Input.GetKey(KeyCode.S)) {
accel.y = -Mathf.Cos(angle) * maxAccel;
accel.x = Mathf.Sin(angle) * maxAccel;
velocity -= accel * Time.deltaTime;
}
if (Input.GetKey(KeyCode.Space)) {
if (shotCooldown <= 0)
{
// Create new shot by instantiating a bullet with current position and angle
shotCooldown = .25f;
}
}
if (Input.GetKey(KeyCode.D)) {
direction += 360 * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A)) {
direction -= 360 * Time.deltaTime;
}
/*
if (this.transform.position.x >= Screen.width && velocity.x > 0) {
this.transform.position.x = 0;
}*/
while (direction < 0) {
direction += 360;
}
while (direction > 360) {
direction -= 360;
}
speed = Mathf.Sqrt( (velocity.x * velocity.x) + (velocity.y * velocity.y));
if (speed > maxSpeed) {
Vector2 normalizedVector = velocity;
normalizedVector.x = normalizedVector.x / speed;
normalizedVector.y = normalizedVector.y / speed;
velocity = normalizedVector * maxSpeed;
}
this.transform.position = velocity * Time.deltaTime;
transform.rotation = Quaternion.AngleAxis(0, new Vector3(0,0,angle));
}
}
It's usually a bad idea to set the position the way you are, because you're not actually using any physics. The way you're doing it, velocity is a new position for the ship, not a speed. Once you let go of the keys, it stops calculating new positions, and thus stops moving.
There are a couple of alternatives which would make for a better result:
1) One way this can be done is by calling: transform.Translate(Vector3.forward * speed * Time.deltaTime) Vector3.forward should correspond to the direction you consider as "forward", but if not, you can change it to whichever works (eg Vector3.up). This means you only really need to calculate a speed and let unity hangle the rest.
2) If you're using a rigidbody on your ship, you could simply do:
rigidbody.AddForce(Vector3.forward * speed * Time.deltaTime) which will automatically accelerate the ship in the given direction by whatever speed you give it.
As for rotation, perhaps try something like this:
if (Input.GetKey(KeyCode.D))
{
Vector3 newRotation = transform.rotation.eulerAngles;
newRotation.z += 10;
transform.rotation = Quaternion.Euler (newRotation);
}
else if (Input.GetKey(KeyCode.A))
{
Vector3 newRotation = transform.rotation.eulerAngles;
newRotation.z -= 10;
transform.rotation = Quaternion.Euler (newRotation);
}
I'm new to programming in C# in Unity and there is some problems when moving in the z-axis. The problem is that I continue to move when I let go of the up button. However, when I move in the x-axis it is fine, as letting go of the button will stop the player. The code is below:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public Vector3 motion = new Vector3();
private CharacterController controller;
private bool onGround;
private float xRot, yRot;
public static float X_ROTATION = 0;
public static float Y_ROTATION = 0;
private const float lookSpeed = 2.0f;
public void Start() {
controller = GetComponent<CharacterController>();
}
public void FixedUpdate() {
if(Screen.lockCursor) {
Vector3 impulse = new Vector3();
if(Input.GetKey(KeyCode.W)) impulse.z+=1;
if(Input.GetKey(KeyCode.A)) impulse.x-=1;
if(Input.GetKey(KeyCode.S)) impulse.z-=1;
if(Input.GetKey(KeyCode.D)) impulse.x+=1;
if(impulse.sqrMagnitude > 0) {
motion += Quaternion.Euler(new Vector3(0, xRot, 0)) * impulse.normalized * 0.05f;
}
if(onGround) {
if(Input.GetKey(KeyCode.Space)) {
motion.y += 0.2f;
}
}
motion.y -= 0.015f;
Vector3 oldMotion = motion;
Vector3 oldPos = controller.transform.localPosition;
controller.Move(motion);
Vector3 newPos = controller.transform.localPosition;
motion = newPos - oldPos;
onGround = oldMotion.y < -0.0001f && motion.y >= -0.0001f;
motion.x *= 0.8f;
motion.y *= 0.8f;
}
}
public void Update() {
if(Screen.lockCursor && Input.GetKeyDown(KeyCode.Escape)) {
Screen.lockCursor = false;
}
if(!Screen.lockCursor && Input.GetMouseButtonDown(0)) {
Screen.lockCursor = true;
}
if(Screen.lockCursor) {
xRot += Input.GetAxis("Mouse X") * lookSpeed;
yRot -= Input.GetAxis("Mouse Y") * lookSpeed;
if(yRot < -90) yRot = -90;
if(yRot > 90) yRot = 90;
if(xRot < -180) xRot += 360;
if(xRot >= 180) xRot -= 360;
controller.transform.localRotation = Quaternion.Euler(new Vector3(yRot, xRot, 0));
}
Player.X_ROTATION = xRot;
}
}
The last few statments in FixedUpdate() where you have coded-
motion.x *= 0.8f;
motion.y *= 0.8f;
should also contain
motion.z *= 0.8f;
and may be u dont need-
motion.y *= 0.8f;
As Gkills said, you should fix the "depletion" of motion.y for motion.z at the end.
Additionally, you should probably want to swap
motion += Quaternion.Euler(new Vector3(0, xRot, 0)) * impulse.normalized * 0.05f;
for
motion += transform.rotation * impulse.normalized * 0.05f;
Then zero out the impulse.y component to prevent the player flying.
Finally you might want to use Time.deltaTime in your Update (so mouse look is frame rate independent)