So....i worked on some code that makes your rocket rotate when you press space
and added a force to the right and it seems like as you go more the velocity increases, why is that?
Sorry for my exprimation, I'm a beginner in unity and programming so..dodon't judge me
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerMovement: MonoBehaviour
{
private float gravity;
public float moveSpeed = 20f;
private Rigidbody2D rb;
private Vector2 startPos;
public Vector2 velocity;
public static PlayerMovement Instance
{
get;
set;
}
// Start is called before the first frame update
private void Start()
{
Instance = this;
startPos = transform.position;
rb = GetComponent < Rigidbody2D > ();
gravity = rb.gravityScale;
}
// Update is called once per frame
private void Update()
{
Vector2 vel = rb.velocity;
float ang = Mathf.Atan2(vel.y, x: 30) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(x: 0, y: 0, z: ang - 90));
rb.AddForce( - velocity * Time.deltaTime, ForceMode2D.Impulse);
rb.AddForce(Vector2.right * 500 * Time.deltaTime);
if (Input.GetKey(KeyCode.Space)) {
rb.AddForce(Vector2.up * 3000 * gravity * Time.deltaTime);
}
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Obstacle")
{
Die();
}
}
void Die()
{
SceneManager.LoadScene(0);
}
}
RigidBody.AddForce is the reason, whenever you using it, it add a force to your game object, and you do this on each frame.
Related
I have a Player (made out of an cylinder, some FirstCam, SecondCam and ThirdCam, for switching views when pressing a certain key - doesn't matter), which is located on a cube (wide enough to take a walk on it). There's nothing else below the cube.
This is how it looks like:
This is the Player's structure:
This is the inspector for Player:
I have the following script ResetToInitial.cs, attached to my Player:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ResetToInitial : MonoBehaviour {
Vector3 pos;
void Start() {
pos = transform.position;
}
void Update() {
if (transform.position.y < -10) {
transform.position = pos;
}
}
}
and also some movement script PlayerMovement.cs that allows him to move up, down, left, right, jump and sprint.
This is PlayerMovement.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PlayerMovement : MonoBehaviour {
public CharacterController controller;
Vector3 velocity;
bool isGrounded;
public Transform groundCheck;
public LayerMask groundMask;
public TextMeshPro State;
public TextMeshPro State2;
public TextMeshPro State3;
// Start is called before the first frame update
void Start() {
}
// Update is called once per frame
void Update() {
float groundDistance = 0.4f;
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0) {
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
float g = -20f;
float jumpHeight = 1f;
float speed = 6f;
if (Input.GetKey(KeyCode.LeftShift)) {
speed = 8f;
State.text = "running mode";
State2.text = "running mode";
State3.text = "running mode";
} else {
speed = 5f;
State.text = "walking mode";
State2.text = "walking mode";
State3.text = "walking mode";
}
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if (Input.GetButton("Jump") && isGrounded) {
velocity.y = Mathf.Sqrt(jumpHeight * -2f * g);
}
velocity.y += g * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
ResetToInitial.cs is intended to teleport the Player to the initial position (back on the cube, the position recorded when the scene loads), after he falls of the cube. The problem is transform.position won't move the player anywhere. It won't do anything. I tried to output something in the last if to see if it works, and the output was printed, but still no teleportation happened.
What could be the problem?
FIRST : SORRY FOR MY ENGLISH !!!
Hello everyone, i'm very new into Unity (5 days).
Today i've make a script for the basics movements with a rigid-bodie, BUT the diagonal movements are faster than the normal movements.. I search on Internet but I don't find a post that i can understand.
So here my script.
Also if you know how to not move when we jump, or when we jump into a direction, it follow this direction, tell me. (I know my english is terrible.) Also, i'm new into this website.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovements : MonoBehaviour
{
[SerializeField] private float walkingSpeed;
[SerializeField] private float runningSpeed;
[SerializeField] private float jumpForce;
[SerializeField] private float jumpRaycastDistance;
private Rigidbody rb;
float speed;
Vector3 movement;
/////////////////////////////////////////////////////
void Start()
{
rb = GetComponent<Rigidbody>();
}
/////////////////////////////////////////////////////
void Update()
{
Jumping();
}
/////////////////////////////////////////////////////
private void FixedUpdate()
{
Movements();
}
/////////////////////////////////////////////////////
private void Movements()
{
float hAxis = Input.GetAxisRaw("Horizontal");
float vAxis = Input.GetAxisRaw("Vertical");
if(Input.GetButton("Run"))
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * runningSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
else
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * walkingSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
}
/////////////////////////////////////////////////////
private void Jumping()
{
if(Input.GetButtonDown("Jump"))
{
if (isGrounded())
{
rb.AddForce(0, jumpForce, 0, ForceMode.Impulse);
}
}
}
/////////////////////////////////////////////////////
private bool isGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, jumpRaycastDistance);
}
}
You need to clamp your velocity in order to keep it same. Look into Vector3.ClampMagnitude()
velocity = Vector3.ClampMagnitude(velocity, _movementSpeed);
velocity.y = playerVelocity.Y; // keeping your Y velocity same since you have jumping.
playerVelocity = velocity;
EDIT: in your case it should be something like this.
_maxSpeed is the speed limit.
private void FixedUpdate()
{
Movements();
var clampedVelocity = Vector3.ClampMagnitude(rb.velocity, _maxSpeed);
clampedVelocity.y = rb.velocity.y;
rb.velocity = clampedVelocity;
}
Try normalizing the vector. (more info is on unity docs, but normalize() will make sure that the sum of all the vector's values isnt above 1.
I have a script that has the enemy move towards the player at the same speed, but I am trying to make the enemy slow down then accelerate when he is switching directions. The enemy currently just moves left and write towards the player's position.
Here is my code from the script that my boss is attached to in the update function:
Vector2 targetPosition = new Vector2 (player.transform.position.x, transform.position.y);
transform.position = Vector2.MoveTowards (transform.position, targetPosition, moveSpeed * Time.deltaTime);
I have also tried using Lerp and using the transform.position as the first parameter, but the boss goes slower when the player is closer, and faster when the player is faster away.
transform.position = Vector2.Lerp (transform.position, targetPosition, moveSpeed * Time.deltaTime);
Does anyone know how to make the enemy slow down, then gradually increase his speed as he change direction, then return to normal speed after he has finished changing directions
**EDIT: ** full script below
using UnityEngine;
public class Roll : StateMachineBehaviour
{
[SerializeField] private float moveSpeed = 2.4f;
[SerializeField] private float rotateSpeed = 100f;
[SerializeField] private float minRollTime = 6f;
[SerializeField] private float maxRollTime = 8f;
private float rollTimer = 0f;
[SerializeField] private float rightBoundary = 5f;
[SerializeField] private float leftBoundary = -5f;
private Transform playerTransform = null;
private BossHealth bossHealth = null;
private Transform bossTransform = null;
private Transform bodyTransform = null;
private Transform earsTransform = null;
private Vector2 targetPosition = Vector2.zero;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
playerTransform = GameObject.FindWithTag("Player").transform;
bossHealth = animator.GetComponent<BossHealth>();
Boss01 boss = FindObjectOfType<Boss01>();
bossTransform = boss.bossTransform;
bodyTransform = boss.bodyTransform;
earsTransform = boss.earsTransform;
rollTimer = Random.Range (minRollTime, maxRollTime);
}
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (bossTransform.position.x >= leftBoundary && bossTransform.position.x <= rightBoundary)
{
targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);
if (playerTransform.position.x > 0)
bodyTransform.Rotate(0f, 0f, -rotateSpeed * Time.deltaTime);
else
bodyTransform.Rotate(0f, 0f, rotateSpeed * Time.deltaTime);
}
else if (bossTransform.position.x < leftBoundary)
{
if (playerTransform.position.x > bossTransform.position.x)
{
targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);
}
}
else
{
if (playerTransform.position.x < bossTransform.position.x)
{
targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);
}
}
if (rollTimer <= 0f)
animator.SetTrigger ("aim");
else
rollTimer -= Time.deltaTime;
if (bossHealth.CheckHealth())
animator.SetTrigger ("transition");
if (earsTransform.rotation != Quaternion.Euler (0f, 0f, 0f))
earsTransform.rotation = Quaternion.Slerp(earsTransform.rotation, Quaternion.Euler(0f, 0f, 0f), 1f * Time.deltaTime);
}
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.ResetTrigger ("aim");
animator.ResetTrigger ("transition");
}
}
To achieve the position (meters/second) you multiply the speed * Time.deltatime, so you achieve the meters. To handle acceleration, you need to handle variable speed. Acceleration is m/s2, multiplied * Time.deltatime you will have the instant speed, and that speed * Time.deltaTime will give you the position.
Here some pseudocode (step and speed should be class varibles and this modifieed in the update. accel is the constant acceleration, that should be constans for the simplicity's sake, I guess that you need uniformingly accelerated movement):
speed += accel * Time.deltaTime; // instant speed
step = speed * Time.deltaTime; // calculate distance to move
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
With the sign of the accel + or - you will determine if the entities speed is increasing (accelerating) or decreasing (decelerating).
Hope that helps
Edit:
Full script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveTowards : MonoBehaviour
{
public Transform target;
private float step = 0f;
private float speed = 0f;
public float accel = 0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
speed += accel * Time.deltaTime; // instant speed
step = speed * Time.deltaTime; // calculate distance to move
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
}
Screenshot of script attached in editor:
Attached the script to the game object you want to move, and attach the transform of the target in the public fielld. The choose your acceleration, positive to accelerate towards an negative to accelerate backwars, and there you got it.
I want to be able to jump by pressing on space key inside a place like home or space station and also outside.
This is the player controller script attached to a capsule :
It was working fine until I added the jump part. At the top I added this 3 lines :
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
Then in the Update added :
if (controller.isGrounded && Input.GetButton("Jump"))
{
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
But I don't have the variable controller.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 10.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
float translation = Input.GetAxis("Vertical") * speed;
float straffe = Input.GetAxis("Horizontal") * speed;
translation *= Time.deltaTime;
straffe *= Time.deltaTime;
transform.Translate(straffe, 0, translation);
if (controller.isGrounded && Input.GetButton("Jump"))
{
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
if (Input.GetKeyDown("escape"))
{
Cursor.lockState = CursorLockMode.Locked;
}
}
}
And this is the cam mouse look script attached to the main camera that is child of the capsule :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamMouseLook : MonoBehaviour
{
public float sensitivity = 5.0f;
public float smoothing = 2.0f;
Vector2 mouseLook;
Vector2 smoothV;
GameObject character;
// Start is called before the first frame update
void Start()
{
character = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update()
{
var md = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
md = Vector2.Scale(md, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, md.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, md.y, 1f / smoothing);
mouseLook += smoothV;
mouseLook.y = Mathf.Clamp(mouseLook.y, -90f, 90f);
transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);
character.transform.localRotation = Quaternion.AngleAxis(mouseLook.x, character.transform.up);
}
}
Have you thought about applying a force?
public Rigidbody myphysic;
public float forceofjump = 100f; // or minor or more....
void Awake()
{
myphysic= transform.GetComponent<Rigidbody>();
}
void FixedUpdate()
{
if (controller.isGrounded && Input.GetButton("Jump"))
{
myphysic.AddForce( transform.up * forceofjump, ForceMode.Impulse);
}
}
Vector3.zero is wrong beacouse set all movement vector to zero! so = no actions!
or, exemple:
Vector3 moveDirection = new Vector3(0, 10, 0);
what does it mean:
new Vector3(X=stop, Y=10 of force, Z=stop);
I am doing a 2d game and I want to know how I can make the bullets to shoot right and left . At this moment the bullets go just to the left , even if my player moves right. How I can make them shoot both sides or shoot just when they find an object tagged " enemy "
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class Character : MonoBehaviour
{
Rigidbody2D rb;
float dirX;
[SerializeField]
float moveSpeed = 5f, jumpForce = 400f, bulletSpeed = 500f;
Vector3 localScale;
public Transform barrel;
public Rigidbody2D bullet;
// Use this for initialization
void Start()
{
localScale = transform.localScale;
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
dirX = CrossPlatformInputManager.GetAxis("Horizontal");
if (CrossPlatformInputManager.GetButtonDown("Jump"))
Jump();
if (CrossPlatformInputManager.GetButtonDown("Fire1"))
Fire();
}
void FixedUpdate()
{
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
}
void Jump()
{
if (rb.velocity.y == 0)
rb.AddForce(Vector2.up * jumpForce);
}
void Fire()
{
var firedBullet = Instantiate(bullet, barrel.position, barrel.rotation);
firedBullet.AddForce(barrel.up * bulletSpeed);
}
}
You're already accounting for the direction of the barrel. You just need to change the direction of the barrel when you move.
One way to do that is to just set that directly:
// Update is called once per frame
void Update()
{
dirX = CrossPlatformInputManager.GetAxis("Horizontal");
if (dirX !=0)
{
barrel.up = Vector3.right * Mathf.Sign(dirX);
}
if (CrossPlatformInputManager.GetButtonDown("Jump"))
Jump();
if (CrossPlatformInputManager.GetButtonDown("Fire1"))
Fire();
}
If the barrel is a child of the player object, then changing the character's rotation so that the barrel's direction points in the correct direction will also work. There's not enough information in the question to know for sure but maybe using Quaternion.LookRotation to set the character's rotation like so would work:
// Update is called once per frame
void Update()
{
dirX = CrossPlatformInputManager.GetAxis("Horizontal");
if (dirX !=0)
{
Vector3 newPlayerForward = Vector3.forward * Mathf.Sign(dirX);
transform.rotation = Quaternion.LookRotation(newPlayerForward, Vector3.up);
}
if (CrossPlatformInputManager.GetButtonDown("Jump"))
Jump();
if (CrossPlatformInputManager.GetButtonDown("Fire1"))
Fire();
}