简体   繁体   English

让敌人在 Unity 中向玩家加速

[英]Have enemy accelerate towards player in Unity

I have a script that has the enemy move towards the player at the same speed, but I am trying to make the enemy slow down then accelerate when he is switching directions.我有一个脚本让敌人以相同的速度向玩家移动,但我试图让敌人在切换方向时减速然后加速。 The enemy currently just moves left and write towards the player's position.敌人目前只是向左移动并写向玩家的 position。 Here is my code from the script that my boss is attached to in the update function:这是我的老板在更新 function 中附加的脚本中的代码:

Vector2 targetPosition = new Vector2 (player.transform.position.x, transform.position.y); 
transform.position = Vector2.MoveTowards (transform.position, targetPosition, moveSpeed * Time.deltaTime);

I have also tried using Lerp and using the transform.position as the first parameter, but the boss goes slower when the player is closer, and faster when the player is faster away.我也尝试过使用 Lerp 并使用 transform.position 作为第一个参数,但是当玩家靠近时,boss 会变慢,当玩家远离时会变快。

transform.position = Vector2.Lerp (transform.position, targetPosition, moveSpeed * Time.deltaTime);

Does anyone know how to make the enemy slow down, then gradually increase his speed as he change direction, then return to normal speed after he has finished changing directions有没有人知道如何让敌人减速,然后在他改变方向时逐渐增加速度,然后在他改变方向后恢复正常速度

**EDIT: ** full script below **编辑:**下面的完整脚本

using UnityEngine;

public class Roll : StateMachineBehaviour
{
    [SerializeField] private float moveSpeed = 2.4f; 
    [SerializeField] private float rotateSpeed = 100f; 

    [SerializeField] private float minRollTime = 6f;
    [SerializeField] private float maxRollTime = 8f;
    private float rollTimer = 0f; 

    [SerializeField] private float rightBoundary = 5f;
    [SerializeField] private float leftBoundary = -5f;

    private Transform playerTransform = null;
    private BossHealth bossHealth = null;     
    private Transform bossTransform = null;
    private Transform bodyTransform = null;
    private Transform earsTransform = null; 

    private Vector2 targetPosition = Vector2.zero; 

    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        playerTransform = GameObject.FindWithTag("Player").transform; 

        bossHealth = animator.GetComponent<BossHealth>(); 

        Boss01 boss = FindObjectOfType<Boss01>(); 
        bossTransform = boss.bossTransform;  
        bodyTransform = boss.bodyTransform; 
        earsTransform = boss.earsTransform; 

        rollTimer = Random.Range (minRollTime, maxRollTime); 
    }

    override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        if (bossTransform.position.x >= leftBoundary && bossTransform.position.x <= rightBoundary)
        {
            targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
            bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);

            if (playerTransform.position.x > 0)
                bodyTransform.Rotate(0f, 0f, -rotateSpeed * Time.deltaTime); 
            else
                bodyTransform.Rotate(0f, 0f, rotateSpeed * Time.deltaTime); 
        }
        else if (bossTransform.position.x < leftBoundary) 
        {
            if (playerTransform.position.x > bossTransform.position.x) 
            {
                targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
                bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);
            }
        }
        else
        {
            if (playerTransform.position.x < bossTransform.position.x) 
            {
                targetPosition = new Vector2(playerTransform.position.x, bossTransform.position.y);
                bossTransform.position = Vector2.MoveTowards(bossTransform.position, targetPosition, moveSpeed * Time.deltaTime);
            }
        }

        if (rollTimer <= 0f)
            animator.SetTrigger ("aim"); 
        else
            rollTimer -= Time.deltaTime; 

        if (bossHealth.CheckHealth())
            animator.SetTrigger ("transition"); 

        if (earsTransform.rotation != Quaternion.Euler (0f, 0f, 0f))
            earsTransform.rotation = Quaternion.Slerp(earsTransform.rotation, Quaternion.Euler(0f, 0f, 0f), 1f * Time.deltaTime); 
    }

    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.ResetTrigger ("aim"); 
        animator.ResetTrigger ("transition"); 
    }
}

To achieve the position (meters/second) you multiply the speed * Time.deltatime, so you achieve the meters.要实现 position(米/秒),您需要乘以速度 * Time.deltatime,从而获得米。 To handle acceleration, you need to handle variable speed.要处理加速度,您需要处理可变速度。 Acceleration is m/s2, multiplied * Time.deltatime you will have the instant speed, and that speed * Time.deltaTime will give you the position.加速度为 m/s2,乘以 * Time.deltatime,您将获得即时速度,而该速度 * Time.deltaTime 将为您提供 position。

Here some pseudocode (step and speed should be class varibles and this modifieed in the update. accel is the constant acceleration, that should be constans for the simplicity's sake, I guess that you need uniformingly accelerated movement):这里有一些伪代码(步长和速度应该是 class 变量,并且在更新中进行了修改。加速是恒定的加速度,为了简单起见应该是常数,我猜你需要均匀加速的运动):

speed += accel * Time.deltaTime; // instant speed
step =  speed * Time.deltaTime; // calculate distance to move
transform.position = Vector3.MoveTowards(transform.position, target.position, step);

With the sign of the accel + or - you will determine if the entities speed is increasing (accelerating) or decreasing (decelerating).使用加速 + 或 - 的符号,您将确定实体速度是增加(加速)还是减少(减速)。

Hope that helps希望有帮助

Edit:编辑:

Full script:完整脚本:

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

public class MoveTowards : MonoBehaviour
{
  public Transform target;
  private float step = 0f;
  private float speed = 0f;
  public float accel = 0f;
  // Start is called before the first frame update
  void Start()
  {

  }

  // Update is called once per frame
  void Update()
  {
    speed += accel * Time.deltaTime; // instant speed
    step = speed * Time.deltaTime; // calculate distance to move
    transform.position = Vector3.MoveTowards(transform.position, target.position, step);
  }
}

Screenshot of script attached in editor:编辑器中附加的脚本截图:

在此处输入图像描述

Attached the script to the game object you want to move, and attach the transform of the target in the public fielld.将脚本附加到您要移动的游戏 object 中,并在公共字段中附加目标的变换。 The choose your acceleration, positive to accelerate towards an negative to accelerate backwars, and there you got it.选择你的加速度,正向加速,负向加速,然后你就明白了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM