How to move forward an object in Unity? - c#

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);
}

Related

Unity C# - Move character while jumping

My character moves great, and jumps great. But when jumping he just moves straight in the direction he came from and you can't rotate or move him while in the air. How can that be done?
From the Update Function:
if (controller.isGrounded)
{
moveD = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
moveD = transform.TransformDirection(moveD.normalized) * speed;
moveDA = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
if (moveDA.magnitude > 0)
{
gameObject.transform.GetChild(0).LookAt(gameObject.transform.position + moveDA, Vector3.up);
}
if (Input.GetButton("Jump"))
{
moveD.y = jumpSpeed;
}
}
moveD.y = moveD.y - (gravity * Time.deltaTime);
controller.Move(moveD * Time.deltaTime);
controller.isGrounded Is only true if the last time you called controller.Move() the bottom of the object's collider is touching a surface, so in your case once you jump, you cannot move until you hit the ground again.
You can solve this by separating your movement code and jumping code like so:
moveD = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
moveD = transform.TransformDirection(moveD.normalized) * speed;
moveDA = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
if (moveDA.magnitude > 0)
{
gameObject.transform.GetChild(0).LookAt(gameObject.transform.position + moveDA, Vector3.up);
}
if (controller.isGrounded)
{
if (Input.GetButton("Jump"))
{
moveD.y = jumpSpeed;
}
}
moveD.y = moveD.y - (gravity * Time.deltaTime);
controller.Move(moveD * Time.deltaTime);

Unity Player's Shoot Function Will Not Work

I am creating a game in Unity. I have so far been able to get my player to follow the mouse at a somewhat correct angle. I am also trying to implement a shooting function for the character that shoots from the correct angle (straight from the top of the player, toward the mouse at the time of shooting). When I click using this code, nothing happens. I have objects set up for player, bullet and fire Point.
public void Update()
{
if (FollowMouse || Input.GetMouseButton(0))
{
_target = Camera.ScreenToWorldPoint(Input.mousePosition);
_target.z = 0;
}
var delta = ShipSpeed * Time.deltaTime;
var bulletDelta = shootSpeed * Time.deltaTime;
bulletDelta *= Vector3.Distance(transform.position, _target);
if (ShipAccelerates)
{
delta *= Vector3.Distance(transform.position, _target);
}
angle = Mathf.Atan2(_target.y, _target.x) * Mathf.Rad2Deg;
transform.position = Vector3.MoveTowards(transform.position, _target, delta);
transform.rotation = Quaternion.Euler(0, 0, angle);
if (Input.GetMouseButtonDown(0) && Time.time > nextFire && numOfBullets > 0)
{
nextFire = Time.time + fireRate;
Instantiate(bullet, firePoint.position, firePoint.rotation);
numOfBullets--;
bullet.transform.position = Vector3.MoveTowards(bullet.transform.position, _target, bulletDelta);
}
}

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 :)

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

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!

Unity2D Asteroids style game

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);
}

Categories