How to make sprites spawn in and disappear on screenbounds in unity - c#

I'm trying to create a game where asteroids spawn in and despawn when touching a screenbound, I've looked at many tutorials but these doesn't work for me or say I got something wrong in the code while the code seems to be fine, how do I make it so they spawn in at random and despawn when they touch the screenbounds?
Code I got for now:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class asteroid : MonoBehaviour
{
public float speed = 10.0f;
private Rigidbody2D rb;
private Vector2 screenBounds;
// Use this for initialization
void Start()
{
rb = this.GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(0, -speed);
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}
// Update is called once per frame
void Update()
{
if (transform.position.y < screenBounds.y)
{
Destroy(this.gameObject);
}
}
}

Try to check if the Renderer component is visible:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class asteroid : MonoBehaviour
{
public float speed = 10.0f;
private Rigidbody2D rb;
private Vector2 screenBounds;
// Use this for initialization
void Start()
{
rb = this.GetComponent<Rigidbody2D>();
rb.velocity = new Vector2(0, -speed);
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
}
// Update is called once per frame
void Update()
{
if (!GetComponent<Renderer>().isVisible)
{
Destroy(this.gameObject);
}
}
}

You can use this function:
void OnBecameInvisible()
{
Destroy(gameObject);
}

Related

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

Change AI Enemy Animation

Currently, I'm making a game in unity, and I made a simple script to make the enemy follow the player but I can't change the animation of the enemy to the other side
gameplay:
EnemyController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
[Header("References")]
private Animator animator;
// The target to follow.
private Transform target;
private Rigidbody2D rb;
[Header("Movement")]
public float speed;
public float range;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
target = FindObjectOfType<PlayerMovement>().transform;
}
// Update is called once per frame
void Update()
{
FollowPlayer();
}
private void FollowPlayer()
{
animator.SetBool("isRunning", true);
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
}
I fix it by using blend tree
Blend Tree:
Script:
private void FollowPlayer()
{
animator.SetBool("isRunning", true);
animator.SetFloat("Horizontal", target.position.x - transform.position.x);
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}

Unity accessing rigidBody component with input system

I have just started a new Unity tut using its input system to move a ball. However, the script doesn't seem to be working when I try to move the ball
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem; //Namespace for accessing InputSystem to control ball
public class PlayerController : MonoBehaviour
{
private Rigidbody rb;
private float movementX;
private float movementY;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Onmove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement);
}
}
If you did everything else right and the problem is only in your script then changing from Onmove to OnMove should fix problem
Create in Unity a new InputControl with the name PlayerInputActions and into
Inspector select Generate C# class, Unity autogenerate for you Action Maps , Actions and Binding Property, double click on it to watch, than in a new c# script named NewInputSystem
using UnityEngine;
using UnityEngine.InputSystem;
public class NewInputSystem : MonoBehaviour
{
public Rigidbody rb;
public float moveSpeed = 7.0f;
Vector2 moveDirections = Vector2.zero;
public PlayerInputActions playerControls;
private InputAction move;
private void Awake()
{
playerControls = new PlayerInputActions();
}
private void OnEnable()
{
move = playerControls.Player.Move;
move.Enable();
}
private void OnDisable()
{
move.Disable();
}
void Start()
{
rb =gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
moveDirections = move.ReadValue<Vector2>();
}
private void FixedUpdate()
{
//change how you want
rb.velocity = new Vector3(moveDirections.y * moveSpeed, 0, moveDirections.x * -moveSpeed);
}
}

My code to move in unity 2D game not working correctly

There is my current code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovementScript : MonoBehaviour
{
[SerializeField] float runSpeed = 10f;
Vector2 moveInput;
Rigidbody2D rigidbody;
void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
}
void Update()
{
Run();
}
void OnMove(InputValue value){
moveInput = value.Get<Vector2>();
Debug.Log(moveInput);
}
void Run()
{
Vector2 playerVelocity = new Vector2(moveInput.x * runSpeed, rigidbody.velocity.y);
rigidbody.velocity = moveInput;
}
}
But my character still mowing with speed of 2f and can fly up and down (i did it in first version of my code).
It looks like game not loaded newest code and don't know how to fix it.
I have selected auto refresh.

How to make a player die while falling?

I am developing a basic game on Unity to improve myself. It's a basic endless runner platform game.
If you right click when the player is on the ground, it jumps; if it's not on the ground, it falls faster.
But I couldn't figure out how to make a player die while falling when it couldn't catch the platform. Could you please check my code? I am trying to find an "if" command to make it happen.
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerControls : MonoBehaviour
{
public Rigidbody2D rb;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
float CurrentFallTime;
public float MaxFallTime = 7;
bool PlayerIsFalling;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
rb.velocity = new Vector2(5, rb.velocity.y);
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
CurrentFallTime += Time.deltaTime;
if (Input.GetMouseButtonDown(0) && onGround)
{
rb.velocity = new Vector2(rb.velocity.x, 12);
}
if (Input.GetMouseButtonDown(0) && !onGround)
{
rb.velocity = new Vector2(rb.velocity.x, -10);
}
// I want it to die and go to game over screen when it exceeds the CurrentFallTime
if ()
{
if (CurrentFallTime >= MaxFallTime)
{
SceneManager.LoadScene("GameOver");
}
}
}
}
EDIT: It solved! I simpy added "if(onGround)" and reset the CurrentFallTime. Here is the new code:
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerControls : MonoBehaviour
{
public Rigidbody2D rb;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask whatIsGround;
private bool onGround;
float CurrentFallTime;
public float MaxFallTime = 7;
bool PlayerIsFalling;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
rb.velocity = new Vector2(5, rb.velocity.y);
onGround = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
CurrentFallTime += Time.deltaTime;
if (onGround)
{
CurrentFallTime = 0f;
}
if (Input.GetMouseButtonDown(0) && onGround)
{
rb.velocity = new Vector2(rb.velocity.x, 12);
}
if (Input.GetMouseButtonDown(0) && !onGround)
{
rb.velocity = new Vector2(rb.velocity.x, -10);
}
if (CurrentFallTime >= MaxFallTime)
{
SceneManager.LoadScene("GameOver");
}
}
}
This is something that I just thought of now, so I'm not sure how well it will work, but you can create a 1-sided plane collider and position it to follow the x- and y-coordinate of the player, but stay slightly lower than the height of the ground, e.g. 1unit. Then check when the player collides with the plane, if it does then you know that the player has fallen.
So, create an empty GameObject and add the collider, no need for any mesh properties and set the collider trigger to true. Then in player controls add something like in update.
colliderGo.transform.location = new Vector3(transform.x, groundHeight - 1, transform.z)
Also in the player controller function
function onTrigger(Collider col) {
if (col.tag == "fallDetector") {
Debug.Log("What a cruel world")
playHasFallen = true;
}
}
Something like this should work.

Categories