unity自学日记:一个超级简单的npc对话动作脚本

public class NPC5 : MonoBehaviour
{
    public Transform player;//获取玩家的引用 
    public float rightspeed=1;
    public float leftspeed = 0.5f;//npc转身的速度
    private float dis;//玩家和npc之间的距离
    private float dir;//玩家和npc之间的方向(左右侧)
    private float angle;//玩家与npc之间的夹角
    private Animator ani;
    public int num;//玩家的状态
    public AudioClip aud1;
    public AudioClip aud2;
    public AudioClip aud3;
    private AudioSource aud;
    public float longestDis = 5f;//触发范围
    private Vector3 p;//npc指向玩家的向量

    // Start is called before the first frame update
    void Start()
    {
        ani = GetComponent<Animator>();
        InvokeRepeating("jiance1", 0.0001f, Time.deltaTime);
    }

    // Update is called once per frame
    void Update()
    {

        aud = GetComponent<AudioSource>();
        dis = (player.position - transform.position).magnitude;
        if (dis >= longestDis)
        {
            ani.SetBool("rightturn1", false);
            ani.SetBool("rightturn2", false);
            ani.SetBool("leftturn1", false);
            ani.SetBool("leftturn2", false);
        }
    }
    void jiance1()
    {
        p = player.position - transform.position;
        dis = (player.position - transform.position).magnitude;//计算玩家和npc之间的距离
        dir = Vector3.Cross(this.transform.forward, p).y;//大于0,玩家在npc右方,反之

        Vector3 d1 = transform.forward;
        Vector3 d2 = new Vector3(0, 3, 0);
        float dot = Vector3.Dot(d1, player.forward.normalized);     //d2.normalized向量归一化
        float angle = Mathf.Acos(dot) * Mathf.Rad2Deg;
       Debug.Log("夹角:"+Mathf.Abs(angle)+"    dir:"+dir);
        if (dis <= longestDis)
        {
            if (Mathf.Abs(angle) < 160f)
            {
                Debug.Log("夹角过大" + Mathf.Abs(angle));
                if (dir > 0)
                {
                    Debug.Log("检测到在右方,开始旋转"+dir);
                    ani.SetBool("rightturn1", true);
                    ani.SetBool("rightturn2", true);
                    rightturn();
                }
                else if (dir < 0)
                {
                    Debug.Log("检测到在左方,开始旋转"+dir);
                    ani.SetBool("leftturn1", true);
                    ani.SetBool("leftturn2", true);
                    leftturn();
                }
            }
            else if (Mathf.Abs(angle) >=160f)
             {
                Debug.Log("!!!!??????????????????!!!!!!!!!!!!!!!!");

                Invoke("playclip", 0);
             }
        }
    }
    void playclip()
    {
        Debug.Log("开始播放音频,调用");
        ani.SetBool("leftturn1", true);
        ani.SetBool("rightturn1", true);
        ani.SetBool("rightturn2", false);
        ani.SetBool("leftturn2", false);
        if (num == 1)
        {
            aud.clip = aud1;
            aud.Play();
        }
        if (num == 2)
        {
            aud.clip = aud2;
            aud.Play();
        }
        if (num == 3)
        {
            aud.clip = aud3;
            aud.Play();
        }
        CancelInvoke("jiance1");
       CancelInvoke("playclip");

    }
    void rightturn()
    {
        Vector3 v = new Vector3(player.position.x, transform.position.y, player.position.z);

        Quaternion rotation = Quaternion.LookRotation(v - transform.position);

        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * rightspeed);

        
    }
    void leftturn()
    {
        Vector3 v = new Vector3(player.position.x, transform.position.y, player.position.z);

        Quaternion rotation = Quaternion.LookRotation(v - transform.position);

        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * leftspeed);


    }
}

状态机:

非常非常粗糙丑陋的代码,还有很多可以改进的地方,比如左右转身的速度没必要分开设置的……

但无所谓了

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值