Unity3D学习笔记(六):三角函数和点乘

本文深入探讨了Unity游戏开发中向量与三角函数的实用技巧,包括向量的点乘运算、三角函数的概念及其在判断敌人位置和扇形范围检测中的应用。通过具体代码示例,展示了如何计算向量间的夹角、判断目标是否位于敌人前方及扇形范围内,以及实现角色的动态移动和旋转。
摘要由CSDN通过智能技术生成
三角函数:
概念:用来描述三角形中某个角和对应的三条边的比例关系。
正弦:sin<θ>(sin<theta>)=对边/斜边
余弦:cos<θ>(cos<theta>)=邻边/斜边
正切:tan<θ>(tan<theta>)=对边/邻边
 
正弦函数曲线:随着θ角度不断增大,sinθ的值的变化周期
 
余弦函数曲线:正弦函数曲线左移90度
 
反三角函数:已知比例关系,反推出角度或者弧度。
反正弦:Arcsin(0.5)=30度
反余弦:Arccos
反正切:Arctan
 
向量的乘法:
向量的点乘:a(ax,ay,az) · b(bx.by.bz)
数学运算:a·b = axbx + ayby + azbz,各分量分别相乘再相加
1、满足乘法交换律
2、结果是标量
几何意义:
a·b = |a| * |b| * cos<a,b>,<a,b>夹角范围0~180度,两个向量夹角越小,相似度越高
a·b = (|a| * cos<a,b>) * |b|,最重要的几何意义就是求投影
1、a向量在b向量方向上投影的长度再乘以b向量的模长
2、当b向量为单位向量的时候,结果就是:a向量在b向量方向上投影的长度
3、当a向量和b向量都是单位向量的时候,结果就是:两个向量的夹角的余弦
 
敌人的正前方和敌人与自己连线的夹角,小于90度,在敌人前方,大于90度,在敌人后方
API Vector3.Dot(Vector3 lhs,Vector3 rhs),两个向量点乘满足乘法交换律,但叉乘不行
API Vector3.Angle,直接计算两个向量之间的夹角
 
思考题:入射光线和反射光线不在一个水平线上
 
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyLook : MonoBehaviour
{
    public Transform player;
    public float result;
    public float distance;
    // Use this for initialization
    void Start()
    {
        ////向量点乘的数学运算
        //Vector3 enemy2Player = player.position - transform.position;
        //Vector3 enemyForward = transform.forward;
        //result = enemy2Player.x * enemyForward.x + enemy2Player.y * enemyForward.y + enemy2Player.z + enemyForward.z;
        //把向量变成单位向量
        Vector3 enemy2Player = (player.position - transform.position).normalized;
        Vector3 enemyForward = transform.forward;
        //计算两个向量之间的夹角
        result = Vector3.Dot(enemy2Player, enemyForward);
        //计算两个物体之间的距离
        distance = Vector3.Distance(player.position, transform.position);
        //API:计算两个向量之间的夹角
        //Vector3.Angle();
    }
    // Update is called once per frame
    void Update()
    {
    }
    private void OnGUI()
    {
        //if (result > 0)
        //{
        //    GUILayout.Label("在敌人前方");
        //}
        //else
        //{
        //    GUILayout.Label("在敌人后方");
        //}
        if (result > Mathf.Cos(30 * Mathf.Deg2Rad) && distance < 5)
        {
            GUILayout.Label("在扇形范围内:" + Mathf.Acos(result) * Mathf.Rad2Deg + "");
        }
        else
        {
            GUILayout.Label("不在扇形范围内:" + Mathf.Acos(result) * Mathf.Rad2Deg + "");
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestTrans : MonoBehaviour {
    public Transform Target;
    public float distance;
    private float SkillDistance = 5;//扇形距离
    private float SkillJiaodu = 60;//扇形的角度
    // Use this for initialization
    void Start () {
        ////偶然性编程
        distance = Vector3.Distance(transform.position, Target.position);//距离
        Vector3 norVec = transform.rotation * Vector3.forward;
        Vector3 temVec = Target.position - transform.position;
        Debug.DrawLine(transform.position, norVec, Color.red);//画出技能释放者面对的方向向量
        Debug.DrawLine(transform.position, Target.position, Color.green);//画出技能释放者与目标点的连线
        float jiajiao = Mathf.Acos(Vector3.Dot(norVec.normalized, temVec.normalized)) * Mathf.Rad2Deg;
        if (distance <= SkillDistance)
        {
            if (jiajiao <= SkillJiaodu)
            {
                Debug.Log("在扇形范围内");
            }
            else
            {
                Debug.Log("不在扇形范围内");
            }
        }
    }
       
       // Update is called once per frame
       void Update () {
      
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CrystalMove : MonoBehaviour {
    //public Transform startTrans;
    //public float moveSpeed = 1;
    //public float rotSpeed = 1;
    public float rotateSpeed = 30;
    //调节上下频率和浮动
    public float amplitude = 1f;
    public float frequency = 1f;
    // Use this for initialization
    void Start () {
              
       }
       
       // Update is called once per frame
       void Update () {
        //    transform.Rotate(Vector3.up, Space.World);
        //    Vector3 delta = Vector3.up * Mathf.Sin(Time.time) * moveSpeed*0.25F;
        //    transform.position = startTrans.position + delta;
        transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed);
        float sin = Mathf.Sin(Time.time * frequency) * amplitude;
        transform.Translate(Vector3.up * sin, Space.World);
    }
}

 

转载于:https://www.cnblogs.com/cnwuchao/p/10362823.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值