Unity player facing wrong way - c#

I'm very new to unity and have followed a brackeys tutorial to get this. My movement script works, but the player is always facing the wrong direction, and I am unable to change this. I've made an empty gameobject, parented the model to it and put the script into it, but it still won't rotate.
Movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class MovementSystem : MonoBehaviour
{
private CharacterController controller;
public float positiveZForce = 200f;
public float negativeZForce = 175f;
public float xForce = 175f;
public float yForce = 125f;
Rigidbody rb;
public bool isGrounded;
void Start() {
rb = GetComponent<Rigidbody>();
}
void OnCollisionEnter(Collision other) {
if (other.gameObject.CompareTag("Ground")) {
isGrounded = true;
}
}
void FixedUpdate()
{
if (Input.GetKey("w")) {
rb.AddForce(0, 0, positiveZForce * Time.deltaTime);
}
if (Input.GetKey("s")) {
rb.AddForce(0, 0, -negativeZForce * Time.deltaTime);
}
if (Input.GetKey("a")) {
rb.AddForce(-xForce * Time.deltaTime, 0, 0);
}
if (Input.GetKey("d")) {
rb.AddForce(xForce * Time.deltaTime, 0, 0);
}
if (Input.GetKey("space")) {
if (isGrounded) {
rb.AddForce(0, yForce, 0);
isGrounded = false;
}
}
}
}

The most direct solution would be to call
transform.LookAt(transform.position + rb.velocity);
in your FixedUpdate function. This will cause your gameObject to rotate to face in the direction of its motion.

Related

Sprite not Appearing in Unity 2D Game

I'm creating a 2D Top Down game for practice and I need a little bit of help. For context, it's a 2D Top Down Shooter game, where you can move and shoot enemies. The enemies have a basic radius system where if the player gets within the radius, it'll approach the player.
Now I'm making a game mechanic where the player can hide in a cardboard box, the player can press 'E' and he'll suddenly become a cardboard box, where if the player is in the cardboard box, the enemy doesn't detect him even if the player's within the radius. Yes, just like in Metal Gear. Now I've created the prefabs and everything and functionality-wise, it works perfectly. If you press 'E' the enemy cannot detect you.
Now the small problem is that the cardboard box didn't appear, so it's just the player disappearing entirely. I do not know what caused this problem.
For context, these are my scripts. Feel free to read them, or not :)
PlayerController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
public GameObject bulletPrefab;
public GameObject player;
private Rigidbody2D rb2d;
private Vector2 moveDirection;
[SerializeField] private Camera cam;
[SerializeField] private GameObject gunPoint;
public bool isHiding = false;
[SerializeField] private GameObject cardboardBox;
[SerializeField] private GameObject gunSprite;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
cardboardBox.SetActive(false); // Hide the cardboard box when the game starts
gunSprite.SetActive(true); // Show the gun sprite when the game starts
}
// Update is called once per frame
void Update()
{
CheckCursor();
ProcessInputs();
// Make the camera follow the player
cam.transform.position = new Vector3(player.transform.position.x, player.transform.position.y, cam.transform.position.z);
// Check if player pressed the "E" key to toggle the cardboard box
if (Input.GetKeyDown(KeyCode.E))
{
isHiding = !isHiding; // Toggle the isHiding variable
cardboardBox.SetActive(isHiding); // Show/hide the cardboard box accordingly
// If player is hiding, stop player movement
if (isHiding)
{
moveDirection = Vector2.zero;
player.GetComponent<SpriteRenderer>().enabled = false;
cardboardBox.GetComponent<SpriteRenderer>().enabled = true;
gunSprite.SetActive(false); // Hide the gun sprite when the player is hiding
}
else
{
player.GetComponent<SpriteRenderer>().enabled = true;
cardboardBox.GetComponent<SpriteRenderer>().enabled = false;
gunSprite.SetActive(true); // Show the gun sprite when the player is not hiding
}
}
}
private void FixedUpdate()
{
if (!isHiding) // Only allow player to move if they are not hiding in the cardboard box
{
Movement();
}
}
private void CheckCursor()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 characterPos = transform.position;
if (mousePos.x > characterPos.x)
{
this.transform.rotation = new Quaternion(0, 0, 0, 0);
}
else if (mousePos.x < characterPos.x)
{
this.transform.rotation = new Quaternion(0, 180, 0, 0);
}
}
private void Movement()
{
// TODO : Implementasi movement player
rb2d.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
}
private void ProcessInputs()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY);
if (Input.GetMouseButtonDown(0))
{
Shoot();
}
}
private void Shoot()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 gunPointPos = gunPoint.transform.position;
Vector3 direction = (mousePos - gunPointPos).normalized;
GameObject bullet = Instantiate(bulletPrefab, gunPointPos, Quaternion.identity);
bullet.GetComponent<Bullet>().Init(direction);
}
}
EnemyController script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public Transform player;
public float moveSpeed = 5f;
public float detectionRadius = 5f;
public int maxHealth = 1;
private int currentHealth;
private Rigidbody2D rb2d;
private Vector2 movement;
private void Start()
{
rb2d = this.GetComponent<Rigidbody2D>();
currentHealth = maxHealth;
}
private void Update()
{
float distanceToPlayer = Vector2.Distance(transform.position, player.position);
if (player != null && distanceToPlayer <= detectionRadius && !player.GetComponent<PlayerController>().isHiding)
{
Vector3 direction = player.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb2d.rotation = angle;
direction.Normalize();
movement = direction;
}
else
{
movement = Vector2.zero;
}
}
void FixedUpdate()
{
moveCharacter(movement);
}
private void moveCharacter(Vector2 direction)
{
rb2d.MovePosition((Vector2)transform.position + (direction * moveSpeed * Time.deltaTime));
}
public void DestroyEnemy()
{
Destroy(gameObject);
}
}
Bullet script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField] private float speed;
[SerializeField] private Vector3 direction;
public void Init(Vector3 direction)
{
this.direction = direction;
this.transform.SetParent(null);
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg);
}
// Update is called once per frame
void Update()
{
this.transform.position += transform.right * speed * Time.deltaTime;
}
// TODO : Implementasi behaviour bullet jika mengenai wall atau enemy
private void OnTriggerEnter2D(Collider2D other)
{
switch(other.gameObject.tag)
{
case "Wall":
Destroy(gameObject);
break;
case "Enemy":
Destroy(gameObject);
other.gameObject.GetComponent<EnemyController>().DestroyEnemy();
break;
}
}
}
I've tried tinkering my scripts, I've tried checking if there are any missing components in the cardboard box game object but to no avail. Although I might be wrong on the Unity part since I'm fairly certain that the script isn't the problem here, again might be wrong.
I appreciate all the help I can get, thank you for reading until here

My Bullet is not getting instantiated where my Player is. It is getting instantiated from center only

I am new to Unity & on Stackoverflow. Need your help as I am stuck in this below mentioned situation.
When I spawn my projectile(Bullet), It should be instantiated at player's current position but It's not getting changed. The bullet is getting generated from Center only(Not from Player's position). Please advise. image is for reference
SpawnobjectController Script
public class SpawnobjectController : MonoBehaviour
{
[SerializeField]
GameObject projectilereference;
[SerializeField]
GameObject enemyreference;
[SerializeField]
GameObject playerreference;
void Start()
{
StartCoroutine(Enemycoroutine());
StartCoroutine(ProjectileCoroutine());
}
void SpawnProjectile()
{
Instantiate(projectilereference, new Vector3(playerreference.transform.position.x,projectilereference.transform.position.y,0.0f), Quaternion.identity);
}
IEnumerator ProjectileCoroutine()
{
while (true)
{
SpawnProjectile();
yield return new WaitForSeconds(2.0f);
}
}
IEnumerator Enemycoroutine()
{
while (true) {
SpawnEnemy();
yield return new WaitForSeconds(1.0f);
}
}
void SpawnEnemy()
{
Instantiate(enemyreference, enemyreference.transform.position, Quaternion.identity);
}
}
PlayerController Scripts
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
float _horizontalAxisPlayer;
float _playerSpeed = 5f;
float _maxXBoundry = 2.31f;
void Start()
{
}
void Update()
{
ControlPlayerBoundries();
PlayerMovement();
}
void PlayerMovement()
{
_horizontalAxisPlayer = Input.GetAxis("Horizontal")*_playerSpeed*Time.deltaTime;
transform.Translate(new Vector3(_horizontalAxisPlayer, 0.0f, 0.0f));
}
void ControlPlayerBoundries()
{
if (transform.position.x>_maxXBoundry)
{
transform.position = new Vector3(_maxXBoundry,transform.position.y,0.0f);
}
else if (transform.position.x<-_maxXBoundry)
{
transform.position = new Vector3(-_maxXBoundry, transform.position.y, 0.0f);
}
}
}
EnemyController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
[SerializeField]
private float enemeySpeed = 2f;
void Start()
{
}
void Update()
{
transform.Translate(Vector3.down * enemeySpeed * Time.deltaTime);
}
}
ProjectileController Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileController : MonoBehaviour
{
[SerializeField]
private GameObject Playerref;
[SerializeField]
private float projectile_speed = 2f;
void Start()
{
}
void Update()
{
// print(Playerref.transform.position);
}
private void LateUpdate()
{
transform.Translate(new Vector3(transform.position.x, 0.5f) * projectile_speed * Time.deltaTime);
}
}
Your problem is likely in the script that translates your bullet.
As the code you shared does exactly what you want. Assuming we are in a front view.
I have verified this by using your script and a copy of the enemy script in place of a bullet that moves them in Vector3.Up direction.
Edit:
You are creating a new vector with the transforms x and 0,5f that gets added every frame.
You either set transform.position or use Translate but with a direction only.
Moves the transform in the direction and distance of translation.
transform.Translate(Vector3 translation)
The following line would work instead.
private void LateUpdate()
{
transform.Translate(Vector3.up * projectile_speed* Time.deltaTime);
}

OnCollisionEnter2D and OnTriggerEnter2D not working

I am making a 2D camera follow script where if the player enters a collider it will test if that has the layer "waypoint" and if so the camera will go to the center of the gameobject with that collider in a smooth transition; however, when I try to test if the player is colliding with OnCollisionEnter2D it doesn't execute, I also tried OnTriggerEnter2D and that doesn't work either. I tested each with "is trigger" true, and false, and with a rigidbody set to kinematic. the only thing I haven't tried is adding a rigidbody with kinematic false, but I don't want to go through the trouble of having to make physics not effect the player with kinematic true.
Camera script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamFollow : MonoBehaviour
{
public Transform player;
public Transform playerFrame;
public List<GameObject> waypoints;
private bool hasWaypoints;
private bool inWaypoint;
private int waypointIn;
// Start is called before the first frame update
void Start()
{
hasWaypoints = true;
if (waypoints.Count == 0)
{
hasWaypoints = false;
}
inWaypoint = false;
waypointIn = 0;
}
// Update is called once per frame
void Update()
{
if (hasWaypoints)
{
if (inWaypoint)
Move(waypoints[waypointIn].transform.position);
else
MoveInFrame(player.position);
}
else
{
MoveInFrame(player.position);
}
}
void MoveInFrame(Vector3 moveTo)
{
Vector3 playerFrameRelative = playerFrame.position - transform.position;
transform.position = Vector3.MoveTowards(transform.position, moveTo - playerFrameRelative, 10);
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
}
void Move(Vector3 moveTo)
{
transform.position = Vector3.MoveTowards(transform.position, moveTo, 10);
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
}
public void Coll(Collider2D collision)
{
inWaypoint = true;
waypointIn = waypoints.IndexOf(collision.gameObject);
}
public void setWaypoint(bool b)
{
inWaypoint = b;
}
}
Player script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed = 9.53f;
public float jumpPower = 2.46f;
public float gravity = 0.65f;
public bool startsBackwards;
public GameObject camera;
public LayerMask layerMask;
private float upSpeed;
private int jumps;
private RaycastHit2D hit;
private Vector3 direction;
void Start()
{
if (startsBackwards)
direction = Vector3.left;
else
direction = Vector3.right;
}
void Update()
{
if (jumps < 3)
{
if (Input.GetKeyDown("w") || Input.GetKeyDown("up") || Input.GetKeyDown("space"))
{
upSpeed = jumpPower + gravity;
jumps--;
}
}
transform.Translate(direction * speed * Time.deltaTime);
upSpeed = upSpeed - gravity;
if (upSpeed < 0)
{
hit = Physics2D.BoxCast(transform.position, new Vector2(1, 1), 0, Vector2.down, -upSpeed, layerMask.value);
if (hit)
{
transform.Translate(Vector3.down * hit.distance);
jumps = 0;
upSpeed = 0;
}
else
transform.Translate(Vector3.up * upSpeed);
}
if (upSpeed > 0)
{
//hit = Physics2D.BoxCast(transform.position, new Vector2(1, 1), 0, Vector2.up, upSpeed);
if (false)
transform.Translate(Vector3.up * hit.distance);
else
transform.Translate(Vector3.up * upSpeed);
}
}
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Reverse")
{
if (direction == Vector3.right)
direction = Vector3.left;
else
direction = Vector3.right;
}
if (camera.GetComponent<CamFollow>().waypoints.Contains(collision.gameObject))
camera.GetComponent<CamFollow>().Coll(collision);
else
camera.GetComponent<CamFollow>().setWaypoint(false);
Debug.Log("worked!");
}
}
Help me please!!

Movement really slow in Unity

I'm working on a very basic side scrolling platformer in Unity 3D. The player is a cube, you can move left and right, you can jump. I can't get the movement correct as the character moves too slow.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float walkSpeed = 15f;
public float jumpSpeed = 15f;
public float gravity = 50f;
Rigidbody rb;
bool pressedJump = false;
Vector3 movementInput;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
movementInput = new Vector3(Input.GetAxis("Horizontal"), 0f, 0f);
}
void FixedUpdate()
{
WalkHandler();
JumpHandler();
GravityHandler();
}
void WalkHandler()
{
rb.velocity = new Vector2(0f, rb.velocity.y);
rb.velocity = movementInput * walkSpeed * Time.fixedDeltaTime;
}
void JumpHandler()
{
if (Input.GetButtonDown("Jump"))
{
if (!pressedJump)
{
pressedJump = true;
Vector3 jumpVector = new Vector3(0f, jumpSpeed, 0f);
rb.velocity = rb.velocity + jumpVector;
}
}
else
{
pressedJump = false;
}
}
void GravityHandler()
{
rb.AddForce(Vector3.down * gravity * rb.mass);
}
}
More context I originally had this implemented and it worked. Very smooth movement and jumping. I tragically lost that game due to my own actions. So I'm trying to recreate it. Here is a video of the original movement and jumping I'm looking to recreate:
My Progress so Far
Note: The values for walkSpeed, jumpForce and gravity were what was used previously.
Losing the first game was pretty soul crushing so any help would be great.
OK so I'm not sure how to recreate this using velocity but this seems to work:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float walkSpeed = 15f;
public float jumpSpeed = 15f;
public float gravity = 50f;
Rigidbody rb;
bool pressedJump = false;
float hAxis;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
hAxis = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
WalkHandler();
JumpHandler();
GravityHandler();
}
void WalkHandler()
{
rb.velocity = new Vector2(0f, rb.velocity.y);
Vector3 movement = new Vector2(hAxis * walkSpeed * Time.deltaTime, 0f);
rb.MovePosition(transform.position + movement);
}
void JumpHandler()
{
if (Input.GetButtonDown("Jump"))
{
if (!pressedJump)
{
pressedJump = true;
Vector3 jumpVector = new Vector3(0f, jumpSpeed, 0f);
rb.velocity = rb.velocity + jumpVector;
}
}
else
{
pressedJump = false;
}
}
// Check if the object is grounded
bool CheckGrounded()
{
return true;
}
void GravityHandler()
{
rb.AddForce(Vector3.down * gravity * rb.mass);
}
}
Ignore the CheckGrounded method

unity projectile spawns but doesn't pick up velocity?

This is my code does anyone know or can anyone spot why my projectile remains stationary once it's spawned in? the projectile is the prefab shell thanks for your help in advance.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab,
fireTransform.position,
fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.velocity = 15.0f * fireTransform.forward;
Debug.Log("velocity");
}
}
}
It is also generally discouraged to set the velocity of a rigidbody, but you can use the Rigidbody.AddForce() method to add force to a rigidbody. When you just want add force at the start, you can set the force mode in the function to impulse, like this rb.AddForce(Vector3.forward, ForceMode2D.Impulse);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankBehaviour : MonoBehaviour
{
public GameObject shellPrefab;
public Transform fireTransform;
private bool isFired = false;
public float bulletSpeed;
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
transform.position += transform.forward * y;
transform.Rotate(0, x, 0);
if (Input.GetKeyUp(KeyCode.Space) && !isFired)
{
Debug.Log("fire!");
Fire();
}
}
void Fire()
{
//isFired = true;
GameObject shellInstance = Instantiate(shellPrefab, fireTransform.position, fireTransform.rotation) as GameObject;
if (shellInstance)
{
shellInstance.tag = "Shell";
Rigidbody shellRB = shellInstance.GetComponent<Rigidbody>();
shellRB.AddForce(15f * transform.forward, ForceMode.Impulse);
Debug.Log("velocity");
}
}
}
Hope this helps!

Categories