怪物AI&血量UI
使用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;
}
}
}
}

