Good Morning
I have this infiltrator enemy in my game that when the player is in range it teleports to a Game Object behind my player. Everything works great when all of my references are filled out. But I have another enemy in my game that summons other enemies to the scene. So when the summoner enemy summons an instantiated infiltrator it is broken. This is because when it is instantiated the Stealth Attack area and the follow this object references are empty.
Here is a picture of the inspector of instantiated Infiltrator
So I know what I need to do, I need to make it so that transforms for Follow This Object and Stealth Attack Area and Player are initialized in the Start(); I feel looked up the correct method to do this, and that is using transform.Find. When I tried this I broke my infiltrator enemy. Here is the code relevant to the problem.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class InfiltratorStateMachine : MonoBehaviour
{
private enum InfiltratorStates
{
PATROL,
ATTACK,
STEALTH,
TAKE_DAMAGE
}
//Exposed Variables
//----------------------------------------------------------------------
[SerializeField]
private Transform sightStart;
[SerializeField]
private Transform wallEnd;
[SerializeField]
private Transform attackStart;
[SerializeField]
private Transform sightEnd;
[SerializeField]
private Transform stealthStart;
[SerializeField]
private Transform player;
[SerializeField]
private Transform stealthAttackArea;
[SerializeField]
private LayerMask detectWhat;
public GameObject[] PickupTypes;
public GameObject sword;
public GameObject stealthSword;
public GameObject followThisObject;
public GameObject infilitratorTeleport;
public GameObject Player;
public GameObject parentDeath;
public Animator swordAttack;
public Animator stealthSwordAttack;
public bool colliding;
public bool startAttack;
public bool startStealth;
public bool facingRight;
public bool inStealth;
public float moveSpeed = 5.0f;
public float stealthTimer = 0.0f;
public float alphaTimer = .5f;
//----------------------------------------------------------------------
//Private Variables
//----------------------------------------------------------------------
Infiltrator theEnemy;
private InfiltratorStates curState;
int layerMask = 8 << 9;
private bool hasBeenHit = false;
Dictionary<InfiltratorStates, Action> fsm = new Dictionary<InfiltratorStates, Action>();
//----------------------------------------------------------------------
// Use this for initialization
void Start ()
{
theEnemy = GetComponent<Infiltrator>();
//Need to fix the transform references for aerial fight and infiltrator https://docs.unity3d.com/ScriptReference/Transform.Find.html
Player = GameObject.Find("PlayerParent/Player/stealthStrike");
//This Line breaks my Infiltrator
Player = followThisObject.transform.Find("PlayerParent/Player/stealthStrike").gameObject;
//
facingRight = true;
inStealth = false;
fsm.Add(InfiltratorStates.PATROL, PatrolState);
fsm.Add(InfiltratorStates.STEALTH, StealthState);
fsm.Add(InfiltratorStates.ATTACK, AttackState);
fsm.Add(InfiltratorStates.TAKE_DAMAGE, DamageState);
SetState(InfiltratorStates.PATROL);
}
// Update is called once per frame
void Update ()
{
fsm[curState].Invoke();
}
//Helper Functions
//----------------------------------------------------------------------
void SpawnPickup()
{
int randIndex = UnityEngine.Random.Range(0, PickupTypes.Length);
Instantiate(PickupTypes[randIndex], transform.position, transform.rotation);
}
void OnTriggerEnter2D(Collider2D col)
{
if(col.tag == "PlayerProjectile")
{
SetState(InfiltratorStates.TAKE_DAMAGE);
Destroy(col.gameObject);
}
if(col.tag == "PlayerSaber")
{
SetState(InfiltratorStates.TAKE_DAMAGE);
}
}
void Vision()
{
startAttack = Physics2D.Linecast(sightStart.transform.position, attackStart.transform.position, 1 << LayerMask.NameToLayer("Player"));
startStealth = Physics2D.Linecast(sightStart.transform.position, stealthStart.transform.position, 1 << LayerMask.NameToLayer("Player"));
if(startAttack == true)
{
SetState(InfiltratorStates.ATTACK);
//sword.SetActive(true);
if (startStealth == true)
{
SetState(InfiltratorStates.STEALTH);
sword.SetActive(false);
//stealthSword.SetActive(true);
}
}
else
{
SetState(InfiltratorStates.PATROL);
sword.SetActive(false);
stealthSword.SetActive(false);
}
}
void Patrol()
{
GetComponent<Rigidbody2D>().velocity = new Vector2(moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
colliding = Physics2D.Linecast(sightStart.transform.position, wallEnd.transform.position, detectWhat);
this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
if (colliding == true)
{
transform.localScale = new Vector2(transform.localScale.x * -1, transform.localScale.y);
moveSpeed *= -1;
facingRight = !facingRight;
}
}
//----------------------------------------------------------------------
//State Functions
//----------------------------------------------------------------------
void PatrolState()
{
Patrol();
Vision();
}
void StealthState()
{
Vision();
//sword.SetActive(false);
stealthTimer += Time.deltaTime;
this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 0.1f);
if (stealthTimer >= 3 && inStealth == false)
{
inStealth = true;
this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 0.1f);
Debug.Log("I should be stealth and you cant see me");
stealthTimer = 0;
if(inStealth == true)
{
// This section of code makes it so that the infiltrator teleports behind the player and then it will become visable then attack otherwise stealth is false
infilitratorTeleport.transform.position = followThisObject.transform.position;
this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
//<Renderer>().material.color = new Color(1, 1, 1, alphaTimer);
stealthSword.SetActive(true);
stealthSwordAttack.GetComponent<Animator>().Play("StealthStrike");
Debug.Log("STEALTH STRIKE!!");
inStealth = false;
}
else
{
inStealth = false;
stealthSword.SetActive(false);
sword.SetActive(false);
this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
}
}
else
{
//stealthTimer = 0;
inStealth = false;
//this.GetComponent<MeshRenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
}
}
Am I using “Player = followThisObject.transform.Find(“PlayerParent/Player/stealthStrike”).gameObject;” wrong? Or should I go about this a different way?
Kindly,
Harpoaian