I halfway have no idea what I am doing. Trying to get the player to walk around but instead it rotates and then flies in the direction of the trigger instead. I don't know how to fix this. Here's my code, I hope someone can figure out whats going on cause I can't. It may be a problem in the ridged body but again, no idea how to fix that
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Rigidbody playerRb;
private Animator playerAnim;
public float jumpForce;
public float gravityModifier;
public bool isOnGround = true;
public bool gameOver = false;
public ParticleSystem explosionParticle;
public ParticleSystem dirkParticle;
public AudioClip jumpSound;
public AudioClip crashSound;
private AudioSource playerAudio;
public float speed;
// Start is called before the first frame update
void Start()
{
playerRb = GetComponent<Rigidbody>();
playerAnim = GetComponent<Animator>();
Physics.gravity *= gravityModifier;
playerAudio = GetComponent<AudioSource>();
}
// Update is called once per frame
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
playerRb.AddForce(Vector3.forward * speed * verticalInput);
playerRb.AddForce(Vector3.right * speed * horizontalInput);
if (Input.GetKeyDown(KeyCode.Space) && isOnGround) {
playerRb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isOnGround = false; //Makes sure you cannot jump in the air
playerAnim.SetTrigger("Jump_trig");
dirkParticle.Stop();
playerAudio.PlayOneShot(jumpSound, 1.0f);
}
}```
If you are using a Rigidbody to apply any force or velocity to the player, it doesn't appear as if the player is walking or running, it appears as if some external force is pushing the player in that direction. Hence, use CharacterController to move the player.
Add the CharacterController component to the player in the inspector. In the script, initialize the CharacterController and get a reference to that component
private CharacterController cc;
void Start() {
cc = GetComponent<CharacterController>();
}
Move the player in Update() method.
void Update() {
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
// move the cc
Vector3 move = new Vector3(horizontalInput, 0, verticalInput);
cc.Move(move * speed * Time.deltaTime);
}
Related
I am new to Unity and I was working on the enemy's movement of my first video game with C#.
The thing is that whenever the enemy follows the main character, it moves in a very jittery way and I do not know why. I tried a lot of solutions including a different code approach but notthing worked. I tried changing some configurations in its rigid body like collision detection but nothing happend.
This is the code of my enemy:
public class Black : Enemy
{
public float checkRadius;
public float attackRadius;
public bool shouldRotate;
public LayerMask lm;
private Rigidbody2D bd;
private Vector2 movement;
public Vector3 dir;
private bool isInchaseRange;
private bool isInattackRange;
// Start is called before the first frame update
void Start()
{
Debug.Log("Jugador " + player.name);
bd = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
isInchaseRange = Physics2D.OverlapCircle(transform.position, checkRadius, lm);
isInattackRange = Physics2D.OverlapCircle(transform.position, attackRadius, lm);
dir = player.position - transform.position;
dir.Normalize();
movement = dir;
}
void FixedUpdate() {
if (isInchaseRange && !isInattackRange) {
MoveCharacter(movement);
}
if (isInattackRange)
{
bd.velocity = Vector2.zero;
}
}
private void MoveCharacter(Vector2 dir) {
transform.position = Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
}
}
This is how I move my main character if it helps you
public class PlayerMovement : MonoBehaviour
{
public float speed;
private Rigidbody2D rb;
private Vector2 moveAmount;
public float health;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveAmount = moveInput.normalized * speed;
}
void FixedUpdate()
{
move();
}
void move()
{
rb.MovePosition(rb.position + moveAmount * Time.fixedDeltaTime);
}
public void takeDamage(int damageAmount)
{
health -= damageAmount;
if (health <= 0)
{
Destroy(gameObject);
}
}
}
The character has the same stuff as the enemy: Script, box collider 2d, rigid body
Any ideas on how to solve this?
As you can see by the gif it is not working as it should
https://im2.ezgif.com/tmp/ezgif-2-fbffacda5a27.gif
Thanks
Try making the chase range huge and attack range very small and see if it still moves in a jittery way to make sure it's not jittering because it's going in and out of range very quickly.
Set Rigidbody2D to interpolate from the inspector.
Also for the player, use Time.deltaTime instead of Time.fixedDeltaTime. Although this probably isn't related to your problem, this will give more smooth movement for the player. Time.fixedDeltaTime is just for setting the target you want the unity to stay at, but it will never precisely achieve that frametime. And Time.deltaTime will return the correct value based on whether it's called from Update() or FixedUpdate()
When this is called from inside MonoBehaviour.FixedUpdate, it returns Time.fixedDeltaTime. - Unity Docs
I'm trying to make a basic FPS game in Unity and I'm having an issue where the projectiles I shoot won't instantiate in the right place. From what I can tell, the projectile instantiates in roughly the same position relative to the player regardless of where I look (that position being a little to the left of the starting angle of the player).
Here's a 20 second video demonstration of what I'm talking about.
https://youtu.be/WLVuqUtMqd0
Even when I'm facing the exact opposite direction of where the projectile usually instantiates it still spawns in the same place, which means the projectile ends up spawning behind the player and hitting the player.
I tried using Debug.DrawRay() to see if maybe the firepoint itself is wrong (which would be shown by the ray starting somewhere other than the gun barrel). However it seems like the starting point of the ray is correct every time.
I'm not sure if this is related to the issue above, but I have noticed that the ray direction is wrong if I'm looking a little below the horizon. It seems like the projectile's direction is correct regardless though.
Ray directions when looking slightly above the horizon vs. lower
Here's my code for intantiating/shooting the projectile. I think the most relevant parts are probably shootProjectile() and instantiateProjectile(). This script is attached to the player character.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooting : MonoBehaviour
{
public Camera cam;
public GameObject projectile;
public Transform firePoint;//firePoint is set to the end of the barrel.
public float projectileSpeed = 40;
//private var ray;
private Vector3 destination;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//var ray = cam.ViewportPointToRay(new Vector3(0.5f,0.5f,0));
//Debug.DrawRay(ray.origin, ray.direction);
if(Input.GetButtonDown("Fire1")) {
//player is shooting
ShootProjectile();
}
}
void ShootProjectile() {
Ray ray1 = cam.ScreenPointToRay(Input.mousePosition);
//Debug.Log(ray.direction);
RaycastHit hit;
if(Physics.Raycast(ray1, out hit))//checking whether the player is going to hit something
{
destination = hit.point;
}
else {
destination = ray1.GetPoint(1000);
}
Debug.DrawRay(firePoint.position, destination, Color.white, 10f);
InstantiateProjectile(firePoint);
}
void InstantiateProjectile(Transform firePoint) {
var projectileObj = Instantiate (projectile, firePoint.position, Quaternion.identity) as GameObject;//projectile is instantiated
projectileObj.GetComponent<Rigidbody>().velocity = (destination - firePoint.position).normalized * projectileSpeed;//projectile is set in motion
}
}
Here's the location of firePoint.
firePoint (i.e. where the projectile should instantiate)
I would appreciate any help on this, as I've been trying to fix it (on and off) for several days, and really have no idea what the problem is.
Edit: Here's my player movement script(s) as well. The first one is PlayerController.cs, and it converts the player's inputs into the appropriate movement vectors and camera rotation. It then calls methods from PlayerMotor.cs, which actually performs the movements.
PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(PlayerMotor))]
public class PlayerController : MonoBehaviour
{
[SerializeField]
public float speed = 10f;
[SerializeField]
private float lookSens = 3f;
private PlayerMotor motor;
void Start() {
motor = GetComponent<PlayerMotor>();
//Debug.Log("PlayerControllerStart");
Cursor.lockState = CursorLockMode.Locked;
}
void Update() {
//Debug.Log("PlayerControllerUpdate");
//calculate movement velocity as 3D vector.
float xMov = Input.GetAxisRaw("Horizontal");
float zMov = Input.GetAxisRaw("Vertical");
Vector3 movHorizontal = transform.right * xMov;
Vector3 movVertical = transform.forward * zMov;
Vector3 velocity = (movHorizontal + movVertical).normalized * speed;
motor.move(velocity);
//speed*=(float)1.15;
//rotation
float yRot = Input.GetAxisRaw("Mouse X");
Vector3 rotation = new Vector3 (0f, yRot, 0f) * lookSens;
motor.rotate(rotation);
float xRot = Input.GetAxisRaw("Mouse Y");
Vector3 cameraRotation = new Vector3 (xRot, 0f, 0f) * lookSens;
motor.rotateCamera(cameraRotation);
if (Input.GetKeyDown(KeyCode.Space) == true && motor.isGrounded()) {
motor.canJump=true;
}
if (Input.GetKey(KeyCode.W) == true) {
motor.accel=true;
}
else{
motor.accel=false;
}
}
}
PlayerMotor:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMotor : MonoBehaviour
{
[SerializeField]
private Camera cam;
private Vector3 velocity = Vector3.zero;
private Vector3 rotation = Vector3.zero;
private Vector3 cameraRotation = Vector3.zero;
private Vector3 jumpVector = new Vector3 (0f, 5f, 0f);
private PlayerController pc;
private Rigidbody rb;
public bool canJump;
public bool accel;
public float acceleration;
int jumpCount;
void Start() {
rb = GetComponent<Rigidbody>();
pc = GetComponent<PlayerController>();
canJump=false;
jumpCount=0;
accel=false;
//acceleration = 1.0;
//distToGround = collider.bounds.extents.y;
//Debug.Log("PlayerMotorStart");
}
//sets velocity to a given movement vector.
public void move(Vector3 _velocity) {
velocity = _velocity;
}
public void rotate(Vector3 _rotation) {
rotation = _rotation;
}
public void rotateCamera(Vector3 _cameraRotation) {
cameraRotation = _cameraRotation;
}
public bool isGrounded() {
return Physics.Raycast(transform.position, -Vector3.up, (float)2.5);
}
public void jump() {
rb.AddForce(transform.up * 250f);
//Debug.Log("Jump"+jumpCount);
jumpCount++;
canJump=false;
}
void FixedUpdate() {
performMovement();
performRotation();
if (canJump) {
jump();
}
//Debug.Log("PlayerMotorUpdate");
if(accel&&pc.speed<20f&&isGrounded())
{
//Debug.Log("W Pressed");
pc.speed*=(float)1.005;
}
else if(!accel) {
pc.speed=7f;
}
}
void performMovement() {
if(velocity != Vector3.zero) {
rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
//Debug.Log("Movement");
}
}
void performRotation() {
rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation));
if(cam != null) {
cam.transform.Rotate(-cameraRotation);
}
}
}
Here are some pictures of my projectile prefab as well.
To solve one first confusion: The method Debug.DrawRay takes as paramters
a start position
a ray direction(!)
You are passing in another position which is not what you want.
This might only work "accidentally" as long as you stand on 0,0,0 so maybe it wasn't that notable but the debt ray definitely points into a wrong direction.
Rather do e.g.
Debug.DrawRay(firePoint.position, destination - firePoint.position, Color.white, 10f);
Or instead rather use Debug.DrawLine which rather actually takes
start position
end position
Then you don't need to calculate the direction first
Debug.DrawLine(firePoint.position, destination, Color.white, 10f);
Then I suspect the following is happening: The spawned projectileObj actually is placed correctly but it is the visuals inside that projectile prefab that have a local offset against the parent prefab root.
Since you always spawn the projectile in world rotation Quaternion.identity that offset stays the same no matter where you look.
I guess a simple fix would already be to also apply the same rotation like
var projectileObj = Instantiate (projectile, firePoint.position, firePoint.rotation);
I made it in my script so that the zombies will know where the player is and go after them but for some reason it tries to go to 0 0 0 and I don't know why. Please take a look at the script and tell me what is wrong.
(Sorry if the code is bad I am a noob)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZK_Attacking : MonoBehaviour
{
public Transform Player;
public float MoveSpeed = 3.5f;
public float AttackRange = 1.0f;
private Animator anim;
private void Start()
{
anim = GetComponent<Animator>();
Player = GameObject.Find("Player").transform;
}
void Update()
{
transform.LookAt(Player);
float dstSqr = (Player.position - transform.position).sqrMagnitude;
bool inAttackRange = (dstSqr <= AttackRange * AttackRange);
anim.SetBool("AttackingPlayer", inAttackRange);
transform.position = Vector3.MoveTowards(transform.position, Player.position, MoveSpeed * Time.deltaTime);
}
}
This line of code might be Player = GameObject.Find("Player").transform; return null or you may have changed this variable public float MoveSpeed = 3.5f; from another script or editor.
You shouldnt find player with "Gameobject.find". Instead of it, use
[SerializeField] private Transform player; drag and drop the player object in your inspector.
Code seems correct i've tried it. Some other things are wrong.
I've been trying to fix this player collision script that I have but I can't figure out why. It's supposed to stop the player from running through walls, but when my player runs up against a wall, it jiggles around a ton like the script isn't running fast enough. (This code is from Sebastian Lagues coding tutorial series.)
The script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollision : MonoBehaviour
{
Rigidbody myRigidbody;
public float speed = 5f;
Vector3 velocity;
// Start is called before the first frame update
void Start()
{
myRigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
Vector3 direction = input.normalized;
velocity = direction * speed;
}
void FixedUpdate() {
myRigidbody.position += velocity * Time.deltaTime;
}
void OnTriggerEnter(Collider triggerCollider) {
print(triggerCollider.gameObject.name);
}
}
When I enabled Interpolate on the player and used MovePosition, it jiggled even more.
Try setting the rigidbody's collisionDetectionMode to Continous
I would also remove your velocity variable and set myRigidbody.velocity in FixedUpdate, like so:
void Update() {
}
void FixedUpdate() {
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
Vector3 direction = input.normalized;
myRigidbody.velocity = direction * speed;
}
https://docs.unity3d.com/ScriptReference/CollisionDetectionMode.html
I'm working on a 2D game (for smartphone) which is automatically jumping, and I want to give a player movement (accelerometer) (a similar principle as doodle jump). How to make automatically jumping of 2D sprite? I tried to create an animation but it will not move using the accelerometer. So I coded script for automatically jump but it's not working. any help? (automatically jump means when player hits ground, jump again)
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
Rigidbody2D coll;
void Start(){
coll = GetComponent<Rigidbody2D>();
}
void Update() {
if (coll.gameObject.tag == "Ground") {
moveDirection = Vector3.zero;
moveDirection.x = 1;
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
}
}
So can someone give me script when player hit ground, player will jump? I want to move up and to the right.
Player object should have collider2D and rigidbody2D. Ground object should have collider2D and "Ground" tag. This code must be on player object.
public int power;
void Update()
{
transform.position = new Vector3(transform.position.x + Input.acceleration.x, transform.position.y, transform.position.z);
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.collider.gameObject.tag.Equals("Ground"))
{
rigidbody2D.AddForce(Vector2.up * power);
}
}
I hope it works.