• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by harpoaian · Dec 11, 2017 at 03:46 PM · instantiatetransformtransform.positionintilization

Having issues with transform.Find();

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 alt text

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

infiltrator.png (34.1 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by tcjulian · Dec 11, 2017 at 05:55 PM

I'd strongly advise against using transform.Find because it is both slow and brittle. Here are two alternatives:


A. Make the reference to the missing transform available as a public static method or property:

In the first version of this, I forgot to add the static _instance, which prevented the code from compiling.

 ComponentAttachedToPlayer :  MonoBehaviour {
    [SerializeField] Transform _playerTransform; // Drag the transform into this field in the inspector
    public static Transform Player {
       get {  return _instance._playerTransform;  } // Be careful to include the '_instance' here
    }
 }

and then you can make your InfiltratorStateMachine reference the desired transform with ComponentAttachedToPlayer.Player.

You'll also need to declare and assign the player _instance with something like this:

 static ComponentAttachedToPlayer _instance;
 
 void Awake () {
    _instance = this; // assign the current instance of the `ComponentAttachedToPlayer` to a statically available field
 }



B. Pass the player reference to the InfiltratorStateMachine when you instantiate a new enemy:

  // In the method where you instantiate the enemy:
 GameObject instantiatedEnemy = Instantiate<GameObject>(_enemyPrefab);
 InfiltratorStateMachine fsm = instantiatedEnemy.GetComponent<InfiltratorStateMachine>();
 fsm.Initialize(_playerTransform);
 //...
 // In InfiltratorStateMachine:
 public void Initialize (Transform player) {
    Player = player;
 }



Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image tcjulian · Dec 12, 2017 at 03:53 PM 0
Share

Oops: I had forgotten to include the code to access the instance in the static function. You'll want to modify the property like this:

  public static Transform Player
  {
      get
      {
          return _instance._playerTransform; // Note the static _instance, which will allow you to access the non-static field _playerTransform of that instance
      }
  }

And you need to declare and assign _instance:

 public static PlayerState$$anonymous$$achine _instance;
 
 void Awake () {
    if (_instance == null) {
       _instance = this;
    } else {
       Debug.LogError("_instance is already defined");
    }
 }





avatar image harpoaian tcjulian · Dec 12, 2017 at 05:07 PM 0
Share

I cannot reply to your comment for some reason so I posted my response down below

avatar image tcjulian harpoaian · Dec 12, 2017 at 10:44 PM 0
Share

The _instance should be the same type as the script it is attached to. In this case, maybe you want public static InfiltratorState$$anonymous$$achine _instance; ins$$anonymous$$d?


"Cannot implicitly convert type InfiltratorState$$anonymous$$achine' to PlayerState$$anonymous$$achine'" on the line _instance = this; is because this is of type InfiltratorState$$anonymous$$achine but _instance is of type PlayerState$$anonymous$$achine. Sorry for the confusion.

Show more comments
avatar image
0

Answer by harpoaian · Dec 12, 2017 at 04:53 PM

I am still having issues with this I have 3 errors pop up error CS0029: Cannot implicitly convert type InfiltratorStateMachine' to PlayerStateMachine' Assets/The Guardian/Scripts/InfiltratorStateMachine.cs(119,8): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement Assets/The Guardian/Scripts/InfiltratorStateMachine.cs(122,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement

I did everything that you said am I misunderstanding something? Here is the updated code so you can see.

Kindly,

Harpoaian

Here is the code that is giving issues InfiltratorStateMachine

 public static PlayerStateMachine _instance;
 
     Dictionary<InfiltratorStates, Action> fsm = new Dictionary<InfiltratorStates, Action>();
 
 
     // Use this for initialization
     void Awake()
     {
         if(_instance == null)
         {
              //Line of code giving issue
             _instance = this;
         }
         else
         {
             Debug.LogError("_instance is already defined");
         }
         
     }
     void Start ()
     {
         theEnemy = GetComponent<Infiltrator>();
 
 
         Player = GameObject.Find("PlayerParent/Player/stealthStrike");
 
         //Error Line
        players.Player;
 
         //Error Line
         players.StealthStrike;

PlayerStateMachine

 public static PlayerStateMachine _instance;
 
 
 
     // GameObject Functions
     // Use this for initialization
     private void Awake()
     {
         health.Initialize();
         spiritEnergy.Initialize();
         nexaStones.Initialize();
     }
     void Start () 
     {
         Beserker = GameObject.Find("BeserkerParent/Beserker");
         thePlayer = player.GetComponent<Player>();
 
         players = player.GetComponent<PlayerStateMachine>();
 
         chargingDamage = Beserker.GetComponent<BeserkerStatemachine>();
 
 
         health.CurrentVal = 100;
 
         nexaStones.CurrentVal = 0;
 
         Bullet.GetResetCharge();
 
         facingRight = true;
 
         hasWolfFormUnlocked = true;
 
         inWolfForm = false;
 
         fsm.Add (PlayerStates.IDLE, StateIdle);
         fsm.Add (PlayerStates.RUN, StateRun);
         fsm.Add (PlayerStates.ENTER_JUMP, StateEnterJump);
         fsm.Add (PlayerStates.IN_AIR, StateInAir);
         fsm.Add (PlayerStates.USE_WEAPON, WeaponFire);
         fsm.Add (PlayerStates.USE_BEAMSABER, BeamSaberAttack);
         fsm.Add(PlayerStates.TAKE_DAMAGE, DamageState);
 
         SetState (PlayerStates.IDLE);
     }
     
     // Update is called once per frame
     void Update () 
     {
 
         fsm [curState].Invoke();
         float horizontal = Input.GetAxis("Horizontal");
        
        
 
     }
 
 
     // Helper Functions
    
     
     public static Transform Player
     {
         get
         {
                    
             return _instance._playerTransform;
             
         }
     }
 
     public static Transform StealthStrike
     {
         get
         {
                     
             return _instance._stealthStrike;
         }
     }




Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

107 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Bullet Not Firing in Correct Direction 0 Answers

Why can't I get the transform from an instantiated object? 1 Answer

Instantiate Object at the extreme end of the object 0 Answers

Maintain object position when using raycasting to multiple height 2 Answers

Setting parent of instantiated sprite 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges