如何翻转AI敌方角色的精灵以面对其移动方向?

时间:2019-04-18 06:47:29

标签: c# unity3d quaternions image-rotation

我正在尝试制作一个巡逻的AI角色,该角色将逐点移动。

巡逻部分工作正常。但是,问题在于该精灵仅面向右。旋转时,精灵保持面向相同方向。

我尝试使用transform.rotatetransform.rotationtransform.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");
    }
}

此代码的预期结果是将选择一个随机点,并且AI将移向该选定点。到达那里后,它将在指定时间段内保持空闲状态,然后转向并移至新位置。

实际结果与预期的结果基本相同,只是精灵不会旋转,而是即使AI向左移动也继续面向右。

Image of area 敌人是暗红色的立方体,移动点是敌人在其间巡逻的点。当它到达左点时,他应该向右转,然后返回,但事实并非如此,相反,他只是来回移动而没有旋转。香港专业教育学院尝试了SpriteRenderer.flipX路线,它只能运行一次,然后坚持该方向。

2 个答案:

答案 0 :(得分:1)

SpriteRenderer组件具有一个Flip属性,可用于此目的。 SpriteRenderer

您可以通过代码

访问它
SpriteRenderer.flipX = true;

它只会翻转精灵,不会改变其他任何东西,因此请仔细检查对撞机是否仍在正确的空间内:) See more in the documentation 祝你好运

答案 1 :(得分:0)

randomSpot是一个索引,而不是一个角度。所以使用

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

对我来说毫无意义...


除了旋转之外,您还可以使用负标度(例如,

)来翻转sprite / 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);
}