- Home /
Player object still gets destroyed even when shields up
Easiest analogy... think of the game asteroids. When the player ship is hit by an asteroid it gets destroyed. No worries got that covered.
Now at later points in the game the player can collect a shield that gives the player invulnerability for a short time. And this is where my problem is... the shield doesn't work... my player still gets destroyed ! ?
I've scripted things so when the player collects the shield it becomes a child of the player object (and I think that's where my problem is) Is the player collision script taking priority over the shield script ?
this is the part of the player controller script that handles collision -
void OnTriggerEnter (Collider other)
{
if (other.tag == "Asteroid02")
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Instantiate(playerExplosion, transform.position, transform.rotation);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
and this is the script on the shields -
using UnityEngine;
using System.Collections;
public class ShieldCollision : MonoBehaviour
{
public GameObject asteroidExplosion;
public GameObject enemyExplosion;
void OnTriggerEnter (Collider other)
{
if (other.tag == "Asteroid02")
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Destroy(other.gameObject);
}
if (other.tag == "EnemyBolt")
{
Destroy(other.gameObject);
}
if (other.tag == "Enemy")
{
Instantiate(enemyExplosion, other.transform.position, other.transform.rotation);
Destroy(other.gameObject);
}
}
}
The shield has its own sphere collider which is bigger than the player object, so there is no direct contact between the player object and the roids (I think?)
All the right bits are set to is trigger etc. I've even thrown some unattached shields into the scene and they destroy the roids as intended.
The only thing I can think of is that its because the shield is a child of the player object?
Am I right (please correct me if not) and how do I go about fixing this.
???
ok I thought of adding this to my player controller script -
if(transform.parent.GetComponent<Shield>() != null)
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Destroy(other.gameObject);
}
else
//Blow up the ship as normal if no shield exists
However I'm getting an error message -
Assets/Scripts/ShipController.cs(42,50): error CS0246: The type or namespace name `Shield' could not be found. Are you missing a using directive or an assembly reference?
Why doesn't it recognise the name Shield as the component, spelling and capitalisation are correct?
Should I be using something like transform.Find ?
Answer by siaran · Mar 22, 2015 at 04:05 PM
What you should probably do (in order to keep this from being needlessly complicated) is put a script more or less like this on your player:
bool hasShield;
void Start(){
hasShield = false;
}
void OnTriggerEnter(Collider other){
switch(other.tag){
case "Asteroid":
CollideWithAsteroid(other.gameObject);
break;
case "ShieldBonus":
GetShield();
break;
default:
Debug.log("unknown tag on collider");
}
void GetShield(){
hasShield = true;
}
void CollideWithAsteroid(GameObject asteroid){
//destroy asteroid
Destroy(asteroid);
//only destroy player if he has no shield
if(!hasShield){
Destroy(gameObject);
}else{
hasShield = false;
}
}
I didnt feel like typing the explosion instantiates. Yes, this checks for collission against your player ship instead of an actual shield collider, but unless your shield extends very far beyond your player that's probably not going to be noticable. Also here I made a shield expire when it takes one hit but otherwise lasts forever, you'll probably want to do that differently.
If you have complicated shield code/graphics you want to put in a separate gameobject, you could put a child gameobject that contains your shield script and/or graphics on your player, keep a reference to it in your player script, and activate/deactivate that shield gameobject when you get/lose a shield.
Also, now that I took some time to really read your question (I should probably do that before I post an answer...oh well.
To your comment, do you have a script named Shield in your project? Because GetComponent is looking for a script called 'Shield', not a gameobject that you have given the name 'Shield'. And you should not use GameObject.Find. Ins$$anonymous$$d, have a public GameObject variable 'shieldobject' or something, assign your Shield object to it when the player picks it up, and check if that is null. Sorry, I just say your problem and wrote an answer 'here's how I would do it', and only skimmed the rest.
Ok I'm probably being really dumb here but doesn't that leave me with basically the same problem I had originally?
So I create a public GameObject shieldsUp and then (assu$$anonymous$$g shieldsUp != null I do something...
void OnTriggerEnter (Collider other)
{
if(shieldsUp != null)
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Destroy(other.gameObject);
}
else
if (other.tag == "Asteroid02")
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Instantiate(playerExplosion, transform.position, transform.rotation);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
That still leaves my problem of how do I actually check if that particular gameObject is a child of my player character?
:/
ok, now the damn thing is immortal, shields attached or not it doesn't take damage and destroys every asteroid on contact/
using UnityEngine;
using System.Collections;
public class ShipController : $$anonymous$$onoBehaviour
{
public GameObject playerExplosion;
public GameObject asteroidExplosion;
public float speed;
public float forwardSpeed;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
public Transform shieldsUp;
public bool shieldActive = false;
void Update ()
{
shieldsUp = transform.Find("Shield");
if(shieldsUp != null)
{
shieldActive = true;
}
if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
GetComponent<AudioSource>().Play ();
}
}
void FixedUpdate ()
{
float moveHorizontal = Input.GetAxis ("Horizontal");
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, forwardSpeed);
GetComponent<Rigidbody>().velocity = movement * speed;
}
void OnTriggerEnter (Collider other)
{
if(shieldActive = true)
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Destroy(other.gameObject);
}
else
if (other.tag == "Asteroid02")
{
Instantiate(asteroidExplosion, other.transform.position, other.transform.rotation);
Instantiate(playerExplosion, transform.position, transform.rotation);
Destroy(other.gameObject);
Destroy(gameObject);
}
}
}
Any ideas why this is happening constantly ?