I have been doing a tutorial for network games using Unity but I am having trouble with the bullet, whenever I include the private void OnCollision thing, the bullet will not initialise if I press space but if I remove it the bullets will be there but I am trying to avoid the arrays of the bullet (clone) when shooting so I want to destroy the bullet. I used the code
//private void OnCollisionEnter(Collision collision)
//{
// Destroy(gameObject);
//}
In my bullet script that I have created, I have had to comment out the lines as whenever I use this and play the game the space button which shoots the bullets don't work at all.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
Rigidbody rigidbody;
// Start is called before the first frame update
void Awake()
{
rigidbody = GetComponent<Rigidbody>();
}
public void InitializeBullet(Vector3 originalDirection)
{
transform.forward = originalDirection;
rigidbody.velocity = transform.forward * 18f;
}
//private void OnCollisionEnter(Collision collision)
//{
// Destroy(gameObject);
//}
}
This is probably happening due to OnCollisionEnter function gets triggered when the gameobject collides with something. When you instantiate the bullet it probably collides with the player character itself as that also has a collider, thus instantly destroying itself.
A simple solution would be to check the tag of the collided gameobject to make sure that the bullet collided with something that we want it to. So after setting the enemy prefab to have it's own tag your collision code would look like this:
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Enemy") //I choosed enemy as the custom tag
{
Destroy(gameObject);
}
}
I figured out what went wrong as #66Gramms talked about the bullet colliding with the player character I had another game object called bullet position where I was suppose to put it in front of the player character but instead I didn't do that, the player and bullet were together colliding smh. So the code I used
private void OnCollisionEnter(Collision collision)
{
Destroy(gameObject);
}
Actually works
Related
hi creators I'm trying to make my first 3d game so it is going fine tell today when I decide to change the movement script
I'm checking if the player is grounded with OnTriggerEnter(Collider coll) on an empty gameObject attached to the player and it works fine and the player move like I dreamed 'but' after some random moves when testing the variable isGrounded turns false even if the player is grounded something that I'm sure about it
so her is the code I'm using on the gameObject child
using System.Collections.Generic;
using UnityEngine;
public class isGrounded : MonoBehaviour
{
public bool isgrounded=false;
private void OnTriggerEnter(Collider col){
isgrounded=true;
}
private void OnTriggerExit(Collider col){
isgrounded=false;
}
}
and the player movement script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moves : MonoBehaviour
{
GameObject cam,world;
Rigidbody rd;
bool moveR,moveL,jump,teleport;
// Start is called before the first frame update
void Start()
{
rd=GetComponent<Rigidbody>();
cam=GameObject.Find("Main Camera");
world=GameObject.Find("World");
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.D)){
moveR=true;
} if(Input.GetKeyUp(KeyCode.D)){
moveR=false;
}
if(Input.GetKeyDown(KeyCode.A)){
moveL=true;
}if(Input.GetKeyUp(KeyCode.A)){
moveL=false;
}
if(Input.GetKeyDown(KeyCode.Space)){
jump=true;
}
if(Input.GetKeyUp(KeyCode.Space)){
jump=false;
}
if(Input.GetKeyDown(KeyCode.W)){
teleport=true;
world.GetComponent<Rigidbody>().velocity=new Vector3(0,0,-90);
}
}
void FixedUpdate(){ Debug.Log(isGrounded());
if(moveR==true&&isGrounded()==true){
rd.velocity=new Vector3(5,0,0);
if(jump==true){rd.velocity+=new Vector3(0,5f,0);}
}
if(moveL==true&&isGrounded()==true){
rd.velocity=new Vector3(-5,0,0);
if(jump==true){rd.velocity+=new Vector3(0,5f,0);}
}
if(jump==true&&isGrounded()==true){
rd.velocity+=new Vector3(0,5f,0);
}
}
bool isGrounded(){
return transform.Find("GroundCheck").GetComponent<isGrounded>().isgrounded;
}
}
I really want to know why and be sure I understand the mechanism of this wonderful variable isGrounded turning false while the player is grounded
and also I would like to know if there is a deference between OnTriggerEnter and OnTriggerStay
The issue is that you're checking if an object is grounded via OnTriggerEnter and OnTriggerExit.
You have no possible way to determine that correctly using this method. Instead you should use https://docs.unity3d.com/ScriptReference/Physics.Raycast.html. You can throw the Raycast downwards, check if it hits anything that have a tag corresponding to your ground objects and if yes then you know you're on the ground.
For the second question. The difference between OnTriggerEnter and OnTriggerStay is that OnTriggerEnter is only invoked when one collider enters the other. OnTriggerStay on the other hand is invoked constantly if the colliders are overlapping each other.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveProjectile : MonoBehaviour
{
public Rigidbody2D projectile;
public float moveSpeed = 10.0f;
// Start is called before the first frame update
void Start()
{
projectile = this.gameObject.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
projectile.velocity = new Vector2(0,1) * moveSpeed;
}
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.name == "Enemy"){
gameObject.name == "EnemyHeart5".SetActive(false);
}
if(col.gameObject.name == "Top"){
DestroyObject (this.gameObject);
}
}
}
This is the code to my player projectile. On collision i tried to reference it to a game object i have called playerheart and it doesnt seem to work out the way i wanted it to.
Im trying to make a health system where if my bullet collides with the enemy game object the health would decrease by one. Im pretty new to Unity and im confused on how to target the hearts when the bullets collide.
I'm assuming "EnemyHeart5" is a GameObject inside Enemy as child gameobject. Correct?
Issue here is when the collision takes place, it recognize "Enemy" gameobject and won't have access to "EnemyHeart5" for disabling it. I'd suggest you to add simple EnemyManager script into your enemy which manages your enemy health and health related gameobject (ie. EnemyHearts which you are displaying). When collision takes place, access that EnemyManager component and change health value.
void OnCollisionEnter2D(Collision2D col){
if(col.gameObject.tag == "Enemy"){
col.gameObject.GetComponent<EnemyManager>().health =-1;
}
Now, in the update method of EnemyManager you check the health value and disable EnemyHealth5 component.
Also, use "tag" in collision instead of "name". name will create issues when you have multiple enemies in the game. Make sure you add tag in enemy gameobject if you are using it.
Hope this helps, let me know how it goes.
So I learned that you can use a function called OnCollisionEnter to do different things on gameObjects collisions. I tried something simple :
using UnityEngine;
public class Bouncing : MonoBehaviour
{
void OnCollisionEnter(Collision collisionInfo)
{
Debug.Log("text");
}
}
I have a player with these children - Camera, Player Body and Ground Check. The Player Body has a capsule collider component (beacuse it's a capsule of course, the collider has the "Is Trigger" option unchecked.).
The Bouncer was meant to bounce me about 5 units high (I'll do it sometime, if you have any tutorials or anything that could help me then you can comment it too. :) ) The Bouncer has these components - Rigidbody (it isn't kinematic but uses gravity) and a Box Collider ("Is Trigger" option is unchecked.).
I tried to search help on the Internet, but nothing would work as I would like (beacuse it won't work at all).
Sorry for my bad English, thanks for your help everyone.
OnCollisionEnter is an event: Unity calls it when the object (which must have a Rigidbody) collides with any collider. This event may occur in both objects, the rigidbody and the hit object. In the player, the code could be like this:
public void OnCollisionEnter(Collision collision)
{
switch (collision.gameObject.tag) // based on Tag
{
case "Ball":
// do something when hitting ball
break;
case "Wall":
// do something when hitting wall
break;
}
// or based on component
if (collision.gameObject.GetComponent<Rigidbody>())
{
// do something when hitting Rigidbody gameobject
}
else if (collision.gameObject.GetComponent<Archer>())
{
// do something when hitting a object with (Archer for exp..) component
}
}
In the ball, the code is pretty much the same - the only difference is that the col structure contains info about the object hit:
void OnCollisionEnter(Collision col)
{
if (col.gameObject.tag == "Player")
{
// this rigidbody hit the player
}
}
I want to check if my ship/s collided and not some other objects.
So this is the script that i attached to a GameObject and the GameObject have box collider and Rigidbody. The box collider: Is Trigger set to on. And he size is 500 600 500. The Rigidbody i didn't change anything and Use Gravity is on.
When running the game i have many cloned gameobjects each one Tagged as "Sphere" but in the script when i check the tag name the collider is "Untagged".
What i'm trying to do is to make sure the collided object is a cloned spaceship.
using UnityEngine;
using System.Collections;
public class InvisibleWalls : MonoBehaviour {
public float smooth = 1f;
private Vector3 targetAngles;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerExit(Collider other)
{
if (other.tag == "Sphere")
{
targetAngles = other.transform.eulerAngles + 180f * Vector3.up;
other.transform.eulerAngles = Vector3.Lerp (other.transform.eulerAngles, targetAngles, smooth * Time.deltaTime);
}
}
}
This is the part where i'm trying to check and make that a ship is collided:
if (other.tag == "Sphere")
But when using break point it does stop on this line when the pbject collided but the other.tag the tag is "Untagged".
Screenshot showing the object spaceship cloned that is tagged as "Sphere"
And this screenshot showing the gameobject with the box collider and the rigidbody
From what i can gather,
You CrashLandedShip objects do not have colliders, adding colliders should work.
Also note that for triggers to work, One of the objects (the terrain or the ship) has to be a non-trigger (2 triggers will not cause a collision or trigger event)
So try this : Add a sphere collider to your CrashLandedShip_UpsideDown prefab and make sure they are not set with IsTrigger
The rest of your code looks fine.
I'm trying to make a BTD game. Since different balloons (enemies) have different speeds, they collide with each other when traveling on the path. I'm currently using this code:
void OnCollisionEnter (Collision coll)
{
if (coll.gameObject.tag == "Enemy")
{
Physics.IgnoreCollision(coll.collider, gameObject.GetComponent<SphereCollider>());
}
}
However, it doesn't appear to be working at all. The enemies still collide with each other. On the otherhand, the collision with the enemies and bullets from towers is working.
void OnTriggerEnter (Collider col)
{
if (col.tag == "Bullet")
{
CurrentHP -= col.GetComponent<TackShooterBullet>().Damage;
}
I've tried layer-collision (enemies to same layer & unchecking of the same layer collision in the layer collision matrix, but that doesn't work either. The enemy contains a sphere mesh filter, sphere collider, mesh renderer, rigidbody, material, and 2 scripts. Is there a better way to avoid collisions between the enemies. I'm asking this question since I've seen duplicates, but their solutions aren't working at all. I can provide more of my code if needed.
Edit for Clarity: Again, what I'm trying to accomplish is have the enemies be able to go through each other.
Edit (Fixed Problem): I found out to avoid Enemy Collisions, I could also remove rigidbody. However, removing the ridigbody would mess up the bullet --> enemy trigger in the enemy class. Therefore, I just wrote the collision between bullet & enemy in the bullet class instead.
using UnityEngine;
public class TackShooterBullet : MonoBehaviour {
private GameObject target;
public float Damage;
// Use this for initialization
void Start () {
target = transform.parent.GetComponent<TackShooterRange>().Target; // Target = Enemy[0] (First Enemy To Enter Range - Enemy is Removed from JList when exiting Range)
}
// Update is called once per frame
void Update()
{
Damage = gameObject.transform.parent.transform.parent.GetComponent<TackShooterLimitingRange1>().level * 20; // Upgrade Level * 20 = Damage Done
if (target == null) // If Enemy Exits Range
{
Destroy(gameObject); // Destroy Bullet
}
if (target != null) // Enemy Exists In Range
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, 20 * Time.deltaTime); // Bullet Follows Enemy
Destroy(gameObject); // Destroy Bullet Upon Contact With Enemy
target.GetComponent<HealthOfEnemy>().CurrentHP -= Damage; // Enemy Loses Health
}
}
This allowed me to remove the OnTriggerEnter & OnCollisionEnter methods as well as the RigidBody from the Enemy Class as stated before, so these properties no longer affect the collisions between Enemies.
Unity has a built in function for easier collision detection called layer-based collision detection:
https://docs.unity3d.com/Manual/LayerBasedCollision.html
The documentation is really good. Just comment if you need further clarification.