Using polymorphism or Interfaces in C# unity - c#

In my game in unity C#, I have two classes one is a PlayerHealth and the other is EnemyHealth they have the same functions but these two fields are inverted currentHapinessPower and currentSadnesPower.
I don't know if i should use the polymorphism principle or inheritance or interfaces.
These are the classes:
public class PlayerHealth : MonoBehaviour
{
#region Public Instances
public GameObject Player;
public GameObject Pl_DeathParticle;
public TextMeshProUGUI NumOfHappyPower;
public TextMeshProUGUI NumOfSadPower;
#endregion
#region HapAndSad System Variables
public int playerHappinessPower;
[HideInInspector] public int currentHappinessPower; <--
[HideInInspector] public int currentSadnesPower; <--These two
#endregion
#region HapAndSad States
private bool isSad = false;
#endregion
void Start()
{
currentHappinessPower = playerHappinessPower; // in the enemy class is currentSadnessPower
NumOfSadPower.enabled = false; // here in the enemy class is true
}
void Update()
{
HapAndSadPowerSystem();
StartCoroutine(CheckThePlayerSadState());
}
void HapAndSadPowerSystem()
{
if (currentHappinessPower > 0) //enemy class: currentSadnessPower
{
NumOfHappyPower.text = currentHappinessPower.ToString(); //also here is changed
}
else if (currentHappinessPower == 0) // here also is currentSadnessPower
{
NumOfHappyPower.enabled = false;
NumOfSadPower.enabled = true;
}
else if (currentHappinessPower < 0 && currentSadnesPower == 0) //and here
{
isSad = true; // enemy class is false
currentSadnesPower = currentHappinessPower * -1; //Make the rest of the soubstraction positive / also here its inverted
NumOfHappyPower.enabled = false; //true in the enemy class
NumOfSadPower.enabled = true; // false
NumOfSadPower.text = currentSadnesPower.ToString();
}
else if (currentSadnesPower > 0)
{
NumOfSadPower.text = currentSadnesPower.ToString();
}
}
IEnumerator CheckThePlayerSadState()
{
if (isSad == true) //here is false
{
yield return new WaitForSeconds(2f);
GameObject PlayerDeath_particle_prefab = Instantiate(Pl_DeathParticle, Player.transform.position, Quaternion.identity);
Destroy(PlayerDeath_particle_prefab.gameObject, 1f);
Destroy(Player.gameObject);
}
}
}
And here is the enemy class:
public class EnemyHealth : MonoBehaviour
#region Public Instances
public GameObject Enemy;
public GameObject En_DeathParticle;
public TextMeshProUGUI NumOfHappyPower;
public TextMeshProUGUI NumOfSadPower;
#endregion
#region HapAndSad System Variables
public int enemySadnesPower;
[HideInInspector] public int currentHappinessPower;
[HideInInspector] public int currentSadnesPower;
#endregion
#region HapAndSad States
private bool isSad = true;
#endregion
void Start()
{
currentSadnesPower = enemySadnesPower;
NumOfHappyPower.enabled = false;
}
void Update()
{
HapAndSadPowerSystem();
StartCoroutine(CheckThePlayerSadState());
}
void HapAndSadPowerSystem()
{
if (currentSadnesPower > 0)
{
NumOfSadPower.text = currentSadnesPower.ToString();
}
else if (currentSadnesPower == 0)
{
NumOfHappyPower.enabled = true;
NumOfSadPower.enabled = false;
}
else if (currentSadnesPower < 0 && currentHappinessPower == 0)
{
isSad = false;
currentHappinessPower = currentSadnesPower * -1;
NumOfHappyPower.enabled = true;
NumOfSadPower.enabled = false;
NumOfHappyPower.text = currentHappinessPower.ToString();
}
else if (currentHappinessPower > 0)
{
NumOfHappyPower.text = currentHappinessPower.ToString();
}
}
IEnumerator CheckThePlayerSadState()
{
if (isSad == false)
{
yield return new WaitForSeconds(2f);
GameObject PlayerDeath_particle_prefab = Instantiate(En_DeathParticle, Enemy.transform.position, Quaternion.identity);
Destroy(PlayerDeath_particle_prefab.gameObject, 1f);
Destroy(Enemy.gameObject);
}
}
}

These scripts are almost identical. I would use the same script as the player and the enemy. And add a boolean to distinguish between the player and the enemy.
Edit:
If you want to use inheritance or polymorphism desperately, I would recommend you to make an Entity class and make Player and Enemy derive from it.

Related

i have a camera shake script but when i click start it directy goes off and it wont stop

i have a camera shake script but when i click start it directy goes off and it wont stop
in this script i wanted to trigger the shake effect
public class GameOver : MonoBehaviour
{
public Explosion shake;
void OnCollisionEnter2D (Collision2D coll)
{
Debug.Log("Collision!");
if (coll.gameObject.tag == "platform")
{
Destroy(gameObject);
shake.GameOver = true;
}
}
}
and this is the other script
public class Explosion : MonoBehaviour
{
public Transform cameraTransform;
private Vector3 orignalCameraPos;
public float shakeDuration;
public float shakeAmount;
private bool canShake = false;
public bool GameOver = false;
private float _shakeTimer;
void Start()
{
orignalCameraPos = cameraTransform.localPosition;
GameOver = false;
_shakeTimer = 0;
}
void Update()
{
if (GameOver = true)
{
ShakeCamera();
}
}
public void ShakeCamera()
{
_shakeTimer = shakeDuration;
StartCameraShakeEffect();
}
public void StartCameraShakeEffect()
{
if (_shakeTimer > 0)
{
cameraTransform.localPosition = orignalCameraPos + Random.insideUnitSphere * shakeAmount;
_shakeTimer -= Time.deltaTime;
}
else
{
_shakeTimer = 0f;
cameraTransform.position = orignalCameraPos;
GameOver = false;
}
}
}
if you are able to help me i would be very thankfull :)
in the statement if (GameOver = true) you are setting GameOver to true and then checking its value. I think you might have wanted to use if (GameOver == true) or if (GameOver) which will check if this variable is set to true.

Coroutine issue in VR

I have tried everything with this. The coroutine will do nothing after yield return. My timestep is 0.005, because I'm executing this in VR (and require this setup). I have no idea if it has anything to do with it, I have read conflicting info. Please help, totally stumped. If there is another route I should go down, happy to dry a different method.
Ideally: tap on object, voiceover comes on and panel appears, panel disappears after 5sec, voiceover obj gets destroyed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ActiveTouch : MonoBehaviour
{
bool redCell;
bool whiteCell;
bool plateletCell;
bool plasmodiumCell;
public GameObject plasmodiumGroup;
public GameObject rPanel;
public GameObject wPanel;
public GameObject pPanel;
public GameObject pfPanel;
public GameObject mPanel;
public GameObject welldonePanel;
public GameObject dragdropPanel;
public GameObject infoPanel;
public AudioSource myAudioSource;
public AudioSource rAudioSource;
public GameObject rAudio;
public AudioSource wAudioSource;
public GameObject wAudio;
public AudioSource pAudioSource;
public GameObject pAudio;
public AudioSource pfAudioSource;
public GameObject pfAudio;
public GameObject groupParent;
Animator groupAnimator;
private void Start()
{
redCell = false;
whiteCell = false;
plateletCell = false;
plasmodiumCell = false;
plasmodiumGroup.SetActive(false);
rPanel.SetActive(false);
wPanel.SetActive(false);
pPanel.SetActive(false);
pfPanel.SetActive(false);
welldonePanel.SetActive(false);
dragdropPanel.SetActive(false);
mPanel.SetActive(true);
rAudio.SetActive(true);
wAudio.SetActive(true);
pAudio.SetActive(true);
pfAudio.SetActive(true);
}
void OnTriggerEnter(Collider col)
{
if (col.gameObject.CompareTag("WhiteBloodCell"))
{
//Debug.Log("White Cell triggered!");
whiteCell = true;
mPanel.SetActive(false);
wPanel.SetActive(true);
myAudioSource.Play();
wAudio.SetActive(true);
wAudioSource.Play();
if (wAudioSource.isPlaying)
{
rAudio.SetActive(false);
pAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(wPanelCoroutine(wPanel));
StartCoroutine(PanelCoroutine(wPanel));
}
else if (col.gameObject.CompareTag("RedBloodCell"))
{
redCell = true;
mPanel.SetActive(false);
rPanel.SetActive(true);
//Debug.Log("Red Cell triggered!");
myAudioSource.Play();
rAudio.SetActive(true);
rAudioSource.Play();
if (rAudioSource.isPlaying)
{
wAudio.SetActive(false);
pAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(rPanelCoroutine(rPanel));
StartCoroutine(PanelCoroutine(rPanel));
}
else if (col.gameObject.CompareTag("PlateletCell"))
{
//Debug.Log("Platelet Cell triggered!");
plateletCell = true;
mPanel.SetActive(false);
pPanel.SetActive(true);
myAudioSource.Play();
pAudio.SetActive(true);
pAudioSource.Play();
if (pAudioSource.isPlaying)
{
wAudio.SetActive(false);
rAudio.SetActive(false);
pfAudio.SetActive(false);
}
//StartCoroutine(pPanelCoroutine(pPanel));
StartCoroutine(PanelCoroutine(pPanel));
}
else if (col.gameObject.CompareTag("PlasmodiumF"))
{
plasmodiumCell = true;
mPanel.SetActive(false);
pfPanel.SetActive(true);
myAudioSource.Play();
pfAudio.SetActive(true);
pfAudioSource.Play();
if (pfAudioSource.isPlaying)
{
wAudio.SetActive(false);
pAudio.SetActive(false);
rAudio.SetActive(false);
}
//StartCoroutine(pfPanelCoroutine(pfPanel));
StartCoroutine(PanelCoroutine(pfPanel));
}
else
{
}
}
IEnumerator PanelCoroutine(GameObject myPanel)
{
myPanel.SetActive(true);
yield return new WaitForSeconds(35);
myPanel.SetActive(false);
infoPanel.SetActive(true);
if (redCell == true)
{
if(GameObject.FindWithTag("RedAudio"))
Destroy (GameObject.FindWithTag("RedAudio"));
}
else if (whiteCell == true)
{
if(GameObject.FindWithTag("WhiteAudio"))
Destroy (GameObject.FindWithTag("WhiteAudio"));
}
else if (plateletCell == true)
{
if(GameObject.FindWithTag("PLAudio"))
Destroy (GameObject.FindWithTag("PLAudio"));
}
else if (plasmodiumCell == true)
{
if(GameObject.FindWithTag("PFAudio"))
Destroy (GameObject.FindWithTag("PFAudio"));
}
}
void Update()
{
if (redCell == true && whiteCell == true && plateletCell == true)
{
Debug.Log("yay");
rPanel.SetActive(false);
pPanel.SetActive(false);
wPanel.SetActive(false);
welldonePanel.SetActive(true);
//StartCoroutine(DoneCoroutine(welldonePanel));
plasmodiumGroup.SetActive(true);
redCell = false;
whiteCell = false;
plateletCell = false;
}
if (plasmodiumCell == true)
{
welldonePanel.SetActive(false);
pfPanel.SetActive(false);
dragdropPanel.SetActive(true);
}
}

UNITY3D c# Teleport object on certain amount of points

I encountered a problem with this code. The "Killer" teleports to the location and immediately goes back to the starting position. I have 7 locations for the "Killer" to teleport to (around the player). Whats wrong with this code? (I am a newbie) If possible could you add a sound to every point collected? example. When I get 1 points a sound/audio file plays. Thanks for answers!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FpsScoreScript : MonoBehaviour
{
public int points;
bool isTeleported1 = false;
bool isTeleported2 = false;
bool isTeleported3 = false;
bool isTeleported4 = false;
bool isTeleported5 = false;
bool isTeleported6 = false;
bool isTeleported7 = false;
bool isTeleported8 = false;
public GameObject Killer;
public GameObject Player;
public Transform Destination;
public Transform KillerDestFarBack;
public Transform KillerDestCloseBack;
public Transform KillerDestRight;
public Transform KillerDestLeft;
public Transform KillerDestRightFront;
public Transform KillerDestLeftFront;
public Transform KillerDestFront;
public void Update()
{
if (points == 1 && !isTeleported1)
{
Teleport1();
}
if (points == 2 && !isTeleported2)
{
Teleport2();
}
if (points == 3 && !isTeleported3)
{
Teleport3();
}
if (points == 4 && !isTeleported4)
{
Teleport4();
}
if (points == 5 && !isTeleported5)
{
Teleport5();
}
if (points == 6 && !isTeleported6)
{
Teleport6();
}
if (points == 7 && !isTeleported7)
{
Teleport7();
}
if (points == 8 && !isTeleported8)
{
Teleport8();
}
}
void Teleport1()
{
isTeleported1 = true;
Killer.transform.position = KillerDestFront.transform.position;
}
void Teleport2()
{
isTeleported2 = true;
Killer.transform.position = KillerDestRightFront.transform.position;
}
void Teleport3()
{
isTeleported3 = true;
Killer.transform.position = KillerDestLeftFront.transform.position;
}
void Teleport4()
{
isTeleported4 = true;
Killer.transform.position = KillerDestRight.transform.position;
}
void Teleport5()
{
isTeleported5 = true;
Killer.transform.position = KillerDestLeft.transform.position;
}
void Teleport6()
{
isTeleported6 = true;
Killer.transform.position = KillerDestFarBack.transform.position;
}
void Teleport7()
{
isTeleported7 = true;
Killer.transform.position = KillerDestCloseBack.transform.position;
}
void Teleport8()
{
isTeleported8 = true;
Player.transform.position = Destination.transform.position;
}
}
Instead of using many Transform vars, I would prefer using a transform array, also I have used an array of bools has teleported. I would prefer you to follow some tutorials or get a book. Add a collider to your player and the coin.
[SerializeField] Transform[] teleportPoints;
[SerializeField]Transform coin;
bool[] hasTeleported;
AudioSource source;
int points = 0 ;
void Awake()
{
source = GetComponent<AudioSource>();
hasTeleported = new bool[teleportPoints.Length];
}
private void Update()
{
for(int i = 0; i <= teleportPoints.Length; i++)
{
if (points == i && !hasTeleported[i])
{
Teleport(i);
}
}
}
void Teleport(int index)
{
transform.position = teleportPoints[index].position;
hasTeleported[index] = true;
}
void IncreasePoints()
{
source.Play();
points++;
}
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject == coin.gameObject)
{
IncreasePoints();
}
}

Unity: How do I start my weapon reload countdown when I am reloading?

I have a Timer that counts down every 3 seconds (The white circle). It has a script attached called ReloadTimer.
I have a script that fires bullets (TankShooter) and reloads for 3 seconds.
How do I make it so that my countdown starts when I am reloading?
I tried looking at a lot of Unity forums and the advice didn't work.
ReloadTimer.cs
[ExecuteInEditMode]
public class ReloadTimer : MonoBehaviour
{
public Image filled;
public Text text;
public float maxValue = 3;
public float value = 0;
// UpdateReload is called once per frame
public void UpdateReload ()
{
value = Mathf.Clamp(value, 0, maxValue);
float amount = value / maxValue;
filled.fillAmount = amount;
text.text = value.ToString();
}
}
TankShooter
public int m_PlayerNumber = 1;
public Rigidbody m_Shell;
public Transform m_FireTransform;
public AudioSource m_ShootingAudio;
public AudioClip m_FireClip;
public float m_ShellVelocity = 100f;
private string m_FireButton;
public int maxAmmo = 5;
private int currentAmmo;
public float reloadTime = 2f;
private bool isReloading = false;
public ReloadTimer reloadTimer;
public class TankShootingT : NetworkBehaviour
{
public ReloadTimer reloadTimer;
private void Start()
{
if (!isLocalPlayer)
{
return;
}
currentAmmo = maxAmmo;
m_FireButton = "Fire" + m_PlayerNumber;
}
private void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
reloadTimer.UpdateReload();
if (m_FireButton == "Fire1" && Input.GetButtonUp(m_FireButton))
{
// we released the button, have not fired yet
CmdShoot();
}
}
IEnumerator Reload()
{
isReloading = true;
Debug.Log("Reloading...");
yield return new WaitForSeconds(reloadTime);
currentAmmo = maxAmmo;
isReloading = false;
}
[Command]
private void CmdShoot()
{
currentAmmo--;
// Instantiate and launch the shell.
Rigidbody shellInstance = Instantiate(m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
shellInstance.velocity = m_ShellVelocity * m_FireTransform.forward;
// Server spawns the shell
NetworkServer.Spawn(shellInstance.gameObject);
m_ShootingAudio.clip = m_FireClip;
m_ShootingAudio.Play();
}
}
For starters, There isn't such thing as UpdateReload that would be "called once per frame" as this is not a predetermined Unity function, it is just a function that you created (You can read about this here). Another problem is that you didn't even call that function anywhere else in your scripts. And even if you did, Mathf.Clamp() needs to be placed in an Update() function so it can update it's value each frame.
I made some modifications to the scripts that you posted, but I haven't tested them yet. give it a try and let me know how it goes:
ReloadTimer.cs
public class ReloadTimer : MonoBehaviour
{
public static ReloadTimer Instance { set; get; }
public Image filled;
public Text text;
public float coolDownTime = 3;
public bool isCoolingDown = false;
void Awake()
{
Instance = this;
}
void Update()
{
if (isCoolingDown == true)
{
filled.fillAmount += 1.0f / coolDownTime * Time.deltaTime;
int percentageInt = Mathf.RoundToInt((filled.fillAmount / coolDownTime) * 10);
text.text = percentageInt.ToString();
}
}
}
TankShootingT.cs
public int m_PlayerNumber = 1;
public Rigidbody m_Shell;
public Transform m_FireTransform;
public AudioSource m_ShootingAudio;
public AudioClip m_FireClip;
public float m_ShellVelocity = 100f;
private string m_FireButton;
public int maxAmmo = 5;
private int currentAmmo;
public float reloadTime = 2f;
private bool isReloading = false;
public ReloadTimer reloadTimer;
public class TankShootingT : NetworkBehaviour
{
public ReloadTimer reloadTimer;
private void Start()
{
if (!isLocalPlayer)
{
return;
}
currentAmmo = maxAmmo;
m_FireButton = "Fire" + m_PlayerNumber;
}
private void Update()
{
if (isReloading)
return;
if (currentAmmo <= 0)
{
StartCoroutine(Reload());
return;
}
reloadTimer.UpdateReload();
if (m_FireButton == "Fire1" && Input.GetButtonUp(m_FireButton))
{
// we released the button, have not fired yet
CmdShoot();
}
}
IEnumerator Reload()
{
isReloading = true;
ReloadTimer.Instance.isCoolingDown = true;
Debug.Log("Reloading...");
yield return new WaitForSeconds(reloadTime);
currentAmmo = maxAmmo;
isReloading = false;
ReloadTimer.Instance.isCoolingDown = false;
ReloadTimer.Instance.filled.fillAmount = 0.0f;
}
[Command]
private void CmdShoot()
{
currentAmmo--;
// Instantiate and launch the shell.
Rigidbody shellInstance = Instantiate(m_Shell, m_FireTransform.position, m_FireTransform.rotation) as Rigidbody;
shellInstance.velocity = m_ShellVelocity * m_FireTransform.forward;
// Server spawns the shell
NetworkServer.Spawn(shellInstance.gameObject);
m_ShootingAudio.clip = m_FireClip;
m_ShootingAudio.Play();
}
}
Hope this helps a bit.

Using code in other class

My code works perfectly in the player class, but when I try to put it in a different class, it does nothing. My player doesn't lose lifes, and he doesn't die.
Here it doesn't work:
Spikes class
using UnityEngine;
using System.Collections;
public class Spikes : MonoBehaviour
{
SimplePlayer0 player = new SimplePlayer0();
Animator anim;
private bool isDead;
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "spike" && !isDead && player.Lives <= 1 && !player.IsImmune)
{
player.Lives = 0;
isDead = true;
}
else if (other.gameObject.tag == "spike" && player.Lives >= 1 && !player.IsImmune)
{
player.Lives--;
anim.SetBool("Immume", true);
player.IsImmune = true;
}
}
void OnTriggerStay2D(Collider2D other)
{
if (other.tag == "spike" && !isDead && player.Lives <= 1 && !player.IsImmune)
{
player.Lives = 0;
isDead = true;
}
else if (other.gameObject.tag == "spike" && player.Lives >= 1 && !player.IsImmune)
{
player.Lives--;
anim.SetBool("Immume", true);
player.IsImmune = true;
}
}
void OnCollisionStay2D(Collision2D other)
{
if (other.gameObject.tag == "spike" && !isDead && player.Lives <= 1 && !player.IsImmune)
{
player.Lives = 0;
isDead = true;
}
else if (other.gameObject.tag == "spike" && player.Lives > 1 && !player.IsImmune)
{
player.Lives--;
anim.SetBool("Immune", true);
player.IsImmune = true;
}
else if (other.gameObject.tag == "Underground")
{
isDead = true;
}
}
void Dead()
{
if (isDead == true)
{
Application.LoadLevel(8);
}
}
}
Player class
using UnityEngine;
using System.Collections;
public class SimplePlayer0 : MonoBehaviour
{
Animator anim;
//Lives
private int lives = 3;
private bool isImmune;
public float immuneCounter;
public float immuneTime;
//PROPERTIES
public int Lives
{
get { return lives; }
set { lives = value; }
}
public bool IsImmune
{
get { return isImmune; }
set { isImmune = value; }
}
void Start ()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (IsImmune)
{
immuneCounter -= Time.deltaTime;
}
if (immuneCounter <= 0)
{
IsImmune = false;
immuneCounter = immuneTime;
anim.SetBool("Immume", false);
}
}
This was the original code where it did work:
using UnityEngine;
using System.Collections;
public class Player0 : MonoBehaviour
{
Animator anim;
//Lives
public int lives = 3;
public bool isImmune;
public float immuneCounter;
public float immuneTime;
public bool isDead;
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (isImmune)
{
immuneCounter -= Time.deltaTime;
}
if (immuneCounter <= 0)
{
isImmune = false;
immuneCounter = immuneTime;
anim.SetBool("Immume", false);
}
if (isDead == true)
{
Application.LoadLevel(8);
}
void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "spike" && !isDead && lives <= 1 && !isImmune)
{
rigidbody2D.velocity = Vector2.zero;
lives = 0;
rigidbody2D.AddForce(new Vector2(0, 200)); // death animation
isDead = true;
}
else if (other.gameObject.tag == "spike" && lives >= 1 && !isImmune)
{
lives--;
anim.SetBool("Immume", true);
isImmune = true;
}
}
void OnTriggerStay2D(Collider2D other)
{
if (other.tag == "spike" && !isDead && lives <= 1 && !isImmune)
{
rigidbody2D.velocity = Vector2.zero;
lives = 0;
rigidbody2D.AddForce(new Vector2(0, 200));
isDead = true;
}
else if (other.gameObject.tag == "spike" && lives >= 1 && !isImmune)
{
lives--;
anim.SetBool("Immume", true);
isImmune = true;
}
else if (other.gameObject.tag == "Underground")
{
rigidbody2D.AddForce(new Vector2(0, 200));
isDead = true;
}
}
void OnCollisionStay2D(Collision2D other)
{
if (other.gameObject.tag == "spike" && !isDead && lives <= 1 && !isImmune)
{
rigidbody2D.velocity = Vector2.zero;
lives = 0;
rigidbody2D.AddForce(new Vector2(0, 200));
isDead = true;
}
else if (other.gameObject.tag == "spike" && lives > 1 && !isImmune)
{
lives--;
anim.SetBool("Immune", true);
isImmune = true;
}
else if (other.gameObject.tag == "Underground")
{
rigidbody2D.velocity = Vector2.zero;
lives = 0;
isDead = true;
}
}
}
My guess is that your "Player" doesn't lose lives, because the object you're subtracting the lives from isn't your player. In your Spikes class, you're creating an all new Player object and decreasing the lives from that object, not your already available one.
What I would do, is have a GameController script, which instantiates the player (and anything else that may be required). That way, you know that you've only got one player object to work with.
For example:
public static class GameController
{
public static Player myOnlyPlayer; // either drag in the editor, or instantiate
}
Then you can use the following to access the object:
public class Spike
{
void OnCollisionEnter2D(Collision2D other)
{
// Do something with:
GameController.myOnlyPlayer.ReduceLifeCount();
}
}
Hope this helps!
Firstly - instantiating subclasses of MonoBehaviour via new is an error in itself - I am referring to SimplePlayer0 player = new SimplePlayer0(); in Spikes.cs. Don't do that.
Secondly - LokiSinclair's answer would work, but using a global variable for storing player and always applying the damage to it is very limiting. We should just check for what has collided with spikes and then decide what to do with it (mind you, my code isn't a really elegant solution either):
using UnityEngine;
using System.Collections;
public class Spikes : MonoBehaviour
{
private void ResolveDamage(Collision2D other){
if (other.gameObject.tag == "player"){
var player = other.gameObject.getComponent<SimplePlayer0>();
if(!player.IsImmune){
player.Lives--;
}
}
}
void OnCollisionEnter2D(Collision2D other)
{
ResolveDamage(other);
}
void OnTriggerStay2D(Collision2D other)
{
ResolveDamage(other);
}
void OnCollisionStay2D(Collision2D other)
{
ResolveDamage(other);
}
}
And your player logic should be contained in Player class - that's just a good design principle to follow:
using UnityEngine;
using System.Collections;
public class SimplePlayer0 : MonoBehaviour
{
Animator anim;
//Lives
private int lives = 3;
private bool isImmune;
public float immuneCounter;
public float immuneTime;
//PROPERTIES
//putting some logic in getters-setters of your properties
public int Lives
{
get { return lives; }
set {
if(lives != value){
lives = value;
if(IsDead){
Dead();
}else{
IsImmune = true;
}
}
}
}
private void Dead()
{
Application.LoadLevel(8);
}
public bool IsImmune
{
get { return isImmune; }
set {
if(isImmune != value){
isImmune = value;
anim.SetBool("Immume", isImmune);
//ternary operator - a shorthand for if-else statement
immuneCounter = isImmune ? immuneTime : 0;
}
}
}
public bool IsDead{
get{
return Lives <= 0;
}
}
void Start ()
{
anim = GetComponent<Animator>();
}
void Update()
{
if (IsImmune)
{
immuneCounter -= Time.deltaTime;
}
if (immuneCounter <= 0)
{
IsImmune = false;
}
}

Categories