So I'm trying to get my vehicle to play an explosion when colliding with an enemy vehicle and have succeeded in making the explosion appear but when doing so it is cloned outside of the parent object and gets left behind when collision happens at a speed so the actual player car doesn't look like its exploding but instead travels past the explosion prefab. Any ideas on how to fix this would be much appreciated. Thanks
void OnTriggerEnter(Collider col)
{
if (col.tag == "Enemy")
{
PlayExplosion();
}
}
void PlayExplosion()
{
GameObject explosion = (GameObject)Instantiate(ExplosionGo);
//set the position of the explosion
explosion.transform.position = transform.position;
}
You need to either manually set the parent:
explosion.transform.parent = transform;
Or supply a parent transform in the Instantiate parameters:
GameObject explosion = (GameObject)Instantiate(ExplosionGo, transform);
You need to set explosion transform a child of your car transform/ Try this:
void PlayExplosion()
{
GameObject explosion = (GameObject)Instantiate(ExplosionGo);
explosion.transform.SetParent(transform, false);
}
Related
In my game on unity 2d I have spaceship and a planet. The planet is orbiting a star so I made a script that parents the planet to the player when I get within a range so the planet doesn't fly past or into the player. This script makes the player move with the planet so they land on it and fly around it easily.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParentPlayer : MonoBehaviour
{
[SerializeField] GameObject Player;
private float Dist;
[SerializeField] float Threshold;
private CircleCollider2D ParentTrigger;
// Start is called before the first frame update
void Start()
{
ParentTrigger = GetComponents<CircleCollider2D>()[1];
ParentTrigger.isTrigger = true;
ParentTrigger.radius = Threshold / transform.localScale.x;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(transform);
}
}
private void OnTriggerExit2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(null);
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Threshold);
}
}
The problem is that as the planet rotates it ends up moving the player that has been parented to it. How can I make the planet's rotation not affect the position and rotation of the player, but still make the planets position affect the position of the player?
This might not be what you're looking for but I'm going to add it reguardless. Given that the Child-object will follow the parent, I would suggest putting the planet and spaceship as a child of the empty gameobject. Then you could rotate the the planet object, and if planets are in movement, you could add the movement to the parent object.
How about instead of parenting the player, write a script to set its position to the planets + some offset, and then the rotation wouldn't be an issue. Alternatively, if the player doesn't rotate at all, add constraints to its Rigidbody. Maybe something like this:
player.transform.position = planet.transform.position + offset;
Hope that works!
I have the code for destroying a Cube GameObject when it collides with the Terrain. However, Im not sure how I would then after instantiate a New Sphere GameObject in its place after the cube is destroyed.
This is the current code:
{
void OnCollisionEnter(Collision collision)
{
if (collision.collider.gameObject.tag != "Destroy")
{
Destroy (gameObject);
}
}
}
1) Attach this script to your terrain game object and not the cube.
2) Add a new tag in the editor for cube objects (e.g cube).
3) Create a new sphere prefab instance that you can access through the script containing the OnCollisionEnter() event.
void OnCollisionEnter(Collision collision)
{
if (collision.collider.gameObject.tag == "Cube")
{
//store the transform component of the gameobject to be destroyed.
var transf = collision.gameObject.transform;
//Destroy the collided gameobject
DestroyImmediate(gameObject);
//Instantiate in the position and rotation of the destroyed object.
Instantiate(sphere, transf.position, transf.rotation);
}
}
I am trying to have my player ignore the collision with an edge collider on a platform i have.
Here's the script that I have added to the player
public class TestMovement : MonoBehaviour
{
public Rigidbody2D ball;
private GameObject purplePlat1;
private GameObject player;
// Start is called before the first frame update
void Start()
{
purplePlat1 = GameObject.Find("purple_plat");
player = GameObject.Find("circle-png-44659");
ball = GetComponent<Rigidbody2D>();
ball.AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
Debug.Log("start");
}
// Update is called once per frame
void Update()
{
}
void OnCollisionEnter2D(Collision2D collision)
{
Physics2D.IgnoreCollision(purplePlat1.GetComponent<EdgeCollider2D>
(), GetComponent<CircleCollider2D>());
Debug.Log("collision");
}
}
The ball is still hitting the platform. I have confirmed that the oncollisionenter method is firing.
You can use the layer system of Unity to avoid collisions between both. Set a layer for a player and another for the edge and untick the collision between them.
What you can do is create a layer mask for the different type of game objects. Then, open your Physics2D settings.
On the bottom part, you can see a matrix of physics objects that can collide to one another. Just uncheck which layer should not collide with the other.
Is it possible to have two colliders for one object?
My situation is that I have a CircleCollider2D that causes my enemy to chase the player when it enters. This works well but I want to also have a BoxCollider2D that will switch scene to my scene called "BattleScene" when the player enters.
I want it so that when my player enters the circle collider my enemy will follow him but when the player gets closer and enters the box collider (both attached to the enemy) it will switch scenes to the scene called "BattleScene".
Another alternative I thought of was using a rigid body collision but I don't know how to implement that.
Here is my code
private bool checkContact;
private bool checkTrigger;
public float MoveSpeed;
public Transform target;
public Animator anim;
public Rigidbody2D myRigidBody;
BoxCollider2D boxCollider;
public string levelToLoad;
// Start is called before the first frame update
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();//getting the position of our player
anim = GetComponent<Animator>();
myRigidBody = GetComponent<Rigidbody2D>();
boxCollider = gameObject.GetComponent<BoxCollider2D>();
}
// Update is called once per frame
void Update()
{
if (checkTrigger == true)
{
transform.position = Vector2.MoveTowards(transform.position, target.position, MoveSpeed * Time.deltaTime); //move towrds from your position to the position of the player
if (myRigidBody.position.y < target.position.y && Mathf.Abs(target.position.y - myRigidBody.position.y) > Mathf.Abs(target.position.x - myRigidBody.position.x)) //if it is further away from target in x direction than y direction the animation for moving in y is loaded and vice versa
{
anim.SetFloat("MoveY", 1);
anim.SetFloat("MoveX", 0);
}
if (myRigidBody.position.y > target.position.y && Mathf.Abs(target.position.y - myRigidBody.position.y) > Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveY", -1);
anim.SetFloat("MoveX", 0);
}
if (myRigidBody.position.x > target.position.x && Mathf.Abs(target.position.y - myRigidBody.position.y) < Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveX", -1);
anim.SetFloat("MoveY", 0);
}
if (myRigidBody.position.x < target.position.x && Mathf.Abs(target.position.y -myRigidBody.position.y) < Mathf.Abs(target.position.x - myRigidBody.position.x))
{
anim.SetFloat("MoveX", 1);
anim.SetFloat("MoveY", 0);
}
anim.SetBool("checkTrigger", checkTrigger); //updating if in range
}
}
public void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.name == "Player")
{
checkTrigger = true; //setting our check trigger = true so it will follow if in radius
anim.SetBool("checkTrigger", checkTrigger);
}
}
public void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.name == "Player")
{
checkTrigger = false; //setting our check trigger = false so it will not follow if not in radius
anim.SetBool("checkTrigger", checkTrigger);
}
EDIT: THIS PROBLEM HAS BEEN RESOLVED
The best way to handle this is by having an empty GameObject with the other collider attached to it, while making sure both GameObjects have a Rigidbody - the child with IsKinematic ticked. Why? Because this will separate the child GameObject from the parent collision structure. Read more about compound colliders.
You should only have more than one collider in one GameObject if they all make part of the same collision structure. If they have different purposes, use different GameObjects with kinematic Rigidbodies, each handling it's own task.
In your specific scenario, I would have the CircleCollider in the enemy itself and the BoxCollider in a child GameObject with a kinematic Rigidbody. This child GameObject can also contain a script with the sole purpose of checking against the Player and loading the BattleScene.
I have an object moving towards the player and a trigger that when the player or object hit it they teleport to another area in the map. The object moves towards the player without any issues until the object moves through the teleporter. When the object gains a new position post trigger it just runs off screen. Anyone got any ideas why this might be?
Object chasing player:
private void Update()
{
Vector3 targetPosition = new Vector3(target.transform.position.x,
target.transform.position.y,
target.transform.position.z);
transform.LookAt(targetPosition);
Monster.transform.position = Vector3.MoveTowards(Monster.transform.position,
Player.transform.position, moveSpeed);
}
Teleport script:
private void OnTriggerEnter(Collider collider)
{
if (collider.name == Player.name)
{
Player.transform.position = new Vector3(XLocation, YLocation, ZLocation);
}
if (collider.name == Monster1.name)
{
Monster1.transform.position = new Vector3(XLocation, YLocation, ZLocation);
}
}