Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Set a trasnform target in an instantiated prefab

Discussion in 'Scripting' started by SemanticDuck, Sep 12, 2023.

  1. SemanticDuck

    SemanticDuck

    Joined:
    Jul 27, 2018
    Posts:
    6
    Hi

    I'm making a game an having lot of problems trying to resolve this one even after reading several answers in this and other forums, so I need to ask for help now

    So I have this prefab Enemy that is going to be instantiated to spawn at certain location, but how can I set the transform target? because as you know you cant just say public transform targetOne on a prefab and assign it because the inspector doesn't allow you to set a transform in an object that doesn't exist in the hierarchy.

    So if you can explain this one to me or if you have a documentation or video with examples will be highly appreciate. Thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Do you mean how to give the enemy a Transform to attack?

    Normally there would be a GameManager that would track things like "is there a player alive now" and "who is the closest player alive I can attack."

    Tons of tutorials on the function of a GameManager up on Youtube.
     
    SemanticDuck likes this.
  3. SemanticDuck

    SemanticDuck

    Joined:
    Jul 27, 2018
    Posts:
    6
    Hi Kurt
    Actually I read one of you answers in another post while searching for a solution, I remember because of the dog in your pic, lol.
    Is not a position to attack, is a position where the enemy will go and stole goods from the player, but I guess is practically the same, will look into gamemanager on youtube. And I already have the rest of the code and is working, the enemy appear randomly and going to a certain point and play the animation to pretend is stealing the goods but only works if the enemy already exists in the hierarchy and I want to instantiated several enemies to go to random location on the map.

    Will look into this, thanks
     
  4. SemanticDuck

    SemanticDuck

    Joined:
    Jul 27, 2018
    Posts:
    6
    Ok, so I need to create the gamemanager and in here I will set up the target transform as well as the instantiated enemy
    so this is the code line in the enemy script for the enemy to go to the target but only works as I said when the enemy is in the hierarchy

    transform.LookAt(targetPoint.transform.position);
    transform.position = Vector3.MoveTowards(transform.position, targetPoint.transform.position, enemySpeed * Time.deltaTime);

    I need to create the gamemanager script and in there I will set up the target transform, and I need to pass it to the enemy script right

    so the enemy will appear as an instantiated object and then the enemy script kicks in and do the rest of the work, but since the enemy doesn't have the target transform I need to pass it from the gamemanager to the enemy script

    As you can see I'm new on this and how I see in a lot of videos and answers in forums script communication is difficult for the newbies

    so in the GameManager script is going to be

    public Transform targetPoint; to assign in the inspector

    and this is where I get stuck because I need to call from the enemy script this transform
    and to make the reference will be something like

    private GameManager gameManager;

    and on start is gameManager = GetComponent<GameManager>();

    to make the target position reference in update function

    transform.LookAt(gameManager.targetPoint.transform.position);
    transform.position = Vector3.MoveTowards(transform.position, gameManager.targetPoint.transform.position, enemySpeed * Time.deltaTime);

    but the enemy is not moving

    Obviously I'm not referring to the target position properly, how do you pass a transform from one script to another?
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    The same way you would do if it was in the same hierarchy, the same way as if it had been dragged in. You have to locate it, such as with a GameManager, and then tell the enemy "use this Transform."

    Referencing variables, fields, methods (anything non-static) in other script instances:

    https://forum.unity.com/threads/hel...-vars-in-another-script.1076825/#post-6944639

    https://forum.unity.com/threads/accessing-a-gameobject-in-different-scene.1103239/

    It isn't always the best idea for everything to access everything else all over the place. For instance, it is BAD for the player to reach into an enemy and reduce his health.

    Instead there should be a function you call on the enemy to reduce his health. All the same rules apply for the above steps: the function must be public AND you need a reference to the class instance.

    That way the enemy (and only the enemy) has code to reduce his health and simultaneously do anything else, such as kill him or make him reel from the impact, and all that code is centralized in one place.

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    If your problem is with OnCollision-type functions, print the name of what is passed in!

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.
     
    SemanticDuck likes this.
  6. SemanticDuck

    SemanticDuck

    Joined:
    Jul 27, 2018
    Posts:
    6

    Thanks Kurt
    Yeah, it wasn't even get called because I didn't point to the script correctly, rookie mistakes
    but thanks for taking the time in replying. Cheers, have a great day!