Как я могу перевернуть спрайта AI вражеского персонажа, чтобы посмотреть направление его движения? - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь сделать патрулирующего AI-персонажа, который будет перемещаться из точки в точку.

Патрульная часть работает отлично. Однако проблема в том, что спрайт только направо. Когда он повернулся, спрайт остается в том же направлении.

Я попытался изменить поворот преобразования, используя transform.rotate, transform.rotation, transform.Quaternion и создав переменную для хранения значения вращения, но все они отбрасывают ошибки назад. Ошибки обычно делаются из-за того, что функции поворота / вращения не совместимы ни с одной из попыток, которые я пробовал.

Вот мой код:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// To do:
/// - make rotation of enemy sprite work when reaching the end of patrol area
/// - create attack function
/// </summary>


public class Enemy : MonoBehaviour
{
    public int health;
    public float speed;
    public GameObject bloodEffect;
    public Transform[] moveSpots;               //patrol spots
    public float startWaitTime;                 //start countdown till move to next spot

    private Rigidbody2D rb;
    private Animator anim;
    private int randomSpot;                     //number of patrol spots 
    private float waitTime;                     //how long enemy stays at patrol spot for

    // Start is called before the first frame update
    void Start()
    {
        waitTime = startWaitTime; //make waittime equal to startwaittime
        anim = GetComponent<Animator>();
        randomSpot = Random.Range(0, moveSpots.Length); //choose a random first spot 
    }

    // Update is called once per frame
    void Update()
    {

        Vector3 spriteRotation = new Vector3(0, randomSpot, 0);
        transform.position = Vector2.MoveTowards(transform.position, moveSpots[randomSpot].position, speed * Time.deltaTime); //move toward first patrol area
        transform.eulerAngles = spriteRotation;

        if (Vector2.Distance(transform.position, moveSpots[randomSpot].position) < 0.5f) //asks if patrol point is further that .5f away from enemy
        {
            if (waitTime <= 0) //if waitTime less than or equal to 0
            {

                randomSpot = Random.Range(0, moveSpots.Length); //picks new patrol point
                waitTime = startWaitTime; //restarts countdown clock
            }
            else
            {
                waitTime -= Time.deltaTime; //counts down clock till next point
            }
        }

        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }


    public void TakeDamage(int damage)
    {
        Instantiate(bloodEffect, transform.position, Quaternion.identity);
        Debug.Log("Blood effect played");
        health -= damage;
        Debug.Log("Damage Taken");
    }
}

Ожидаемые результаты для этого кода: случайная точка будет выбрана, и ИИ будет двигаться к этой выбранной точке. Оказавшись там, он будет простаивать в течение определенного времени, прежде чем повернуть и переместиться на новое место.

Фактический результат в основном такой же, как и ожидалось, только спрайт не поворачивается, а вместо этого продолжает поворачиваться вправо, даже когда ИИ движется влево.

Изображение области враг - это темно-красный куб, точки движения - это точки, между которыми патрулирует враг. когда он достигает левой точки, он должен повернуть вправо и вернуться назад, но этого не происходит, вместо этого он просто перемещается назад и вперед без вращения. Я пробовал маршрут SpriteRenderer.flipX, и он работает только один раз, а затем придерживается этого направления.

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Компонент SpriteRenderer имеет атрибут Flip, который вы можете использовать для этого.SpriteRenderer

Вы можете получить к нему доступ в коде

SpriteRenderer.flipX = true;

Это только перевернет спрайт и ничего не изменит, так что дважды проверьте, если ваши коллайдерывсе еще в правильном месте :) Подробнее в документации Удачи

0 голосов
/ 18 апреля 2019

randomSpot - это индекс, а не угол.Поэтому использование

transform.eulerAngles = new Vector3(0, randomSpot, 0);

не имеет для меня никакого смысла ...


Вместо вращения вы можете также перевернуть спрайт / Image, используя отрицательную шкалу, напримернапример,

// Update is called once per frame
private void Update()
{
    // however you determin if facing left or right
    // you e.g. simply check whether the target position 
    // is left or right of you
    var difference = moveSpots[randomSpot].position - transform.position;
    var isFacingRight = difference.x > 0; 

    if (isFacingRight && transform.localScale.x < 0
        || !isFacingRight && transform.localScale.x > 0)
    {
        FlipSprite();
    }
}

private void FlipSprite()
{
    // invert the local X-axis scale
    transform.localScale = new Vector3(-spriteTransform.localScale.x, spriteTransform.localScale.y, spriteTransform.localScale.z);
}

enter image description here

Сценарий, использованный для примера

private void Update()
{
    // works only in a ScreenOverlay Canvas
    var targetPosition = Input.mousePosition;

    var difference = targetPosition - transform.position;
    var isFacingRight = difference.x > 0 ? true : false;

    if (isFacingRight && transform.localScale.x < 0
        || !isFacingRight && transform.localScale.x > 0)
    {
        FlipSprite();
    }

    // simply only move left or right on the x-axis towards the mouse
    transform.position = Vector3.MoveTowards(transform.position, new Vector3(targetPosition.x, 218, 0), Time.deltaTime * 100);
}

private void FlipSprite()
{
    // invert the local X-axis scale
    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
}
...