Поворот врага на Unity
У меня есть ИИ врага. Враг держит в руках оружие и ходит туда-сюда, но, когда он начинает стрелять в игрока, он не может повернутьса и всё время в первом положении. Помогите его перевернуть в нужный момент. Вот Код: C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IIEnemy : MonoBehaviour
{
public float speed_enemy;
public float stopping_distanse;
public int positon_of_patrol;
public Transform point;
private Transform player;
public Transform firePoint;
public GameObject bulet;
private bool moving_right;
private bool chiil = false;
private bool angry = false;
private bool go_back = false;
private float TimeBtwShotr;
public float startTimebtw;
private void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
private void Update()
{
// Если дистанцыя от игрока до точки меньше чем дистанцыя патруля
if (Vector2.Distance(transform.position, point.position) < positon_of_patrol && angry == false)
{
chiil = true;
}
if (Vector2.Distance(transform.position, player.position) < stopping_distanse)
{
angry = true;
chiil = false;
go_back = false;
Shoot();
}
if (Vector2.Distance(transform.position, player.position) > stopping_distanse)
{
go_back = true;
angry = false;
}
if (chiil == true)
{
Chill();
}
else if (angry == true)
{
Angry();
}
else if (go_back == true)
{
GoBack();
}
}
void Chill()
{
if (transform.position.x > point.position.x + positon_of_patrol)
{
moving_right = false;
}
else if(transform.position.x < point.position.x - positon_of_patrol)
{
moving_right = true;
}
if (moving_right)
{
transform.position = new Vector2(transform.position.x + speed_enemy * Time.deltaTime,transform.position.y);
}
else
{
transform.position = new Vector2(transform.position.x - speed_enemy * Time.deltaTime, transform.position.y);
}
}
void Angry()
{
// двигатса к игроку
transform.position = Vector2.MoveTowards(transform.position,player.position,speed_enemy * Time.deltaTime);
}
void GoBack()
{
transform.position = Vector2.MoveTowards(transform.position, point.position, speed_enemy * Time.deltaTime);
}
private void Shoot()
{
if (TimeBtwShotr <= 0)
{
Instantiate(bulet, firePoint.position, firePoint.rotation);
TimeBtwShotr = startTimebtw;
}
else
{
TimeBtwShotr -= Time.deltaTime;
}
}
}
Ответы (1 шт):
Автор решения: Yaroslav
→ Ссылка
using System.Collections;
using UnityEngine;
[DisallowMultipleComponent]
[RequireComponent(typeof(Rigidbody2D))] // делает компонент обязательным
public class IIEnemy : MonoBehaviour
{
public enum EnemyState { Chiil, Angry, GoBack }
// public полей быть не должно
[SerializeField] private float _moveSpeed = 1; // speed_enemy? какой смысл писать в имени enemy в классе enemy
[SerializeField] private float _attackTime = 1;
[SerializeField] private float _angryDistanse = 3; // _stoppingDistanse? явно не остановка
[SerializeField] private float _patrolRange = 3; // positon_of_patrol не понятное имя в контексте того что это int, и почему это int?
[SerializeField] private Transform _chillPoint; // point чего?
[Space]
[SerializeField] private Transform _firePoint;
[SerializeField] private GameObject _buletTemplate;
private Transform _transform;
private Rigidbody2D _body; // вообщето движение делается через тело, незабудь добавить collider врагу и земле
private Transform _player;
private EnemyState _state; // удобнее ведь в место хреналиона bool, иметь что-то одно
private float _patrolVector;
private IEnumerator _attackCoroutine;
private void Start ()
{
_transform = transform;
_player = GameObject.FindGameObjectWithTag("Player").transform;
_body = GetComponent<Rigidbody2D>();
_patrolVector = UnityEngine.Random.Range(0, 2) == 0 ? 1 : -1;
SetState(EnemyState.Chiil);
}
private void Update ()
{
switch (_state)
{
case EnemyState.Chiil: UpdateChill(); break;
case EnemyState.Angry: UpdateAngry(); break;
case EnemyState.GoBack: UpdateGoBack(); break;
}
}
private void SetState (EnemyState state)
{
_state = state;
if (_state == EnemyState.Angry)
{
// поскольку атака не постоянна, то делается с помощью корутины
_attackCoroutine = AttackCoroutine();
StartCoroutine(_attackCoroutine);
}
else if (_attackCoroutine != null)
{
StopCoroutine(_attackCoroutine);
}
}
private void UpdateChill ()
{
if (_patrolVector > 0 && transform.position.x > _chillPoint.position.x+_patrolRange)
_patrolVector = -1;
else if (_patrolVector < 0 && transform.position.x < _chillPoint.position.x-_patrolRange)
_patrolVector = 1;
SetMoveVector(_patrolVector);
if (PlayerIsClose() == true)
SetState(EnemyState.Angry);
}
private void UpdateAngry ()
{
MoveTo(_player.position.x);
if (PlayerIsClose() == false)
SetState(EnemyState.GoBack);
}
private void UpdateGoBack ()
{
MoveTo(_chillPoint.position.x);
if (Vector2.Distance(_transform.position, _chillPoint.position) < _patrolRange)
SetState(EnemyState.Chiil);
if (PlayerIsClose() == true)
SetState(EnemyState.Angry);
}
private void MoveTo (float x)
{
SetMoveVector(x > _transform.position.x ? 1 : -1);
}
private void StopMove ()
{
SetMoveVector(0);
}
private void SetMoveVector (float vector)
{
Vector3 Velocity = _body.velocity;
Velocity.x = vector*_moveSpeed;
_body.velocity = Velocity;
if (vector != 0)
_transform.localScale = new Vector3(vector > 0 ? 1 : -1, 1, 1); // поворачиваем в сторону движения
}
private bool PlayerIsClose ()
{
return Vector2.Distance(_transform.position, _player.position) < _angryDistanse;
}
private IEnumerator AttackCoroutine ()
{
float Timer = 0;
while (true)
{
Timer += Time.deltaTime;
if (Timer >= _attackTime)
{
Shoot();
Timer -= _attackTime;
}
yield return null; // задержка до следующего фрейма
}
}
private void Shoot ()
{
Instantiate(_buletTemplate, _firePoint.position, _firePoint.rotation);
}
}