Home>

I'm writing an enemy script in unity2d.
I want to realize a rotation process that turns to the opposite direction after a certain time, but if I add a rotation process after a certain time, it will go in the opposite direction the first time and proceed as it is, but after the second time it will turn to the opposite direction. After that, I turn to the opposite direction and begin to roughen. What is the cause? I would appreciate it if you could teach me.

Regarding rotation after a certain period of time, I want it to work when I have not found a player, and it does not work until I lose sight of it.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enemy_Move: MonoBehaviour
{
    public GameObject target;
    ContactFilter2D right_hit;
    ContactFilter2D left_hit;
    float x_Dis;
    Rigidbody2D rb2d;
    ///<summary>
    /// Velocity vector flag (when true, right)
    ///</summary>
    private bool minus_Sp;
    private bool not_Discovery;
    [Header ("Movement speed")] float enemy_Speed ​​= 1f;
    [Header ("Time to change direction n")] float returnTime = 5f;// 5 seconds later
    void Start ()
    {
        not_Discovery = true;
        right_hit.useNormalAngle = true;
        right_hit.minNormalAngle = 0;
        right_hit.maxNormalAngle = 40;
        left_hit.useNormalAngle = true;
        left_hit.minNormalAngle = 140;
        left_hit.maxNormalAngle = 180;
        rb2d = GetComponent<Rigidbody2D>();
        rb2d.constraints = RigidbodyConstraints2D.FreezeRotation;
        rb2d.mass = 0.5f;
        this.target = GameObject.Find ("player");
    }
    void Update ()
    {
        bool wall_left = GetComponent<Rigidbody2D>(). IsTouching (right_hit);
        bool wall_right = GetComponent<Rigidbody2D>(). IsTouching (left_hit);
        Discovery ();// Processing at the time of discovery
        rb2d.velocity = new Vector2 (minus_Sp == true? -enemy_Speed: enem_Speed, 0);
        x_Dis = Mathf.Abs (this.gameObject.transform.position.x-target.transform.position.x);
        if (wall_left) // When hitting something right to left
        {
                minus_Sp = false;
                EnemyRot (0);// turn around
        }
        if (wall_right) // Left to right when something hits
        {
                minus_Sp = true;
                EnemyRot (-1);// turn around
        }
// Process that rotates here after a certain period of time (now turns to the opposite direction after 5 seconds)
        if (not_Discovery) // pass if no player is found
        {
            if (transform.localEulerAngles.y == 0)
            {
                Invoke ("Rote_L", returnTime);
            }
            if (transform.localEulerAngles.y == 180)
            {
                Invoke ("Rote_R", returnTime);
            }
        }
    }
    void EnemyRot (float minus) // turn around
    {
        Quaternion enemy_rot = transform.rotation;
        transform.rotation = Quaternion.Euler (enemy_rot.x, 180 * minus, enemy_rot.z);
    }
    void Discovery () // Process when Player is found
    {
        Ray2D ray2D = new Ray2D (transform.position, transform.right);
        RaycastHit2D hit2D = Physics2D.Raycast (ray2D.origin, ray2D.direction);
        Debug.DrawRay (ray2D.origin, ray2D.direction, Color.red);

        if (hit2D.collider.tag == "Player")
        {
            not_Discovery = false;// Automatic rotation flag off as found
            float step = enemy_Speed ​​* Time.deltaTime;

            if (x_Dis>0) // chase until the distance becomes 0
            {
                Vector2 pos = this.target.transform.position;
                transform.position = Vector2.MoveTowards (transform.position, pos, step);
            }
       }
        else
        {
            not_Discovery = true;
        }
    }

    void Rote_R () // Automatic rotation processing right to left
    {
        Quaternion enemy_rot = transform.rotation;
        transform.rotation = Quaternion.Euler (enemy_rot.x, 0, enemy_rot.z);
        minus_Sp = false;// reverse the velocity vector
    }
    void Rote_L () // Automatic rotation processing left to right
    {
        Quaternion enemy_rot = transform.rotation;
        transform.rotation = Quaternion.Euler (enemy_rot.x, -180, enemy_rot.z);
        minus_Sp = true;
    }
}
  • Answer # 1

    Since the rotation process is called by Invoke,
    I think that after 5 seconds it will rotate every time you update.

    Instead, set the initial value of returnTime to 0f,

    With Update ()
    returnTime + = Time.deltaTime;
    As

    The calling part of the rotation process

    if (not_Discovery&&returnTime>= 5f)
    {
        returnTime = 0;
        if (transform.localEulerAngles.y == 0)
        {
            Rote_L ();
        }
        if (transform.localEulerAngles.y == 180)
        {
            Rote_R ();
        }
    }


    I think that

  • Answer # 2

    Invoke ("Rote_L", returnTime);
    Please set Debug.Log in this processing part and check how many times it is called
    It looks like it's been called many times

    Instead of using Invoke, it is better to measure the time yourself and put the conversion process after 5 seconds
    Probably easy to use.