Hi all,
First off, I’m a graphic designer, and not a coding expert. I’ve tried my best to figure out what I’m sure is a “simple” fix for any of you out there that know coding vs me, who can do things visually, but back-end stuff is not my skill.
The issue I’m having is this:
When a character dies in my game, if they die by being hit, everything functions properly, but if they die by any other means (burning, choking, anything non-contact) they still die, but the “death” animation doesn’t activate and they essentially stand idle. So then what happens is, once the character is back in free-roam, if they are hit by something (even if their health is refilled to the max), the player essentially freezes there until they are hit again.
I believe what’s happening is the coding is telling the player they’re dead, but because the player doesn’t follow through with the death animation and it recognizes that although there was no contact, the player has in fact died, the game is thinking the first hit after re-spawn is killing the player, when in fact they’ve already died.
I’ve attached the two scripts that interact with each other and if you take a look at the “deathtracker” script I believe whatever needs to be added for the characters non-contact death should be on line 104. The “player controller” script is where the dead/killable bool options for dying/hitting are.
If anyone can help, I would greatly appreciate it!!
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using System;
public class DeathTracker : MonoBehaviour
{
public static DeathTracker _instance;
public static DeathTracker instance {
get {
if (_instance == null) {
_instance = FindObjectOfType<DeathTracker> ();
}
return _instance;
}
set {
_instance = value;
}
}
void Awake ()
{
if (_instance == null) {
_instance = this;
}
}
public Transform NewGameSpawn, ContinueSpawn;
public void MovePlayer ()
{
}
private bool dead = false;
public void PlayerDeath ()
{
StartCoroutine (PlayerDeath2 ());
}
public void MissionDeath ()
{
StartCoroutine (MissionDeath2 ());
}
public IEnumerator MissionDeath2 ()
{
if (!dead) {
dead = true;
var player = (GMRewrite.currentCharacter as PlayerController);
player.canMove = false;
if (!CameraRewrite.instance.GetCamera.orthographic) {
CameraRewrite.instance.distanceUp = 7.5f;
CameraRewrite.instance.cameraMaxDistance = 25f;
}
yield return new WaitForSeconds (2);
Fader.instance.Fade (Color.black, 1, false, () => {
});
yield return new WaitForEndOfFrame ();
while (Fader.status != Fader.FaderStatus.ENDFADE) {
yield return null;
}
CameraRewrite.instance.distanceUp = 1f;
CameraRewrite.instance.cameraMaxDistance = 10f;
GMRewrite.currentMission.ExitToFreeroam (false, false);
Fader.instance.Fade (Color.black, 1, true, () => {
});
yield return new WaitForEndOfFrame ();
while (Fader.status != Fader.FaderStatus.ENDFADE) {
yield return null;
}
while (CenterScreenText.showing) {
yield return null;
}
if (!GMRewrite.tutorialHealthLost) {
GMRewrite.tutorialHealthLost = true;
DialogueComic.instance.DisplayDialogue (DEBUG_GlobalUpdate.instance.healthLostDialogue, 0, () => {
player.canMove = true;
});
} else {
player.canMove = true;
}
dead = false;
}
}
public IEnumerator PlayerDeath2 ()
{
if (!dead) {
dead = true;
var player = GMRewrite.currentCharacter as PlayerController;
player.canMove = false;
//SOMETHING SHOULD GO HERE THAT ACTIVATES DEAD ANIMATION AND/OR RECOGNITION OF 0 HEALTH FROM PLAYER CONTROLLER
CameraRewrite.instance.distanceUp = 7.5f;
CameraRewrite.instance.cameraMaxDistance = 25f;
yield return new WaitForSeconds (2f);
yield return Fader.instance.Fade (Color.black, 1, false, () => {
});
player.CancelEverything (false);
player.transform.position = ContinueSpawn.position;
player.transform.rotation = ContinueSpawn.rotation;
CameraRewrite.instance.distanceUp = 1f;
CameraRewrite.instance.cameraMaxDistance = 10f;
yield return Fader.instance.Fade (Color.black, 1, true, () => {
});
if (!GMRewrite.tutorialHealthLost) {
GMRewrite.tutorialHealthLost = true;
DialogueComic.instance.DisplayDialogue (DEBUG_GlobalUpdate.instance.healthLostDialogue, 0, () => {
player.canMove = true;
});
} else {
player.canMove = true;
}
dead = false;
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using System;
public class PlayerController : Entity
{
public float animJumpHeight = 3f;
public bool hit = false, landing = false;
// public int heightIndex = 20;
public float sniffMoveRate;
public ParticleSystem digParticles;
public GameObject sniff;
public Transform sniffTarget, sniffZone;
private Vector3 defaultCenter;
public AudioClip barkClip;
void Start ()
{
movement = MovementBase.CreateJoystick ();
defaultCenter = ccont.center;
// aud = gameObject.GetComponent<AudioSource> ();
}
public bool killable;
// Update is called once per frame
public override void UpdateEntity ()
{
// Debug.Log ("Scene count: " + SceneManager.sceneCount);
if (killable) {
if (Health.currentValue <= 0) {
stayDead = true;
if (GMRewrite.currentMission) {
DeathTracker.instance.MissionDeath ();
} else {
DeathTracker.instance.PlayerDeath ();
}
killable = false;
}
}
if (!killable && Health.currentValue > 0) {
killable = true;
}
if (!GMRewrite.tutorialStaminaLost) {
if (Stamina.currentValue <= 0) {
if (GMRewrite.currentMission == null) {
bool comic = true;
if (ComicCutsceneManager.instance) {
comic = !ComicCutsceneManager.instance.comicMan.canvas.gameObject.activeSelf;
}
bool dialogue = !DialogueComic.instance.headLeft.gameObject.activeSelf;
bool status = Fader.status != Fader.FaderStatus.FADING;
// Debug.Log (comic + " " + dialogue + " " + status);
if (comic && status && dialogue) {
DialogueComic.instance.DisplayDialogue (DEBUG_GlobalUpdate.instance.staminaLostDialogue, 0, () => {
});
GMRewrite.tutorialStaminaLost = true;
}
}
}
}
if (!inAir) {
if (landing)
// AudMgr.PlaySound (AudMgr.instance.landing);
landing = false;
} else {
landing = true;
}
if (hit) {
}
if (anim.GetBool ("Sniff")) {
if (sniffTarget) {
sniff.SetActive (true);
sniff.transform.SetParent (sniffTarget);
// print ("sniffDistance " + Vector3.Distance (sniff.transform.position, sniffTarget.position));
if (Vector3.Distance (sniff.transform.position, sniffTarget.position) > 1) {
// print ("close");
Vector3 moveDirection = (sniffTarget.position - sniff.transform.position);
moveDirection.Normalize ();
print ("move " + moveDirection);
sniff.GetComponent<CharacterController> ().SimpleMove (moveDirection * sniffMoveRate);
} else {
sniff.transform.position = transform.position;
}
} else if (sniffZone) {
InputController.instance.FPLook ();
}
} else {
sniff.SetActive (false);
sniff.transform.SetParent (transform);
sniff.transform.position = transform.position;
}
try {
movement.Move (this);
} catch (NullReferenceException e) {
Debug.LogWarning ("NPC IMovement field is Null\n" + e.Message);
}
UpdateCContPosition ();
// RefillTracker.instance.RefillUpdate ();
}
internal void FallOver()
{
throw new NotImplementedException();
}
private void UpdateCContPosition ()
{
float addy = anim.GetFloat ("AdditionalY");
ccont.center = defaultCenter + Vector3.up * addy * animJumpHeight;
}
void LateUpdate ()
{
Animate ();
}
private void Animate ()
{
anim.SetBool ("inAir", inAir);
float normalWalk = (Speed.currentValue / Speed.maxValue);
float normalSprint = (Mathf.Max (0, Speed.currentValue - Speed.maxValue) / Sprint.maxValue);
float speed = Mathf.Clamp (normalWalk, -1, 1) + normalSprint;
anim.SetBool ("Sprint", sprinting);
anim.SetFloat ("Speed", speed);
}
public bool barking{ get; set; }
public bool barkTick = false;
public override void Bark ()
{
StartCoroutine (bark ());
}
IEnumerator bark ()
{
barking = true;
anim.SetTrigger ("Barking");
yield return new WaitForSeconds (barkAnimOffsets.x);
AudMgr.PlaySFX (barkClip);
if (StaticM8Reference.isMission8) {
yield return new WaitForSeconds (0.25f);
barkTick = true;
StaticM8Reference.mission8.BlastCone.PlayBlast ();
}
// yield return new WaitForSeconds (barkAnimDelay);
yield return new WaitForSeconds (barkAnimOffsets.y);
AudMgr.PlaySFX (barkClip);
barkTick = true;
yield return null;
barkTick = false;
barking = false;
}
public bool digging{ get; set; }
public bool digTick = false;
public float particleSpeed;
public static float[] burstDelay2 = new float[] {
1f + (15f / 30f),
(15f / 30f),
(15f / 30f),
(10f / 30f),
(7f / 30f),
(4f / 30f),
(4f / 30f),
(6f / 30f),
};
public void Dig ()
{
// StartCoroutine (dig ());
StartCoroutine (perfectDig ());
}
IEnumerator perfectDig ()
{
canMove = false;
digging = true;
anim.SetBool ("Digging", digging);
int count = burstDelay2.Length;
var emission = digParticles.emission;
for (int i = 0; i < count; i++) {
digTick = false;
yield return new WaitForSeconds (burstDelay2 [i]);
if (i == count - 1) {
// Debug.Log ("Dig Tick");
digParticles.Emit (300);
digTick = true;
} else {
// Debug.Log ("Regular Dig");
digParticles.Emit (100);
}
}
yield return new WaitForSeconds (20f / 30f);
digTick = false;
digging = false;
anim.SetBool ("Digging", digging);
if ((GMRewrite.currentCharacter as PlayerController).sniffTarget)
(GMRewrite.currentCharacter as PlayerController).sniffTarget.GetComponent<MeshRenderer> ().enabled = true;
canMove = true;
}
void OnTriggerEnter (Collider other)
{
if ((other.gameObject.CompareTag ("Projectile") || other.gameObject.CompareTag ("Enemy"))) {
Vector3 v = other.transform.position - transform.position;
int dir = Vector3.Cross (transform.forward, v).y > 0 ? 1 : -1;
FallOver (dir);
}
if ((other.gameObject.layer == LayerMask.NameToLayer ("Water"))) {
// if (!inWater) {
// AudMgr.PlaySFX (AudMgr.instance.jumpWater);
// }
inWater = true;
}
}
public void FallOver (int dir)
{
if (!hit) {
hit = true;
StartCoroutine (GetHit (dir, true));
}
}
private bool stayDead{ get; set; }
public static PlayerController _IEnumerator;
public static PlayerController IEnumerator
{
get
{
if (_IEnumerator == null)
{
_IEnumerator = FindObjectOfType<PlayerController>();
}
return _IEnumerator;
}
set
{
_IEnumerator = value;
}
}
IEnumerator GetHit (int dir, bool reset)
{
Health.currentValue = Mathf.Clamp (Health.currentValue - 1, 0, Health.maxValue);
bool dead = Health.currentValue <= 0;
if (!dead || !killable) {
string side = dir > 0 ? "TakeDamageR" : "TakeDamageL";
anim.SetTrigger (side);
iOSHapticFeedback.Instance.Trigger(iOSHapticFeedback.iOSFeedbackType.ImpactHeavy);
} else {
string side = dir > 0 ? "DeadRight" : "DeadLeft";
anim.SetBool (side, true);
iOSHapticFeedback.Instance.Trigger(iOSHapticFeedback.iOSFeedbackType.Failure);
}
AudMgr.PlaySFX (AudMgr.instance.getHit);
canMove = false;
yield return new WaitForSeconds (1.8f);
if (!stayDead) {
CancelEverything (true);
}
yield return new WaitForEndOfFrame ();
stayDead = false;
yield return new WaitForSeconds (1.5f);
hit = false;
}
private bool inWater = false;
public override void Footstep ()
{
if (inWater) {
inWater = false;
aud.clip = AudMgr.instance.WalkWater;
aud.volume = 0.5f;
aud.pitch = 1 + (UnityEngine.Random.value - 0.5f) * 0.25f;
aud.Play ();
return;
}
aud.volume = 1f;
Ray ray = new Ray (GMRewrite.currentCharacter.transform.position, Vector3.down);
RaycastHit hit;
if (Physics.Raycast (ray, out hit)) {
if (hit.collider.CompareTag ("Terrain")) {
aud.volume = 0.5f;
aud.clip = AudMgr.instance.WalkGrass;
} else if (hit.collider.CompareTag ("Wood")) {
aud.clip = AudMgr.instance.WalkWood;
} else {
aud.clip = AudMgr.instance.WalkConcrete;
}
}
aud.pitch = 1 + (UnityEngine.Random.value - 0.5f);
aud.Play ();
}
public Transform LeftHeadIKTarget;
public Transform RightHeadIKTarget;
public void GetPet (float duration, float speed)
{
StartCoroutine (pet (duration, speed));
}
private IEnumerator pet (float duration, float speed)
{
Vector3 iL = LeftHeadIKTarget.position;
Vector3 iR = RightHeadIKTarget.position;
Vector3 head = iL + (iR - iL) / 2;
float a = 0;
while (a < duration) {
a += Time.deltaTime;
Vector3 dL = iL - head;
Vector3 dR = iR - head;
float sinTime = Mathf.Sin (a * speed);
Vector3 refL = Vector3.Cross (Vector3.up, dL) * 27.5f;
Vector3 refR = Vector3.Cross (Vector3.up, dR) * 27.5f;
float time = (1 + sinTime) / 2f;
dL = Quaternion.Lerp (Quaternion.Euler (refL), Quaternion.Euler (-refL), time) * dL;
dR = Quaternion.Lerp (Quaternion.Euler (-refR), Quaternion.Euler (refR), time) * dR;
Debug.DrawRay (head, dL);
Debug.DrawRay (head, dR);
LeftHeadIKTarget.position = head + dL;
RightHeadIKTarget.position = head + dR;
yield return null;
}
LeftHeadIKTarget.position = iL;
RightHeadIKTarget.position = iR;
yield return null;
}
public bool rolling = false;
public void Roll ()
{
if (!canMove || !anim.GetCurrentAnimatorStateInfo (0).IsName ("idle") || (GMRewrite._controlMethod == (int)CMRewrite.LOOK)) {
return;
}
anim.SetTrigger ("Trick");
StartCoroutine (Rolling ());
}
IEnumerator Rolling ()
{
GMRewrite.currentCharacter.canMove = false;
rolling = true;
yield return new WaitForSeconds (2);
rolling = false;
GMRewrite.currentCharacter.canMove = true;
}
public void CancelEverything (bool canMove)
{
StopAllCoroutines ();
anim.SetBool ("Digging", false);
anim.SetBool ("DeadLeft", false);
anim.SetBool ("DeadRight", false);
anim.SetBool ("Barking", false);
anim.SetBool ("Sniff", false);
anim.ResetTrigger ("Trick");
anim.SetTrigger ("ResetAnimations");
digParticles.emissionRate = 0;
digging = false;
rolling = false;
hit = false;
reverse = walking = running = sprinting = false;
Stamina.currentValue = Mathf.Floor (Stamina.currentValue / Stamina.statValue) * Stamina.statValue;
this.canMove = canMove;
}
}
8287725–1086231–DeathTracker.cs (3.04 KB)
8287725–1086234–PlayerController.cs (9.93 KB)