How can I flip a sprite of an AI enemy character to face the direction its moving in?

拟墨画扇 提交于 2019-12-11 05:59:40

问题


I'm trying to make a patrolling AI character that will move from point to point.

The patrol part works perfectly. However, the problem is that the sprite only faces right. When it turned the sprite stays facing the same direction.

I have tried to change the transform rotation using transform.rotate, transform.rotation, transform.Quaternion and making a variable to store the rotation value yet they all kick errors back. The errors are usually made from the rotate/rotation functions not being compatible with any of the attempts I have tried.

Here is my code:

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");
    }
}

The expected results for this code is that a random point will be chosen and the AI will move toward that chosen point. Once there it will stay idle for a specified amount of time before turning and moving to a new spot.

The actual result is mostly the same as expected only the sprite does not turn around but instead continues to face to the right even when the AI is moving left.

Image of area the enemy is the dark red cube, the movepoints are the points that the enemy patrols between. when it reaches the left point, he should turn to the right and go back but this is not what happens, instead he just moves back and forth with no rotation. ive tried the SpriteRenderer.flipX route and it only works one time and then sticks with that direction.


回答1:


The SpriteRenderer Component has a Flip attribute you could use for this.

You can access it in code

SpriteRenderer.flipX = true;

It will only flip the sprite and won't change anything else, so double check if your colliders are still in the right space :) See more in the documentation Good luck




回答2:


randomSpot is an index not an angle. So using

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

doens't make any sense to me ...


Instead of rotating you could also flip the sprite/Image by using a negative scale like e.g.

// 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);
}

Script used for the example

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);
}


来源:https://stackoverflow.com/questions/55740498/how-can-i-flip-a-sprite-of-an-ai-enemy-character-to-face-the-direction-its-movin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!