In the game I'm developing, the player moves left and right avoiding obstacles that fall from above, but when the player reaches the left or right limit, a collision bug may occur and he simply leaves the screen. I'm using the rigidbody.velocity and the trigger to check for collision but even so, there are times when it manages to cross the wall. Here the script.(And I'm not using FixedUpdate because it's not responding well when I tap the screen.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Ball : MonoBehaviour
{
public bool isRight;
public float speed;
public Transform pointR;
public Transform pointL;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
if(isRight)
{
rb.velocity = new Vector2(speed, 0);
}
else
{
rb.velocity = new Vector2(-speed, 0);
}
if(Input.GetMouseButtonDown(0))
{
isRight = !isRight;
}
}
void OnTriggerEnter2D(Collider2D collider)
{
if(collider.CompareTag("ColisorEs"))
{
isRight = !isRight;
}
if(collider.CompareTag("colisorR"))
{
isRight = !isRight;
}
}
}
Rigidbody changes should be handled in the FixedUpdate methode. It's better for Unitys Physics.
You can leave your Input.GetMouseButtonDown in Update.
Related
My problem is that when I'm holding a gun and shoot it, all the other guns on the floor start shooting as well. How do I make it so that only the gun that I'm holding with the mouse can shoot?
You pick up the gun with the mouse left click, and you shoot with right click
My pickup code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUp : MonoBehaviour
{
bool Pressed = false;
void OnMouseDown()
{
Pressed = true;
GetComponent<Rigidbody2D>().isKinematic = true;
}
void OnMouseUp()
{
Pressed = false;
GetComponent<Rigidbody2D>().isKinematic = false;
}
void Update()
{
if(Pressed)
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = mousePos;
}
}
}
My gun code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour{
public Transform firePoint;
public float fireRate = 15f;
public GameObject bulletPrefab;
public Transform MuzzleFlashPrefab;
private float nextTimeToFire = 0f;
void Update() {
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f/fireRate;
Shoot();
}
}
void Shoot ()
{
Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
Transform clone = Instantiate (MuzzleFlashPrefab, firePoint.position, firePoint.rotation) as Transform;
clone.parent = firePoint;
float size = Random.Range (0.02f, 0.025f);
clone.localScale = new Vector3 (size, size, size);
Destroy (clone.gameObject, 0.056f);
}
}
and my bullet code
using System.Collections.Generic;
using UnityEngine;
public class bulet : MonoBehaviour
{
public float speed = 40f;
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb.velocity = transform.right * speed;
}
}
Set a flag in your Weapon, something called liked pickedUp, and toggle it when the weapon is picked up/dropped. Then in your Weapon's Update function, check if you should process Inputs for that weapon based on its picked up state. If its not picked up, there is no need to check if it should fire a bullet or not.
Upon left clicking, the Player should jump if the condition of colliding with the "Ground" layer is true.
Problem: when I click it is not making the jump.
Hierarchy(3)
Main Camera
Player
Floor
Inspector info:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float jumpForce = 25f;
private Rigidbody2D rigidBody;
void Awake()
{
rigidBody = GetComponent<Rigidbody2D>();
}
void Update()
{
if (Input.GetMouseButtonDown(0)) {
Jump();
}
}
void Jump(){
if (IsGrounded()) {
rigidBody.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
}
}
public LayerMask groundLayer;
bool IsGrounded()
{
if (Physics2D.Raycast(this.transform.position, Vector2.down, 0.2f, groundLayer.value)) {
return true;
}
else {
return false;
}
}
}
I can't see how big your player is but make sure the raycast can actually reach the floor since it's only 0.2 meters long. You can use Debug.DrawLine() to see the raycast in the editor.
Also make sure the jump force value is high enough.
I have a script that makes the camera do a shake by putting a button because
It is a public access function, if I do it that way when placing a button it works well but what I cannot achieve is to call the function so that every time my player collides with an enemy he makes the shake. I hope you can help me.
The shake code in camera is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScreenShaker : MonoBehaviour {
private float shakeAmount = 0.5f;
private float shakeTime = 0.0f;
private Vector3 initialPosition;
private bool isScreenShaking = false;
void Update () {
if(shakeTime > 0)
{
this.transform.position = Random.insideUnitSphere * shakeAmount + initialPosition;
shakeTime -= Time.deltaTime;
}
else if(isScreenShaking)
{
isScreenShaking = false;
shakeTime = 0.0f;
this.transform.position = initialPosition;
}
}
public void ScreenShakeForTime(float time)
{
initialPosition = this.transform.position;
shakeTime = time;
isScreenShaking = true;
}
}
The enemy code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ControladorEnemigoCirculoMediano : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
Here I don't know what to call the public void function ScreenShakeForTime (float time);
I already tried many things online but when my character comes into contact with the character, I don't do the shake in the camera.
}
}
}
You can create Unity-singleton in your ScreenShaker class like:
class ScreenShaker
{
public static ScreenShaker Instance {private set; get;};
void Awake() {
Instance = this;
}
}
And than from any place to call like:
ScreenShaker.Instance.ScreenShakeForTime(2f);
This is the easiest way, but maybe it's better to create standard singeleton(it's up to you).
And also don;t forget to destroy it on OnDestroy()
can you tell me in enemy game object collider isTrigger is enable or not
if it is not enable then use OnColliderEnter2D(Collision2D other){} for collision detection
So I am trying to make the player a child to the moving platform which is being moved by looking for waypoints and going to them. But when I make the player collide with the platform the collision enter is not detecting the player thus not making the player stay on it, it instead glides off.enter image description here
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class movePlatform : MonoBehaviour
{
public GameObject[] waypoints;
float rotSpeed;
int current = 0;
public float speed;
float WPradius = 1;
private GameObject target = null;
private Vector3 offset;
public GameObject Player;
CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
//This will make the player a child of the Obstacle
controller.transform.parent = other.gameObject.transform;
}
}
void OnTriggerExit(Collider other)
{
controller.transform.parent = null;
}
// Update is called once per frame
void Update()
{
if (Vector3.Distance(waypoints[current].transform.position, transform.position) < WPradius)
{
current++;
if (current >= waypoints.Length)
{
current = 0;
}
}
transform.position = Vector3.MoveTowards(transform.position, waypoints[current].transform.position, Time.deltaTime * speed);
}
}
This will not make the player a child of the platform:
controller.transform.parent = other.gameObject.transform;
Because here controller is the CharacterController instance, and other refers to the player collider. So they both refers to the player transform in the end.
Replace it by something like
other.transform.parent = transform;
or
controller.transform.parent = transform;
(Here, transform refers to the platform transform.)
If the OnTriggerEnter() is not detecting, check if your collider has isTrigger enabled. Or change the method to OnCollisionEnter().
If you are making a 2D game, switch these methods to the 2D version (=> OnCollisionEnter2D or OnTriggerEnter2D).
Not sure why, I've done this sort of this a bunch of times, but this is giving me some issues. Making a project for Game AI, I have a whole bunch of stuff already done, now just making some turrets that if the player is in a certain range it will fire, which I have already. The turret fires the bullet and then for some reason they just start destroying themselves and they don't go towards my player. Wondering if anyone on here can help, thanks in advance!
Some details you may need to know:
I have a Base, a Gun nose and a Gun for my turret. My Gun has a GunLook.cs script that makes it look at the player (so when they shoot it should go towards them), I'm not sure if that has anything to do with why I'm having these issues, but I'll post that code as well just incase
How my Hierchy for my turret is
Turret_AI (Base)
Gun (child of Turret_AI)
bulletSpawn (child of Gun)
Gun_Nose (child of turret_AI)
bulletSpawn is an empty GameObject I created in hopes to solve my problem. I set it just off the Gun so that it wouldn't just collide with gun and destroy itself (what I thought it might be doing, but not correct).
That should be all the info needed, if anyone needs more I will be checking this every 2 seconds so let me know and I will get back to you with quick response.
TurretScript.cs
(I did set the GameObject to Player in Unity, before anyone asks)
using UnityEngine;
using System.Collections;
public class TurretScript : MonoBehaviour {
[SerializeField]
public GameObject Bullet;
public float distance = 3.0f;
public float secondsBetweenShots = 0.75f;
public GameObject followThis;
private Transform target;
private float timeStamp = 0.0f;
void Start () {
target = followThis.transform;
}
void Fire() {
Instantiate(Bullet, transform.position , transform.rotation);
Debug.Log ("FIRE");
}
void Update () {
if (Time.time >= timeStamp && (target.position - target.position).magnitude < distance) {
Fire();
timeStamp = Time.time + secondsBetweenShots;
}
}
}
GunLook.cs
// C#
using System;
using UnityEngine;
public class GunLook : MonoBehaviour
{
public Transform target;
void Update()
{
if(target != null)
{
transform.LookAt(target);
}
}
}
BulletBehavior.cs
using UnityEngine;
using System.Collections;
public class BulletBehavior : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (rigidbody.velocity.magnitude <= 0.5)
Destroy (gameObject);
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider)
{
if(collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "EnemyProjectile")
{
Physics.IgnoreCollision(rigidbody.collider,collision.collider);
//Debug.Log ("Enemy");
}
if(collision.gameObject.tag == "SolidObject")
{
Destroy(gameObject);
}
if(collision.gameObject.tag == "Player")
{
Destroy(gameObject);
}
}
}
}
You're never moving your bullet.
public class BulletBehavior : MonoBehaviour
{
private const float DefaultSpeed = 1.0f;
private float startTime;
public Vector3 destination;
public Vector3 origin;
public float? speed;
public void Start()
{
speed = speed ?? DefaultSpeed;
startTime = Time.time;
}
public void Update()
{
float fracJourney = (Time.time - startTime) * speed.GetValueOrDefault();
this.transform.position = Vector3.Lerp (origin, destination, fracJourney);
}
}
Then call it like so:
void Fire()
{
GameObject bullet = (GameObject)Instantiate(Bullet, transform.position , transform.rotation);
BulletBehavior behavior = bullet.GetComponent<BulletBehavior>();
behavior.origin = this.transform.position;
behavior.destination = target.transform.position;
Debug.Log ("FIRE");
}
Note: If you're trying to mix this approach with trying to use physics to move the bullet you may end up with strange results.