使用Animator Override创建更多敌人

图片说明

  • 类似于函数的重载
    图片说明

对玩家施加推力模拟击飞效果

public void KickOff()
    {
        if (attackTarget != null)
        {
            transform.LookAt(attackTarget.transform);
            Vector3 direction = attackTarget.transform.position - transform.position;
            direction.Normalize();
            attackTarget.GetComponent<NavMeshAgent>().isStopped = true;
            attackTarget.GetComponent<NavMeshAgent>().velocity = direction * kickForce;
            attackTarget.GetComponent<Animator>().SetTrigger("Dizzy");
        }
    }

Animation Behavior

  • 用于在进入动画,播放动画,退出动画时执行某些方法,能更为细致的融合动画与代码逻辑
  • 创建:点击动画,add behavior
    图片说明

扩展方法

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

public static class ExtentionMethod
{
    private const float dotThreshold = 0.5f;
//第一个参数为需要扩展的类,第二个参数才是函数的变量!!
   public static bool IsFacingTarget(this Transform transform,Transform target)
    {
        var vectorToTarget = target.position - transform.position;
        vectorToTarget.Normalize();
//两个向量的点积
        float dot = Vector3.Dot(transform.forward, vectorToTarget);
        return dot >= dotThreshold;
    }
}
  • 使用
    transform.IsFacingTarget(attackTarget.transform)

血量显示

  • 创建UI Canvas
    图片说明
  • 设置为世界坐标模式,跟随相机
    图片说明
  • 创建image,使用square作为source image并置于角色头顶
    图片说明
    图片说明
  • 创建UI更新代码,订阅UI更新事件,并在受到伤害时触发该事件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class HealthBarUI : MonoBehaviour
{
    public GameObject healthUIPrebab;
    public Transform barPoint;
    //是否长久可见
    public bool alwaysVisible;
    //可见时间
    public float visibleTime;
    private float timeLeft;

    Image healthSlider;
    //UI的位置
    Transform UIbar;
    //摄像机位置
    Transform cam;
    CharacterStats currentStats;
    void Awake()
    {
        currentStats = GetComponent<CharacterStats>();
        currentStats.UpdateHealthBarOnAttack += UpdateHealthBar;
    }
    void OnEnable()
    {
        cam = Camera.main.transform;
        foreach(Canvas canvas in FindObjectsOfType<Canvas>())
        {
            //目前只有一个RenderMode.WorldSpace
            if (canvas.renderMode == RenderMode.WorldSpace)
            {
                UIbar = Instantiate(healthUIPrebab, canvas.transform).transform;
                healthSlider = UIbar.GetChild(0).GetComponent<Image>();
                UIbar.gameObject.SetActive(alwaysVisible);
            }
        }
    }
    private void UpdateHealthBar(int currentHealth,int maxHealth)
    {
        if (currentHealth <= 0)
            Destroy(UIbar.gameObject);

        UIbar.gameObject.SetActive(true);
        timeLeft = visibleTime;
        float sliderPercent = (float)currentHealth / maxHealth;
        healthSlider.fillAmount = sliderPercent;
    }
    //在上一帧渲染后执行
    void LateUpdate()
    {
        if (UIbar != null)
        {
            UIbar.position = barPoint.position;
            UIbar.forward = -cam.forward;
            if (timeLeft <= 0 && !alwaysVisible)
            {
                UIbar.gameObject.SetActive(false);
            }
            else
            {
                timeLeft -= Time.deltaTime;
            }
        }
    }

}