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 Speed of enemy problem

Discussion in 'Scripting' started by rontzudik, Aug 1, 2023.

  1. rontzudik

    rontzudik

    Joined:
    Nov 16, 2022
    Posts:
    3
    I have an adversary that constantly pursues the player. Everything functions as expected until I use teleportation abilities, after which the enemy's speed is progressively reduced with each teleport. I've observed that the velocity magnitude of the enemy decreases each time I perform a teleportation.
    Enemy Movement code:
    Code (CSharp):
    1. [SerializeField] public GameObject player;
    2.     private Transform playerTransform;
    3.     [SerializeField] private float movementSpeed;
    4.     private Rigidbody2D rb;
    5.  
    6.     private void Start()
    7.     {
    8.         rb = GetComponent<Rigidbody2D>();
    9.        
    10.     }
    11.  
    12.  
    13.     private void FixedUpdate()
    14.     {
    15.         playerTransform = player.transform;
    16.         if (player != null)
    17.         {
    18.             // Calculate the direction to the player
    19.             Vector3 direction = (playerTransform.position - transform.position).normalized;
    20.             float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
    21.             rb.rotation = angle;
    22.             Vector2 moveDirection = direction;
    23.             rb.velocity = moveDirection * movementSpeed;
    24.             print(new Vector2(moveDirection.x, moveDirection.y));
    25.  
    26.         }
    27.        
    28.     }
    Teleport code:
    Code (CSharp):
    1. private Transform player;
    2.     private Rigidbody2D rb;
    3.     public LayerMask IgnoreMe;
    4.    
    5.  
    6.     void Start()
    7.     {
    8.         player = GameObject.FindGameObjectWithTag("Player").transform;
    9.         rb = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
    10.     }
    11.  
    12.    
    13.     void Update()
    14.     {
    15.         if (Input.GetMouseButtonDown(0))
    16.         {
    17.             if (IsRaycastTouchingBorders())
    18.             {
    19.                
    20.                 StartCoroutine(DelayAction(0.5f));
    21.                
    22.             }
    23.         }
    24.     }
    25.  
    26.     private void TeleportPlayer()
    27.     {
    28.         Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    29.         Vector3 newPosition = mousePosition;
    30.  
    31.         // Ensure the new position is not blocked by the "Border" tag before teleporting
    32.         if (IsRaycastTouchingBorders())
    33.         {
    34.             player.position = newPosition;
    35.         }
    36.     }
    37.     public bool IsRaycastTouchingBorders()
    38.     {
    39.         Vector3 playerPosition = player.position;
    40.         Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    41.  
    42.         RaycastHit2D hit = Physics2D.Raycast(playerPosition, mousePosition - playerPosition, Vector3.Distance(playerPosition, mousePosition) , ~IgnoreMe);
    43.         if (hit.collider != null)
    44.         {
    45.             if (hit.collider.CompareTag("Border"))
    46.             {
    47.                 return false;
    48.             }
    49.         }
    50.        
    51.         return true;
    52.              
    53.     }
    54.  
    55.     IEnumerator DelayAction(float delayTime)
    56.     {
    57.        
    58.         yield return new WaitForSeconds(delayTime);
    59.         TeleportPlayer();
    60.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,560
    Don't stop there... print out how you got these values! Sounds like something is making movementSpeed get smaller.

    What's this:

    You dereference player to get the transform, then you use player and test against null?? It would have blown up in the line above it if it was null.

    Why not just keep player and check it, then use its Transform directly if it still is alive.

    Also, all of this noise:

    Seriously try to avoid stuff like this. It's just ninja code and will eventually give you trouble.

    Keep in mind that using GetComponent<T>() and its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.

    This sort of coding is to be avoided at all costs unless you know exactly what you are doing.

    If you run into an issue with any of these calls, start with the documentation to understand why.

    There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.

    In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.

    It is ALWAYS better to go The Unity Way(tm) and make dedicated public fields and drag in the references you want.
     
  3. rontzudik

    rontzudik

    Joined:
    Nov 16, 2022
    Posts:
    3
    So what write instead?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,560
    this:

    That's how everything should ideally be done in Unity.

    Otherwise, if you really need dynamic stuff:

    Remember the first rule of GameObject.Find():

    Do not use GameObject.Find();

    More information: https://starmanta.gitbooks.io/unitytipsredux/content/first-question.html

    More information: https://forum.unity.com/threads/why-cant-i-find-the-other-objects.1360192/#post-8581066
     
  5. rontzudik

    rontzudik

    Joined:
    Nov 16, 2022
    Posts:
    3
    The problem that a prefab and can i cant drag to there transform
     
  6. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    caching the component
    playerTransform = player.transform;
    is better performance wise, as any cached value is better than it's GetComponent() counterpart, as
    gameObject.transform
    does. However, you only need that reference once, so it should be in your Start() method, not called each fixedUpdate(). This is of course assuming your player never gets deleted, and re-instantiated.

    And I'm not too sure on how your teleport class works(communication wise), but as Kurt mentioned there are better ways to handle said issue. But if your just playing around with ideas, and testing things, by all means do what you gotta do to get to the meat and potatoes. Make it work first, then make it better(frustration vs both is debatable).

    And Kurt meant, "Don't stop there:
    print(new Vector2(moveDirection.x, moveDirection.y));
    ", meaning also print your movement speed. As your normalized vector shouldn't be having an issue, so something may be changing your movement speed. Just setting these variables to public, for testing purposes, helps so you can just watch the Inspector.